Data binding not updating when using {Binding.} Or {Binding}

I have an ObservableCollection of addresses that I associate with a ListBox. Then in the ItemTemplate, I bind to the current address record using {Binding.}. This causes my addresses to be displayed using the ToString method, which I configured to format the address. Everything is fine, except when I update the properties in a separate address record, the list in the user interface is not updated. Adds / removes the list by updating the interface (using the ObservableCollection behavior). If I bind directly to the properties on the address that the user interface updates (using the behavior of the Object Address object) INotifyPropertyChanged.

My question is, is there a way to notify the user interface of a change in the whole object so that I can still use this syntax or do I need to sneak up and put the DisplayText property in my address type that calls ToString and binds to it? FYI is an MVVM architecture, so I have no right to call Refresh in a 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> 
+4
source share
2 answers

When you bind to the Address object itself, the object itself, that is, its identifier, does not change, even if its properties are satisfied. Therefore, WPF does not know to update the binding in this case.

So yes, you need to bind to the notification property (or properties), and not to the entire object. As you say, one way to do this is to create a DisplayText property and raise a PropertyChanged event for this property whenever something affects the display text. Another is the use of several text blocks in a horizontally oriented StackPanel, each of which is tied to a specific property, for example.

 <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 user interface to change the way addresses are displayed, for example. multiple lines, formatting, etc .; The downside is that it gets complicated if you have conditional logic, for example. optional flat number or second address bar.

+3
source

I tried to reproduce the problem and succeed.

I activated the debugging options step-into-.NET and saw that WPF is not listening on INotifyPropertyChanged if the binding path is empty.

What worked to get the change that should be reflected in the list is to replace the entire object in the ObservableCollection. This launches INotifyCollectionChanged with the Replace action.

But this may not be acceptable in your case. And this could be seen as a hack rather than a hard decision.

I would seriously think about having a DataTemplate for the address. There you should bind to the properties you need (which would create a listener for INotifyPropertyChanged). It is more flexible than ToString (), and you may run into situations where you need ToString () to do something for things other than the UI, which would create a conflict. And frankly, ToString is not really designed to create a user interface.

+2
source

Source: https://habr.com/ru/post/1303296/


All Articles