TwoWay Binding to ListBox SelectedItem in multiple lists in WPF

I have a scenario where I have a globally accessible Properties window (similar to the Properties window in Visual Studio) that is associated with the SelectedObject property of my model. I have several different ways to view and select objects, so the first attempt is to associate them with SelectedObject directly. For instance:

<ListBox ItemsSource="{Binding ActiveProject.Controllers}" SelectedItem="{Binding SelectedObject, Mode=TwoWay}"/> <ListBox ItemsSource="{Binding ActiveProject.Machines}" SelectedItem="{Binding SelectedObject, Mode=TwoWay}"/> 

This works well when I have more than one item in each list, but it fails if there is only one item in the list. When I select an item, SelectedObject is not updated, since the list still believes that its original item was selected. I believe this is because the two-way binding simply ignores the update from the source when SelectedObject is not an object in the list, leaving the SelectedItem list unchanged. In this way, the bindings become out of sync.

Does anyone know how to make sure that their SelectedItem is reset in the list when SelectedObject is not in the list? Is there a better way to do this so as not to suffer from this problem?

+4
source share
2 answers

Well, I found a way around this problem, but it hurts me a bit. I changed the SelectedObject property in my model to the following:

 public Object SelectedObject { get { return _selectedObject; } set { if (value != _selectedObject) { //HACK //Pulse 'null' between changes to reset listening list controls if (value != null) SelectedObject = null; if (_selectedObject != null) SelectedObjects.Remove(_selectedObject); _selectedObject = value; if (value != null) SelectedObjects.Add(value); } } } 

This forces all data-bound controls to reset their SelectedItem to null before we move on to the "real" SelectedObject element. On the other hand, NotifyPropertyChanged stuff is handled by PostSharp if you are wondering why it is missing.

I would prefer a less hacky solution if possible, but I like that it saves the bindings in XAML (no changes are required.)

+1
source

Dan's answer helped me solve my problem. It seems like the key is to bind the objects first regrouped with a null value, and then back to the new value.

Without Postsharp in my solution or any need to maintain a list of selected objects, this is the only code I need.

  Public Property MyProperty() As Object Get Return Me._MyProperty End Get Set(value As Object) Me._MyProperty = Nothing NotifyOfPropertyChange(Function() MyProperty) Me._MyProperty = value NotifyOfPropertyChange(Function() MyProperty) End Set End Property 
+3
source

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


All Articles