WPF ComboBox databinding ItemsSource item.ToString() to property setter. Why

comboboxdata-bindingmvvmwpf

For some reason when I bind a ComboBox to a list of POCOs, the property which is bound to SelectedValue is set twice:

  1. With value = POCO.ToString()
  2. With value = POCO.Key property, which is the intended behaviour

I have the following ComboBox that is bound to properties in my ViewModel:

<ComboBox ItemsSource="{Binding Path=AllowedClassifications}" 
          DisplayMemberPath="Value" 
          SelectedValue="{Binding Path=TargetGroup.Classification}" 
          SelectedValuePath="Key" />

The properties in ViewModel are defined as:

//ICollection is implemented by ObservableCollection<T>
//DataBaseFieldValue has two public properties: string Key, string Value
public ICollection<DatabaseFieldValue> AllowedClassifications
{
    get { return _allowedClassifications; }
    private set { _allowedClassifications = value; }
}

public Model.TargetGroup TargetGroup
{
    get { return _targetGroup; }
    private set { _targetGroup = value; OnPropertyChanged("TargetGroup"); }
}   

TargetGroup.Classification is defined as:

public string Classification
{
    get { return _classification; }
    set 
    {
        System.Diagnostics.Debug.WriteLine("Classification: " + value);
        _classification = value; 
        OnPropertyChanged("Classification"); 
    }
}

Debug output:

Classification:
MyNamespace.DatabaseFieldValue

Classification: 2

What's happening here? Am I doing this completely wrong?

Best Answer

Everything looks OK in your code, except for the fact that according to your XAML the property which is bound to SelectedValue should be set to the POCO.Key value rather than POCO.Value (as you wrote you expected). I have just created a test project with similar setup and everything works.

Alternatively, you could try using SelectedItem property of combobox in combination with ItemTemplate:

<ComboBox ItemsSource="{Binding Path=AllowedClassifications}"    
          SelectedItem="{Binding Path=TargetGroup.Classification}" >
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Value}"/>
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>

In this case the TargetGroup.Classification property must be of type DatabaseFieldValue.

Related Topic