3
votes

I have spent considerable amount of time investigating this problem. Any help would be greatly appreciated.

I have a WPF ComboBox declared like this.

<Grid>
<Grid.RowDefinitions>
    <RowDefinition/>
    <RowDefinition/>
    <RowDefinition/>
</Grid.RowDefinitions>
    <Button Click="Button_Click">Click Me</Button>
    <ComboBox ItemsSource="{Binding ListOfValues}" SelectedItem="{Binding MySelectedItem}" Grid.Row="1">
    </ComboBox>
    <CheckBox IsChecked="{Binding IsValueChecked}" Grid.Row="2"></CheckBox>
</Grid>

In my code behind, i have these properties and i am implementing the INotifyPropertyChanged

    public Window1()
    {
        InitializeComponent();
        ListOfValues = new List<string>();
        ListOfValues.Add("apple");
        ListOfValues.Add("ball");
        ListOfValues.Add("cat");
        ListOfValues.Add("dog");
        MySelectedItem = "cat";
        IsValueChecked = true;
    }

    public List<string> ListOfValues
    {
        get
        {
            return _listOfValues;
        }
        set
        {
            _listOfValues = value;
            OnPropertyChanged("ListOfValues");
        }
    }

    public string MySelectedItem
    {
        get
        {
            return _selectedValueString;
        }
        set
        {
            _selectedValueString = value;
            OnPropertyChanged("MySelectedItem");
        }
    }

    public bool IsValueChecked
    {
        get
        {
            return _isVlaueChanged;
        }
        set
        {
            _isVlaueChanged = value;
            OnPropertyChanged("IsValueChecked");
        }
    }
    private void Button_Click(object sender, RoutedEventArgs e)
    {
        MySelectedItem = "dog";
        IsValueChecked = !IsValueChecked;
    }

The button click event changes the MySelectedItem which is bound to the SelectedItem property of the combobox. But upon the button click nothing gets selected in the combobox. I dont understand why. This happens even if i set explicitly Mode=TwoWay. Please suggest. Note that my datacontext is set to self, so i have confirmed that data binding is happening properly by adding a checkbox

EDIT: Note that this happens in a sample WPF project. But my original project where i want this to work is a winforms app. I am using the elementhost to embed my wpf control. Is that making a difference?

3

3 Answers

3
votes

The selected item needs to be set to an object in the list you have it bound to. settings it to a string with a matching value won't work. So try this:

foreach(string animal in ListOfValues)
{
    if( animal == "dog")
      this.MySelectedItem = animal;
}
3
votes

I tried to reproduce your problem and I have some questions. Can you please show me your implementation of OnPropertyChanged? When I have a look at the MSDN (http://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.onpropertychanged.aspx) this function requires a DependencyPropertyChangedEventArgs as the first parameter, not a string. And in addition, OnPropertyChanged is for notifying about changes in Dependency Properties, not for normal properties. So I think you overloaded that method to support INotifyPropertyChanged, right?

I tried to implement a working example, this is the result:

public partial class TestWindow2 : Window, INotifyPropertyChanged
{
    public TestWindow2()
    {
        InitializeComponent();

        ListOfValues = new List<string> { "apple", "ball", "cat", "dog" };
        MySelectedItem = "cat";
        IsValueChecked = true;

        this.DataContext = this;
    }

    ...

    public string MySelectedItem
    {
        get
        {
            return _selectedValueString;
        }
        set
        {
            _selectedValueString = value;
            RaisePropertyChanged("MySelectedItem");
        }
    }

    ...

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        MySelectedItem = "dog";
        IsValueChecked = !IsValueChecked;
    }

    private void RaisePropertyChanged(String name)
    {
        if( this.PropertyChanged != null ) this.PropertyChanged(this, new PropertyChangedEventArgs(name));
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

Works perfectly for me. When I click the button, dog becoms the selected item in the combo box and the checkbox toggles its state.

0
votes

If your items are a reference type (and you are just using string for an example), check that the Equals() method is returning what you expect. You might need to override the Equals method (eg this.ID ==other.ID or something like that) to get the correct behavior.