1

When binding ComboBox to referenced source:

<ComboBox SelectedValue="{Binding Source.SelectedItem}"
          ItemsSource="{Binding Source.Items}"
          DisplayMemberPath="Name" />

where Source is

SourceType _source;
public SourceType Source
{
    get { return _source; }
    set { _source = value; OnPropertyChanged(); }
}

and SourceType is

public class SourceType: INotifyPropertyChanged
{
    Item _selectedItem;
    public Item SelectedItem
    {
        get { return _selectedItem; }
        set { _selectedItem = value; OnPropertyChanged(); }
    }

    public IReadOnlyList<Item> Items { get; }

    public SourceType(...)
    {
        Items = new List<Items>(...) // **new** list generated from passed arguments
        SelectedItem = Items.First();
    }
}

and Item is

public class Item: INotifyPropertyChanged
{
    string _name;
    public string Name
    {
        get { return _name; }
        set { _name = value; OnPropertyChanged(); }
    }
}

following happens:

  • for only one source (if Source never changes) it works: ComboBox display list of Items and correct item is selected (I can see its Name when switching view);
  • for more than one items ComboBox bugs: has no selection (but drop-down list is there and working fine), selection doesn't persist when switching view or Source is changed (e.g. between 2 sources).

It seems like ComboBox has some problems to identify SelectedValue or find it in the ItemsSource. And I can't figure out what is wrong.

Debugging does not uncover anything: Items is set correctly, SelectedItem is first item from Items collection, yet ComboBox is displayed without selection. Why?

dbc
  • 104,963
  • 20
  • 228
  • 340
Sinatr
  • 20,892
  • 15
  • 90
  • 319

2 Answers2

4

I will use a ObservableCollection instead of a List for Items and use SelectedItem for the ComboBox, not SelectedValue.

Read this great answer for differences between SelectedItem and SelectedValue Difference between SelectedItem, SelectedValue and SelectedValuePath

Community
  • 1
  • 1
Giangregorio
  • 1,482
  • 2
  • 11
  • 12
  • `ObservableCollection` won't help (list is not changed ever, no need for notification). But `SelectedItem` did the trick, thanks. Didn't noticed I am using wrong property to bind. – Sinatr Nov 25 '15 at 10:19
  • You're welcome. Feel free to accept the asnwer if it helped you. Good Work. – Giangregorio Nov 25 '15 at 10:21
0

@Giangregorio answer is good and working in general, but now I remember why I used SelectedValue in first place.

SelectedValue is useful whenever ItemsSource does not contains SelectedValue. If SelectedItem is used (as per answer), then binding will call setter with null as if the user could select null from the list. I am exploiting this case (to avoid having data-templates and more complicated ViewModel), so I have to stick with SelectedValue and I think I found the reason of the problem in otherwise should-work case.

I have to declare ItemsSource binding first and SelectedValue second:

<ComboBox ItemsSource="{Binding Source.Items}"
      SelectedValue="{Binding Source.SelectedItem}"
      DisplayMemberPath="Name" />

It works!

Sounds to me like another xaml-specific issue, similar to declare CommandParameter before Command problem.

Sinatr
  • 20,892
  • 15
  • 90
  • 319
  • Using SelectedValue without using SelectedValuePath shouldn't be different from using SelectedItem...however if it works , It works! – Giangregorio Nov 25 '15 at 17:02
  • @Giangregorio, yes, but it required exactly that order to work properly. Setting `ItemsSource` before setting `SelectedValue`. If `SelectedItem` is used then order doesn't matter. Which is ... interesting? – Sinatr Nov 26 '15 at 09:04