0

I am trying to set a ComboBox SelectedItem from my VM. I think I am close, but I do not know how to show the SelectedItem in the ComboBox when it is set from the VM.

The textbox is has a binding to the SelectedItem Property. When I run it, it will indeed show Friday in my TextBox, but the combobox is still empty. The TextBox also shows any value I may select in my ComboBox, So I think Ihave done that part ok. What do I need to change to also show it in the ComboBox? Not sure I made a mistake in the code, or I simply need to do something I am not aware of to be honest.

The sample DB is WeekDays

WeekDayID    WeekDayShort   WeekDayLong
    1            Sun          Sunday
    2            Mon          Monday
    3            Tue          Tuesday
    4            Wed          Wednesday
    5            Thu          Thursday
    6            Fri          Friday
    7            Sat          Saturday

Model WeekDays.cs :

public partial class WeekDays
{
    public int WeekDayID { get; set; }
    public string WeekDayShort { get; set; }
    public string WeekDayLong { get; set; }
}

ViewModel MainViewModel.cs :

class MainViewModel : BindableBase
{
    private ObservableCollection<WeekDays> _weekDays;
    public ObservableCollection<WeekDays> WeekDays
    {
        get
        {
            return _weekDays;
        }
        set
        {
            SetProperty(ref _weekDays, value);
        }
    }

    private WeekDays _selectedWeekDay;
    public WeekDays SelectedWeekDay
    {
        get
        {
            return _selectedWeekDay;
        }
        set
        {
            SetProperty(ref _selectedWeekDay, value);
        }
    }

    private void FillWeekDays()
    {
        using (NLTrader01Entities nlt = new NLTrader01Entities())
        {
            var q = (from a in nlt.WeekDays select a).ToList();
            WeekDays = new ObservableCollection<WeekDays>(q);
        }
    }

    public MainViewModel()
    {
        FillWeekDays();
        Initialize();
    }

    public void Initialize()
    {
        using (NLTrader01Entities nlt = new NLTrader01Entities())
        {
            SelectedWeekDay = (from a in nlt.WeekDays where a.WeekDayLong == "Friday" select a).Single();
        }
    }
}

And the View.xaml :

<ComboBox
    ItemsSource="{Binding WeekDays}"
    DisplayMemberPath="WeekDayLong"
    SelectedItem="{Binding SelectedWeekDay, Mode=TwoWay}">
</ComboBox>
<TextBox
    Text="{Binding SelectedWeekDay.WeekDayLong, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
</TextBox>
Joey Joystick
  • 145
  • 1
  • 11

2 Answers2

0

When you want to select an item in a ComboBox by the value of a property of its item class, you should set the SelectedValue and SelectedValuePath properties instead of SelectedItem:

<ComboBox ItemsSource="{Binding WeekDays}"
          DisplayMemberPath="WeekDayLong"
          SelectedValuePath="WeekDayLong"
          SelectedValue="{Binding SelectedWeekDay}"/>

In the view model, the SelectedWeekDay property is no longer a WeekDay instance, but just a string:

private string _selectedWeekDay;
public string SelectedWeekDay
{
    get { return _selectedWeekDay; }
    set { SetProperty(ref _selectedWeekDay, value); }
}

The TextBox Binding would look like this:

<TextBox Text="{Binding SelectedWeekDay, UpdateSourceTrigger=PropertyChanged}"/>

And you would of course simply set it in code behind like this:

SelectedWeekDay = "Friday";
Clemens
  • 123,504
  • 12
  • 155
  • 268
  • I tried the above at no reveal. The only thing I am getting out of this is that I am setting the TextBox value to "Friday". – Joey Joystick Mar 16 '18 at 22:26
  • Works fine for me. – Clemens Mar 16 '18 at 22:34
  • The property SelectedWeekDay is obviously set properly because the binding to the TextBox works just fine. Maybe I can test if the SelectedValue has been set properly? – Joey Joystick Mar 16 '18 at 22:46
  • Did you perhaps just forget to set `SelectedValuePath="WeekDayLong"`? – Clemens Mar 17 '18 at 07:13
  • No, that's not it I think. Checked this over and over again. – Joey Joystick Mar 17 '18 at 10:35
  • I have also tried it with 'Mode=TwoWay' and 'UpdateSourceTrigger=PropertyChanged' both on 'SelectedValue' on the ComboBox. Makes no difference either. – Joey Joystick Mar 17 '18 at 10:40
  • I just found I can set it with SelectedItem. It than does not matter anymore whether I used SelectedValue (with SelectedValuePath of course) or SelectedItem. Only need to change my TextBox Binding to make it work. Thanks for guiding me in the right direction. But I still do not understand why your solution did not work out of the box. Very strange. Should I have an additional NameSpace in the XAML code perhaps? – Joey Joystick Mar 17 '18 at 10:59
0

Thanks to Clemens for guiding me in the right direction here 2 possible answers that worked for me.

Solution 01:

Continuation of using SelectedItem and introducing SelectedIndex.

ViewModel MainViewModel.cs :

class MainViewModel : BindableBase
{
    private ObservableCollection<WeekDays> _weekDays;
    public ObservableCollection<WeekDays> WeekDays
    {
        get
        {
            return _weekDays;
        }
        set
        {
            SetProperty(ref _weekDays, value);
        }
    }

    private int _selectedIndex;
    public int SelectedIndex
    {
        get
        {
            return _selectedIndex;
        }
        set
        {
            SetProperty(ref _selectedIndex, value);
        }
    }

    private WeekDays _selectedWeekDay;
    public WeekDays SelectedWeekDay
    {
        get
        {
            return _selectedWeekDay;
        }
        set
        {
            SetProperty(ref _selectedWeekDay, value);
        }
    }

    private void FillWeekDays()
    {
        using (NLTrader01Entities nlt = new NLTrader01Entities())
        {
            var q = (from a in nlt.WeekDays select a).ToList();
            WeekDays = new ObservableCollection<WeekDays>(q);
        }
    }

    public MainViewModel()
    {
        FillWeekDays();
        SelectedIndex = 4;        
    }
}

And the View.xaml :

<ComboBox
    ItemsSource="{Binding WeekDays}"
    DisplayMemberPath="WeekDayLong"
    SelectedItem="{Binding SelectedWeekDay}"
    SelectedIndex="{Binding SelectedIndex}">
</ComboBox>
<TextBox
    Text="{Binding SelectedWeekDay.WeekDayLong}">
</TextBox>

Solution 02:

Combination of using SelectedIndex and SelectedValue with SelectedValuePath.

ViewModel MainViewModel.cs :

class MainViewModel : BindableBase
{
    private ObservableCollection<WeekDays> _weekDays;
    public ObservableCollection<WeekDays> WeekDays
    {
        get
        {
            return _weekDays;
        }
        set
        {
            SetProperty(ref _weekDays, value);
        }
    }

    private int _selectedIndex;
    public int SelectedIndex
    {
        get
        {
            return _selectedIndex;
        }
        set
        {
            SetProperty(ref _selectedIndex, value);
        }
    }

    private WeekDays _selectedWeekDay;
    public WeekDays SelectedWeekDay
    {
        get
        {
            return _selectedWeekDay;
        }
        set
        {
            SetProperty(ref _selectedWeekDay, value);
        }
    }

    private void FillWeekDays()
    {
        using (NLTrader01Entities nlt = new NLTrader01Entities())
        {
            var q = (from a in nlt.WeekDays select a).ToList();
            WeekDays = new ObservableCollection<WeekDays>(q);
        }
    }

    public MainViewModel()
    {
        FillWeekDays();
        SelectedIndex = 4;       
    }
}

And the View.xaml :

<ComboBox
    ItemsSource="{Binding WeekDays}"
    DisplayMemberPath="WeekDayLong"
    SelectedValuePath="WeekDayLong"
    SelectedValue="{Binding SelectedWeekDay}"
    SelectedIndex="{Binding SelectedIndex}">
</ComboBox>
<TextBox
    Text="{Binding SelectedWeekDay.WeekDayLong}">
</TextBox>
Joey Joystick
  • 145
  • 1
  • 11