Digital Camel
Digital Camel

Reputation: 305

WPF - Using CollectionViewSource is Causing Erroneous Setter Call

WPF, MVVM

I'm finding that if I use a CollectionViewSource with my ComboBox, when I close the window, an extra call to the SelectedValue Setter is executing, if SelectedValue is bound to a string property. If I set the ItemsSource binding directly to the VM, this call does not happen. The extra call is causing values to change in the VM, resulting in incorrect data. I have other ComboBoxes setup the same way, but they bind to integer values.

CollectionViewSource definition:

<CollectionViewSource x:Key="AllClientsSource" Source="{Binding AllClients}" >
  <CollectionViewSource.SortDescriptions>
    <scm:SortDescription PropertyName="ClientName" />
  </CollectionViewSource.SortDescriptions>
</CollectionViewSource>

ComboBox with CollectionViewSource:

<ComboBox Grid.Column="2"
          ItemsSource="{Binding Source={StaticResource AllClientsSource}}"
          DisplayMemberPath="ClientName" SelectedValuePath="ClientId"
          SelectedValue="{Binding Path=ClientId}"
          Visibility="{Binding Path=IsEditingPlan, Converter={StaticResource BoolVisibility}}" />

ComboBox direct to VM (Forgoing sorting):

<ComboBox Grid.Column="2" ItemsSource="{Binding AllClients}"
          DisplayMemberPath="ClientName" SelectedValuePath="ClientId" 
          SelectedValue="{Binding Path=ClientId}" 
          Visibility="{Binding Path=IsEditingPlan, Converter={StaticResource BoolVisibility}}" />

Can anyone tell me why there is an extra setter call using the CollectionViewSource? What's different about the string binding? Is there a way to properly work around it?

EDIT: I tried changing it up and using the SelectItem property on the ComboBox. Same result. So it seems that if the item is a scalar data type, it works as expected. If it's an object, you get an extra setter call with a null value. Again, if I remove the CollectionViewSource from the equation, it works as expected.

EDIT, AGAIN: I added a link to a sample project that illustrates the issue. Targets .Net 4.5.

The only difference between the views is that One and Two use a CollectionViewSource. Three binds directly to the ViewModel. When you move to a new tab from One or Two, the setter for the selected item is getting called with a null value. Why? What's the best work-around?

Thanks.

Upvotes: 0

Views: 216

Answers (1)

Digital Camel
Digital Camel

Reputation: 305

Apparently this is caused when the CollectionViewSource is removed from the visual tree... I moved the CollectionViewSource to the ViewModel and exposed it as a property and the issue is effectively worked-around.

Upvotes: 0

Related Questions