2

I am using WPF with databinding. I have a Combobox bound to a list of strings. I want the selected item in the list to set a field in my View Model. However, I sometimes want to override the user's selection and re-set the selected value in the Combobox but I don't seem to be able to do that.

Here's the View Model code:

public class SettingsViewModel : INotifyPropertyChanged
{
    public enum RateTypes
    {
        [Description("128Hz")]
        Hz128 = 4,
        [Description("256Hz")]
        Hz256 = 6,
        [Description("400Hz")]
        Hz400 = 7,
        [Description("512Hz")]
        Hz512 = 8,
        [Description("600Hz")]
        Hz600 = 9
    }

    RateTypes m_SelectedRate;
    List<string> RateOptions = ((RateTypes [])Enum.GetValues(typeof(RateTypes)))
                                                  .Select(o => o.Description())
                                                  .ToList();

    public string SelectedRate
    {
        get {return m_SelectedRate.Description();}
        set
        {
          if (value == RateType.Hz256)
          {
                MessageBox.Show("256Hz not an option with your system");
                m_SelectedRate= IMURate.Hz400;
          }
          else
          {
              m_SelectedRate = value;
          }
          OnPropertyChanged(nameof(SelectedRate));
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propertyChanged)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            var e = new PropertyChangedEventArgs(propertyChanged);
            handler(this, e);
        }
    }
}

and the XAML has:

<ComboBox Grid.SelectedItem="{Binding SelectedRate, Mode=TwoWay}" ItemsSource="{Binding RateOptions}"> 

However, when I select 256Hz in the GUI, the value displayed stays as 256Hz instead of changing to 400Hz. If I call OnPropertyChanged(SelectedRate) from a separate function, the value does change.

I've tried using SelectedValue and UpdateSourceTrigger but can't find anything that works.

Any ideas?

CAS
  • 41
  • 4

2 Answers2

2

Unbelieveable. I spent hours searching for an answer before posting that question but then 10 minutes after posting, I thought of a new search term that led me to the answer.

I simply needed to add IsAsync="true" to SelectedValue in the XAML:

<ComboBox Grid.SelectedItem="{Binding SelectedRate, Mode=TwoWay, IsAsync="true"}" ItemsSource="{Binding RateOptions}"> 

Oh well, hopefully this will help someone else.

CAS
  • 41
  • 4
  • thanks a lot. I had a similiar problem. This seems to work, though when the app starts i have to select a different item twice to get the different item selected. Still better than freezing in infinite loop like before. There is another solution with using a dispatcher, but I wasnt able to get it to work. – Welcor Aug 01 '19 at 15:39
0

Add Delay=1 fixed the problem for me. The IsAsync=true approach worked, too, but it seems to update the combobox slower sometimes and it created a bug in my GUI where changing the Combobox value in the gui doesnt work once after App start up.

<ComboBox Grid.SelectedItem="{Binding SelectedRate, Mode=TwoWay, Delay=1}" ItemsSource="{Binding RateOptions}"> 
Welcor
  • 2,431
  • 21
  • 32