Search code examples
wpfmvvmdependency-propertiesinotifypropertychangedpostsharp

Property resets when changing Usercontrols DependencyProperty


I've constructed a "Manager" of "Widgets" where i have a ListView/GridView with widgets.

The ListView binds the SelectedItem to a SelectedWidget property on the (Manager) ViewModel.

The SelectedWidget binds to a Usercontrol called WidgetConfig via a DependencyProperty called "Widget" where you can modify the properties of the selected Widget.

In the WidgetConfig , there are 2 RadioButtons:

<RadioButton GroupName="Lead" IsChecked="{Binding Widget.prop1, Mode=TwoWay, ElementName=root}" />
<RadioButton GroupName="Lead" IsChecked="{Binding Widget.prop2, Mode=TwoWay, ElementName=root}" />

When i select the 'prop2', the INPC signal is correctly sent and the model is updated accordingly. If then i click on the 'prop1', the INPC signal is sent + i get an additional signal from the prop2 radiobutton.

Here's the problem: if i select prop2 and then select another Widget in the ListView. I get a INPC signal and prop2 has changed back to false!

what's going on ?

Some info:

  • The WidgetConfiguration is implemented using PostSharp NotifyPropertyChanged aspect.
  • The WidgetConfig UserControl is implemented by hand with DependencyProperty and INotifyPropertyChanged interface

EDIT:

I've created a reproducible example here : https://github.com/Montago/INCP-DP-BindingExample


Solution

  • What you have is a chain of two-way bindings, which are changing values on your Model:

    Two-way binding between ListControl.SelectedItem(DP) and the ViewModel.SelectedModel(INPC).

    Two-way binding between ViewModel.SelectedModel(INPC) and ModelControl.ActiveModel(DP).

    Two-way binding between ModelControl.ActiveModel(DP) and Model.Prop1/Model.Prop2/Model.Name(INPC).

    When you select First, Second and then again First, Second's prop2 is overwritten to false by WPF data binding.

    A way to fix this is to remove the two-way binding that makes the overwrite of prop2, i.e. specify Mode=OneWay on RadioButton bindings.

    My guess of what is happening: RadioButton's logic and two-way binding. When Second is selected in the list box and you change the selection to First, WPF's data binding sets Prop1 radio button as selected (because First.prop1 == true). At that point, the second radio button is still selected, so to respect the group principle, it needs to get unselected. However, there is still the two-way binding active on the Prop2 radio and thus Second.prop2 gets set to false.