Databinding Not Updating When Using {Binding .} or {Binding}

data-binding, listbox, wpf

Solution

When you bind to the Address object itself, the object itself -- that is, its identity -- doesn't change, even though its properties do. WPF therefore doesn't know to refresh the binding in this case.

So yes, you need to bind to a notifying property (or properties) rather than the whole object. As you say, one way to do this is to create a DisplayText property, and raise the PropertyChanged event for that property whenever something that affects the display text changes. Another is to use multiple TextBlocks in a horizontally oriented StackPanel, each bound to a particular property e.g.

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

The advantage of the second approach is that it gives you flexibility in the UI to change how addresses are displayed, e.g. multiple lines, formatting, etc.; the downside is that it gets complicated if you have conditional logic e.g. an optional flat number or second address line.

Problem

I have an ObservableCollection of addresses that I am binding to a ListBox. Then in the ItemTemplate I am Binding to the current address record using {Binding .}. This results in my addresses displaying using their ToString method which I have setup to format the address. All is good, except if I update properties on an individual address record the list in the UI does not update. Adds/Deletes to the list do update the UI (using the ObservableCollection behavior). If I bind directly to properties on the address the UI does update (using the INotifyPropertyChanged behavior of the Address object). My question is, is there a way to notify the UI of the change to the object as a whole so that I can still use this syntax or do I need to punt and put a DisplayText property on my address type that calls the ToString method and bind to that? FYI, this is an MVVM architecture so I don't have the luxury of calling Refresh on the ListBox directly. Thanks for any help/ideas. ``` <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> ```

Original source