使用 Binding . 或 Binding 时数据绑定未更新
Posted
技术标签:
【中文标题】使用 Binding . 或 Binding 时数据绑定未更新【英文标题】:Databinding Not Updating When Using Binding . or Binding使用 Binding . 或 Binding 时数据绑定未更新 【发布时间】:2011-01-24 07:19:57 【问题描述】:我有一个绑定到 ListBox 的地址的 ObservableCollection。然后在 ItemTemplate 中,我使用 Binding . 绑定到当前地址记录。这导致我的地址使用他们的 ToString 方法显示,我已设置该方法来格式化地址。一切都很好,除非我更新单个地址记录的属性,UI 中的列表不会更新。添加/删除到列表会更新 UI(使用 ObservableCollection 行为)。如果我直接绑定到地址上的属性,UI 会更新(使用 Address 对象的 INotifyPropertyChanged 行为)。
我的问题是,有没有办法将整个对象的更改通知 UI,以便我仍然可以使用这种语法,或者我是否需要在我的地址类型上添加一个 DisplayText 属性来调用ToString 方法并绑定到那个?仅供参考,这是一个 MVVM 架构,所以我没有直接在 ListBox 上调用 Refresh 的奢侈。
感谢任何帮助/想法。
<ListBox x:Name="AddressList" ItemsSource="Binding Addresses" Background="Transparent" BorderBrush="Transparent"
Width="200" HorizontalAlignment="Left">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="Binding ." />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
【问题讨论】:
【参考方案1】:当您绑定到 Address 对象本身时,对象本身(即它的标识)不会改变,即使它的属性会改变。因此 WPF 在这种情况下不知道刷新绑定。
所以是的,您需要绑定到通知属性(或属性)而不是整个对象。正如您所说,执行此操作的一种方法是创建一个 DisplayText 属性,并在影响显示文本的内容发生更改时为该属性引发 PropertyChanged 事件。另一种是在水平方向的 StackPanel 中使用多个 TextBlock,每个都绑定到特定的属性,例如
<StackPanel Orientation="Horizontal">
<TextBlock Text="Binding HouseNumber" />
<TextBlock Text=", " />
<TextBlock Text="Binding Street" />
<TextBlock Text=", " />
<TextBlock Text="Binding City" />
</StackPanel>
第二种方法的优点是它让您可以灵活地在 UI 中更改地址的显示方式,例如多行、格式化等;缺点是如果你有条件逻辑,它会变得复杂,例如可选的平面编号或第二个地址行。
【讨论】:
这很有意义。尽管我认为我会坚持使用显示文本属性路由,因为我们需要支持美国和外国地址以及您提到的第二行。要在 WPF 端实现这一点,可能需要一个转换器类。对我来说,将其集中在实体类中更有意义。如有必要,调用者拥有所有单独的字段来覆盖它。【参考方案2】:我尝试重现问题并成功。
我激活了 step-into-.NET 调试选项,发现如果绑定中的路径为空,WPF 不会监听 INotifyPropertyChanged。
使更改反映在列表框中的工作是替换 ObservableCollection 中的整个对象。这会触发 INotifyCollectionChanged 以及 Replace 操作。
但这在您的情况下可能是不可接受的。而且它更像是一种 hack,而不是一种可靠的解决方案。
我会认真考虑为地址设置一个 DataTemplate。在那里,您应该绑定到您需要的确切属性(这将为 INotifyPropertyChanged 创建侦听器)。它比 ToString() 更灵活,您可能会遇到需要 ToString() 为非 UI 内容做某事的情况,这会产生冲突。老实说,ToString 并不是真正用于 UI 的东西。
【讨论】:
以上是关于使用 Binding . 或 Binding 时数据绑定未更新的主要内容,如果未能解决你的问题,请参考以下文章