Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Binding ComboBox SelectedItem using MVVM

I have a problem with the SelectedItem in my ComboBox.

<ComboBox Name="cbxSalesPeriods"         ItemsSource="{Binding SalesPeriods}"         DisplayMemberPath="displayPeriod"         SelectedItem="{Binding SelectedSalesPeriod}"         SelectedValuePath="displayPeriod"         IsSynchronizedWithCurrentItem="True"/> 

Here is anything ok If I open the ComboBox, I see the values.

enter image description hereIf I select an item, the selected Item won't be shown.

Has anybody an idea?

In my ViewModel I have these two properties:

public ObservableCollection<SalesPeriodVM> SalesPeriods { get; private set; }  private SalesPeriodVM selectedSalesPeriod; public SalesPeriodVM SelectedSalesPeriod {     get { return selectedSalesPeriod; }      set      {         if (selectedSalesPeriod != value)         {             selectedSalesPeriod = value;             RaisePropertyChanged("SelectedSalesPeriod");         }     } } 

These are a few properties from the class :

public SalesPeriodVO Vo {     get { return period; } }  public int Year {     get { return period.Year; }     set     {         if (period.Year != value)         {             period.Year = value;             RaisePropertyChanged("Year");         }     } }  public int Month {     get { return period.Month; }     set     {         if (period.Month != value)         {             period.Month = value;             RaisePropertyChanged("Month");         }     } }  public string displayPeriod {      get     {         return this.ToString();     } }  public override string ToString() {     return String.Format("{0:D2}.{1}", Month, Year); } 

EDIT: The Following happens If I remove the Property DisplayMemberPath: enter image description here

like image 651
René Winter Avatar asked Oct 28 '13 10:10

René Winter


People also ask

How do I bind a ComboBox in WPF MVVM?

Select Item and display member property. Here, in item source, we give the collection name and in selected item, we give single person property. We have to define the display member here and you have to give whatever we have to display in combo box dropdown list. Now, run the Application and show the result.

How do I bind a ComboBox in XAML?

xaml has an ItemsControl bound to the collection of ConnectionViewModels. I have a DataTemplate that holds the ComboBox as well as some other TextBoxes. The TextBoxes are bound directly to properties of the ConnectionViewModel using Text="{Binding Path=ConnectionName}" .

What is ComboBox in WPF?

Advertisements. A combobox is a selection control that combines a non-editable textbox and a drop-down listbox that allows users to select an item from a list. It either displays the current selection or is empty if there is no selected item.


1 Answers

You seem to be unnecessarily setting properties on your ComboBox. You can remove the DisplayMemberPath and SelectedValuePath properties which have different uses. It might be an idea for you to take a look at the Difference between SelectedItem, SelectedValue and SelectedValuePath post here for an explanation of these properties. Try this:

<ComboBox Name="cbxSalesPeriods"     ItemsSource="{Binding SalesPeriods}"     SelectedItem="{Binding SelectedSalesPeriod}"     IsSynchronizedWithCurrentItem="True"/> 

Furthermore, it is pointless using your displayPeriod property, as the WPF Framework would call the ToString method automatically for objects that it needs to display that don't have a DataTemplate set up for them explicitly.


UPDATE >>>

As I can't see all of your code, I cannot tell you what you are doing wrong. Instead, all I can do is to provide you with a complete working example of how to achieve what you want. I've removed the pointless displayPeriod property and also your SalesPeriodVO property from your class as I know nothing about it... maybe that is the cause of your problem??. Try this:

public class SalesPeriodV {     private int month, year;      public int Year     {         get { return year; }         set         {             if (year != value)             {                 year = value;                 NotifyPropertyChanged("Year");             }         }     }      public int Month     {         get { return month; }         set         {             if (month != value)             {                 month = value;                 NotifyPropertyChanged("Month");             }         }     }      public override string ToString()     {         return String.Format("{0:D2}.{1}", Month, Year);     }      public virtual event PropertyChangedEventHandler PropertyChanged;     protected virtual void NotifyPropertyChanged(params string[] propertyNames)     {         if (PropertyChanged != null)         {             foreach (string propertyName in propertyNames) PropertyChanged(this, new PropertyChangedEventArgs(propertyName));             PropertyChanged(this, new PropertyChangedEventArgs("HasError"));         }     } } 

Then I added two properties into the view model:

private ObservableCollection<SalesPeriodV> salesPeriods = new ObservableCollection<SalesPeriodV>(); public ObservableCollection<SalesPeriodV> SalesPeriods {     get { return salesPeriods; }     set { salesPeriods = value; NotifyPropertyChanged("SalesPeriods"); } } private SalesPeriodV selectedItem = new SalesPeriodV(); public SalesPeriodV SelectedItem {     get { return selectedItem; }     set { selectedItem = value; NotifyPropertyChanged("SelectedItem"); } } 

Then initialised the collection with your values:

SalesPeriods.Add(new SalesPeriodV() { Month = 3, Year = 2013 } ); SalesPeriods.Add(new SalesPeriodV() { Month = 4, Year = 2013 } ); 

And then data bound only these two properties to a ComboBox:

<ComboBox ItemsSource="{Binding SalesPeriods}" SelectedItem="{Binding SelectedItem}" /> 

That's it... that's all you need for a perfectly working example. You should see that the display of the items comes from the ToString method without your displayPeriod property. Hopefully, you can work out your mistakes from this code example.

like image 54
Sheridan Avatar answered Oct 02 '22 22:10

Sheridan