简体   繁体   English

在ComboBox中将类用作ValueMember

[英]Using a Class as ValueMember in ComboBox

I have a ComboBox, which currently uses a simple class, containing Name and ID . 我有一个ComboBox,当前使用一个简单的类,其中包含NameID Name is used as DisplayMember whereas ID is used as ValueMember . 名称用作DisplayMemberID用作ValueMember However, I would actually like to pass both the Name and the ID , when selecting an item, since this would spare me the operation of looking up the name later. 但是,实际上我想在选择一个项目时同时传递NameID ,因为这样可以避免以后查找名称的操作。 Of course I could store those seperately, but that seems rendundat, since they come from the same place. 当然,我可以将它们分开存储,但这似乎是难免的,因为它们来自同一地方。

Hence arises my question: Is it possible to use the class (from which I get the Name and ID) as ValueMember for the ComboBox ? 因此出现了我的问题:是否可以将类(从中获得名称和ID)用作ComboBox ValueMember

I was thinking something like this: 我在想这样的事情:

cboCategory.DataSource = viewModel.categoryOptions; // Type: BindingList<Equipment>
cboCategory.DisplayMember = "Name";
cboCategory.ValueMember = ???   // <--- This is where I run out of ideas

My Equipment class looks like this: 我的设备类如下所示:

public class Equipment
{
    private int id;
    private string name;

    public Equipment (int id, string name)
    {
        this.id = id;
        this.name = name;
    }

    public int Id
    {
        get { return id; }
        set { id = value; }
    }

    public string Name
    {
        get { return name; }
        set { name = value; }
    }

}

You can access selected instance with SelectedItem property of combobox. 您可以使用组合框的SelectedItem属性访问选定的实例。
Only you need is cast to Eqipment type before using because SelectedItem is of type object . 在使用之前,仅将您需要转换为Eqipment类型,因为SelectedItemobject类型。

var selectedEquipment = (Equipment)combobox.SelectedItem;

You can use data-binding as well to keep your viewmodel "loosely coupled" 您还可以使用数据绑定来使您的视图模型“松散耦合”

cboCategory.DataSource = viewModel.categoryOptions;
cboCategory.DisplayMember = "Name";
cboCategory.ValueMember = "Id";

cboCategory.DataBinding.Add("SelectedItem", viewModel, "SelectedEquipment", true);

With data-binding viewmodel.SelectedEquipment property will be updated when you change selected item in combobox. 使用数据绑定的viewmodel.SelectedEquipment属性将在组合框中更改所选项目时更新。

There's no way how you can achieve this with pure C# without adding third property where you combine Name and ID . 如果不添加将NameID组合在一起的第三个属性,就无法用纯C#实现此目的。 You can consider that 3rd property security like: 您可以考虑第三种属性安全性,例如:

  • Is it enough to have only get ? get就足够了吗?
  • Is it enough to have it protected ? protected它够了吗?
  • etc. 等等

When you're using XAML or WinForms, there's MultiBinding mechanism to achieve similar behavior. 当您使用XAML或WinForms时,可以使用MultiBinding机制来实现类似的行为。 IMHO, multi-binding is in most cases overhead and it is more beneficial to create 3rd property. 恕我直言,在大多数情况下多重绑定是开销,并且创建第三属性更有利。

So your class would look like: 因此您的课程如下所示:

public class Equipment
{
    private int id;
    private string name;

    public Equipment (int id, string name)
    {
        this.id = id;
        this.name = name;
    }

    public int Id
    {
        get { return id; }
        set { id = value; }
    }

    public string Name
    {
        get { return name; }
        set { name = value; }
    }

    public string Identifier
    {
        get { return Id.ToString() + " " + Name; }
    }
}

You can extent you ViewModel with INotifyPropertyChanged and notify about Identifier change when Name or ID changes. 您可以使用INotifyPropertyChanged ViewModel的名称 ,并在NameID更改时通知Identifier更改。

More sophisticated (if needed) will be returning array of objects instead of string so you wont lose data at conversion ( ID.ToString() ) <- require more memory. 更复杂(如果需要)将返回对象数组而不是字符串,因此您不会在转换时丢失数据( ID.ToString() )<-需要更多内存。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM