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

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

问题描述

我的组合框中的 SelectedItem 有问题。

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

类:

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






/ strong>:
发生以下情况如果我删除属性DisplayMemberPath:


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

推荐答案

您似乎不必要地在 ComboBox 。您可以删除具有不同用途的 DisplayMemberPath SelectedValuePath 属性。这可能是一个想法,您可以查看 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框架会自动调用 ToString 方法,需要显示的对象不需要 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"); }
}

然后使用 值初始化集合:

Then initialised the collection with your values:

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

然后数据绑定这两个属性为 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天全站免登陆