Wpf 使用{Binding.}或{Binding}时数据绑定未更新

Wpf 使用{Binding.}或{Binding}时数据绑定未更新,wpf,data-binding,listbox,Wpf,Data Binding,Listbox,我有一个可观察的地址集合,我绑定到一个列表框。然后在ItemTemplate中,我使用{Binding.}绑定到当前地址记录。这导致我的地址显示使用他们的ToString方法,我已经设置格式的地址。一切都很好,除非我更新了单个地址记录的属性,否则UI中的列表不会更新。向列表添加/删除并更新UI(使用ObservableCollection行为)。如果我直接绑定到地址上的属性,UI会更新(使用地址对象的INotifyPropertyChanged行为) 我的问题是,有没有一种方法可以将对象的更改作

我有一个可观察的地址集合,我绑定到一个列表框。然后在ItemTemplate中,我使用{Binding.}绑定到当前地址记录。这导致我的地址显示使用他们的ToString方法,我已经设置格式的地址。一切都很好,除非我更新了单个地址记录的属性,否则UI中的列表不会更新。向列表添加/删除并更新UI(使用ObservableCollection行为)。如果我直接绑定到地址上的属性,UI会更新(使用地址对象的INotifyPropertyChanged行为)

我的问题是,有没有一种方法可以将对象的更改作为一个整体通知UI,以便我仍然可以使用这种语法,或者我是否需要在我的地址类型上punt并放置一个DisplayText属性来调用ToString方法并绑定到它?仅供参考,这是一个MVVM体系结构,因此我没有直接在列表框上调用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>

绑定到Address对象本身时,对象本身(即其标识)不会更改,即使其属性会更改。因此,在这种情况下,WPF不知道刷新绑定

因此,是的,您需要绑定到一个或多个通知属性,而不是整个对象。正如您所说,一种方法是创建DisplayText属性,并在影响显示文本的内容发生更改时引发该属性的PropertyChanged事件。另一种方法是在水平方向的StackPanel中使用多个文本块,每个文本块绑定到一个特定属性,例如

<StackPanel Orientation="Horizontal">
  <TextBlock Text="{Binding HouseNumber}" />
  <TextBlock Text=", " />
  <TextBlock Text="{Binding Street}" />
  <TextBlock Text=", " />
  <TextBlock Text="{Binding City}" />
</StackPanel>


第二种方法的优点是,它使您能够在UI中灵活地更改地址的显示方式,例如多行、格式等。;缺点是,如果您有条件逻辑,例如可选的固定数字或第二个地址行,它会变得复杂。

我试图重现问题,但成功了

我激活了进入.NET调试选项的步骤,发现如果绑定中的路径为空,WPF不会侦听INotifyPropertyChanged

使更改反映在列表框中的方法是替换ObservableCollection中的整个对象。这将触发INotifyCollectionChanged,并执行替换操作

但在你的情况下,这可能是不可接受的。它更像是一个黑客而不是一个固溶体


我认真考虑有地址的数据板。在那里,您应该绑定到所需的确切属性(这将为INotifyPropertyChanged创建侦听器)。它比ToString()更灵活,您可能会遇到需要ToString()为非UI内容执行某些操作的情况,这会产生冲突。老实说,ToString并不是真正用于UI的东西。

这很有道理。虽然我认为我会坚持显示文本属性路由,因为我们需要支持我们和外国地址,以及您提到的第二行。要在WPF端实现这一点,可能需要一个转换器类。对我来说,通过实体类保持这种集中化更有意义。如果需要,调用方可以使用所有单独的字段覆盖它。