使用 MVVM 绑定 ComboBox SelectedItem [英] Binding ComboBox SelectedItem using MVVM

查看:39
本文介绍了使用 MVVM 绑定 ComboBox SelectedItem的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的 ComboBox 中的 SelectedItem 有问题.

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"/>

如果我打开 ComboBox,我会看到值.

If I open the ComboBox, I see the values.

如果我选择一个项目,则不会显示所选项目.

有人有想法吗?

在我的 ViewModel 中,我有这两个属性:

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

<小时>

编辑:如果我删除属性 DisplayMemberPath,则会发生以下情况:


EDIT: The Following happens If I remove the Property DisplayMemberPath:

推荐答案

您似乎在 ComboBox 上不必要地设置了属性.您可以删除具有不同用途的 DisplayMemberPathSelectedValuePath 属性.您可能需要查看 SelectedItem、SelectedValue 和 SelectedValuePath 之间的差异 在这里发布对这些属性的解释.试试这个:

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"/>

此外,使用您的 displayPeriod 属性毫无意义,因为 WPF 框架会为需要显示但没有DataTemplate 为它们明确设置.

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.

更新>>>

由于我无法看到您的所有代码,因此我无法告诉您您做错了什么.相反,我所能做的就是为您提供一个完整的工作示例,说明如何实现您想要的.我已经从你的班级中删除了毫无意义的 displayPeriod 属性和你的 SalesPeriodVO 属性,因为我对此一无所知......也许这就是你的问题的原因??.试试这个:

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

然后用你的值初始化集合:

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

然后数据将only这两个属性绑定到一个ComboBox:

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

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

就是这样......这是一个完美工作示例所需的全部内容.您应该看到项目的显示来自 ToString 方法没有您的 displayPeriod 属性.希望您能从这个代码示例中找出错误.

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.

这篇关于使用 MVVM 绑定 ComboBox SelectedItem的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆