WPF MVVM ComboBox SelectedValue is cleared when na

2019-07-15 03:39发布

问题:

I've had an issue with the WPF ComboBox that I was eventually able to solve. The reason of the issue however is not clear.

The issue occurred when using a ComboBox where the ItemsSource was referencing a different DataContext than the SelectedValue. When doing this and navigating away, the SelectedValue property was set to null. Since some properties contain logic when changing (when field A changes, also change field B), some logic was executed incorrectly.

<ComboBox x:Name="Sector" 
                     ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.SectorList}" 
                     SelectedValuePath="Id" 
                     SelectedValue="{Binding SectorId, Mode=TwoWay}" />

I've found several similar issues (this one was probably the closest: https://stackoverflow.com/a/5033924/3357566), but none solved my problem. A lot of fixes had to do with the order of loading the ItemsSource and SelectedValue so this put me on the right track.

Instead of getting the DataContext from the UserControl through RelativeSources, I've traversed the ViewModels parents to find the SectorList, so the XAML is now as follows (notice the Root property):

<ComboBox x:Name="Sector" 
                     ItemsSource="{Binding Root.SectorList}" 
                     SelectedValuePath="Id" 
                     SelectedValue="{Binding SectorId, Mode=TwoWay}" />

Can someone give me an explanation why the latter code doesn't clear the SelectedValue when leaving a page and the first one does?

Edit

To clarify the structure of the ViewModels:

  • CustomerEntryViewModel
    • SectorList (and other lists to fill ComboBoxes which are only used in the CustomerEntryViewModel)
    • CustomerViewModel (separate ViewModel to reuse in other modules)
      • Name
      • Address
      • SectorId
      • ...

The DataContext of the View is CustomerEntryViewModel but its first container has the DataContext set to the CustomerViewModel. So to get to the SectorList from here, I either have to go to the DataContext of the UserControl through RelativeSource (first example) or I have to traverse my ViewModel parents to the top (second example).

The question remains as to why the behavior is different between the two examples.