Подтвердить что ты не робот

Связывание ComboBox SelectedItem с использованием MVVM

У меня проблема с SelectedItem в моем ComboBox.

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

Here is anything ok Если я открываю ComboBox, я вижу значения.

enter image description here Если я выберу элемент, выбранный элемент не будет отображаться.

Есть ли у кого-нибудь идея?

В моей модели ViewModel у меня есть эти два свойства:

public ObservableCollection<SalesPeriodVM> SalesPeriods { get; private set; }

private SalesPeriodVM selectedSalesPeriod;
public SalesPeriodVM SelectedSalesPeriod
{
    get { return selectedSalesPeriod; }

    set 
    {
        if (selectedSalesPeriod != value)
        {
            selectedSalesPeriod = value;
            RaisePropertyChanged("SelectedSalesPeriod");
        }
    }
}

Это несколько свойств класса:

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);
}

ИЗМЕНИТЬ: Следующее произойдет, если я удалю Property DisplayMemberPath: enter image description here

4b9b3361

Ответ 1

Кажется, вы ненужно устанавливаете свойства на ComboBox. Вы можете удалить свойства DisplayMemberPath и SelectedValuePath, которые имеют разные применения. Возможно, вам стоит взглянуть на Разницу между SelectedItem, SelectedValue и SelectedValuePath для объяснения этих свойств. Попробуйте следующее:

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

Кроме того, это бессмысленно с помощью вашего свойства displayPeriod, так как WPF Framework автоматически вызовет метод ToString для объектов, которые ему нужно отобразить, которые не установлены DataTemplate для них явно.


ОБНОВЛЕНИЕ → >

Поскольку я не вижу весь ваш код, я не могу сказать вам, что вы делаете неправильно. Вместо этого все, что я могу сделать, это предоставить вам полный рабочий пример того, как добиться того, чего вы хотите. Я удалил бессмысленное свойство displayPeriod, а также ваше свойство SalesPeriodVO из вашего класса, поскольку я ничего не знаю об этом... может быть, это причина вашей проблемы??. Попробуйте следующее:

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"));
        }
    }
}

Затем я добавил два свойства в модель представления:

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"); }
}

Затем инициализируется коллекция с вашими значениями:

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

Затем данные привязывали только эти два свойства к ComboBox:

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

Что это... все, что вам нужно для отлично работающего примера. Вы должны увидеть, что отображение элементов происходит из метода ToString без вашего свойства displayPeriod. Надеюсь, вы можете исправить свои ошибки из этого примера кода.