Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ComboBox SelectedValue doesn't show

I have a strange problem in my WinRT/C# XAML Metro app, using the Windows 8 Release Preview (latest patches installed). I'm using a ComboBox, whose values ItemsSource and SelectedValue are bound to properties in a ViewModel:

<ComboBox SelectedValue="{Binding MySelectedValue, Mode=TwoWay}"
          ItemsSource="{Binding MyItemsSource, Mode=OneWay}"
          Width="200" Height="30" />

Code behind:

public MainPage()
{
    this.InitializeComponent();

    DataContext = new TestViewModel();
}

And a very simple definition of the TestViewModel, using strings:

public class TestViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private IEnumerable<string> _myItemsSource = new List<string>
        {
            "Test Item 1",
            "Test Item 2",
            "Test Item 3"
        };
    public IEnumerable<string> MyItemsSource
    {
        get { return _myItemsSource; }
    }

    private string _mySelectedValue = "Test Item 2";
    public string MySelectedValue
    {
        get { return _mySelectedValue; }
        set
        {
            _mySelectedValue = value;
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs("MySelectedValue"));
            }
        }
    }
}

Now I thought this simple solution should just work... But when I start the app, the SelectedValue="Test Item 2" doesn't show up, the ComboBox is left empty. By setting breakpoints I noticed that the bound values MyItemsSource and MySelectedValue are corectly retrieved from the View Model when I set the DataContext of the view. After this action, the ComboBox.SelectedValue property is actually set to "Test Item 2", but it just doesn't show! Also I noticed that when I change the selected value in the ComboBox by user action on the UI, the changed value shows up in the ComboBox and the View Model property is updated accordingly. So everything seems to work fine except the initial visualization of the MySelectedValue View Model property. I'm becoming really desperate about that...

Now while this is the simplest example, in the origin I wanted to bind whole entities to ComboBox, setting DisplayMemberPath and SelectedValuePath. Unfortunately, the same problem occurs.

like image 741
Matthias Avatar asked Jul 14 '12 09:07

Matthias


2 Answers

I found the problem in my example: In the XAML markup I've defined the SelectedValue property before the ItemsSource property. If I swap both definitions in this way, it works:

<ComboBox ItemsSource="{Binding MyItemsSource, Mode=OneWay}"
      SelectedValue="{Binding MySelectedValue, Mode=TwoWay}"
      Width="200" Height="30" />

This is really odd and annoying. Now I would like to know: is this a bug or by design? I think this is a bug, because the control should be working regardless of the order of the defined properties in XAML.

like image 89
Matthias Avatar answered Nov 11 '22 21:11

Matthias


this is working solution : you can find here https://skydrive.live.com/?cid=b55690d11b67401d&resid=B55690D11B67401D!209&id=B55690D11B67401D!209

<ComboBox Width="300" Height="32" HorizontalAlignment="Left" DisplayMemberPath="Name"
                  VerticalAlignment="Top" ItemsSource="{Binding PersonCollection}" 
                  SelectedItem="{Binding SelectedPerson, Mode=TwoWay}"></ComboBox>

ViewModle class is

public class ViewModel:BaseViewModel
    {
        private Person selectedPerson;
        public Person SelectedPerson {
            get { return this.selectedPerson; }
            set { this.selectedPerson = value;
            this.RaisePropertyChanged("SelectedPerson");
            }
        }
        public ObservableCollection<Person> PersonCollection { get; set; }

        public ViewModel()
        {
            this.PersonCollection = new ObservableCollection<Person>();
            this.PopulateCollection();

            //setting first item as default one
            this.SelectedPerson = this.PersonCollection.FirstOrDefault();
        }

        private void PopulateCollection()
        {
            this.PersonCollection.Add(new Person { Name="Oscar", Email="[email protected]" });
            this.PersonCollection.Add(new Person { Name = "Jay", Email = "[email protected]" });
            this.PersonCollection.Add(new Person { Name = "Viral", Email = "[email protected]" });
        }
    }
like image 25
Pranay Rana Avatar answered Nov 11 '22 23:11

Pranay Rana