Jakob Busk Sørensen
Jakob Busk Sørensen

Reputation: 6091

Using a Class as ValueMember in ComboBox

I have a ComboBox, which currently uses a simple class, containing Name and ID. Name is used as DisplayMember whereas ID is used as 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. 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?

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

}

Upvotes: 0

Views: 2093

Answers (2)

Fabio
Fabio

Reputation: 32455

You can access selected instance with SelectedItem property of combobox.
Only you need is cast to Eqipment type before using because SelectedItem is of type object.

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.

Upvotes: 2

krs
krs

Reputation: 599

There's no way how you can achieve this with pure C# without adding third property where you combine Name and ID. You can consider that 3rd property security like:

  • Is it enough to have only get?
  • Is it enough to have it protected?
  • etc.

When you're using XAML or WinForms, there's MultiBinding mechanism to achieve similar behavior. 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.

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.

Upvotes: 0

Related Questions