在 ComboBox 中使用 Class 作为 ValueMember
Using a Class as ValueMember in ComboBox
我有一个 ComboBox,目前使用简单的 class,包含 Name 和 ID。 名称用作DisplayMember
,而ID用作ValueMember
。但是,我实际上想在选择项目时同时传递 Name 和 ID,因为这样可以省去查找操作后来的名字。当然,我可以将它们分开存放,但这似乎是重复的,因为它们来自同一个地方。
因此我的问题出现了:是否可以将 class(我从中获取名称和 ID)用作 ComboBox
的 ValueMember
?
我在想这样的事情:
cboCategory.DataSource = viewModel.categoryOptions; // Type: BindingList<Equipment>
cboCategory.DisplayMember = "Name";
cboCategory.ValueMember = ??? // <--- This is where I run out of ideas
我的装备class是这样的:
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; }
}
}
如果不在组合 Name 和 ID 的地方添加第三个 属性,则无法使用纯 C# 实现此目的.
您可以考虑第 3 个 属性 安全性,例如:
- 只有
get
够吗?
- 够不够
protected
?
- 等等
当您使用 XAML 或 WinForms 时,有 MultiBinding
机制可以实现类似的行为。恕我直言,在大多数情况下,多重绑定是开销,创建第三个 属性.
更有益
所以你的 class 看起来像:
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; }
}
}
您可以使用 INotifyPropertyChanged
扩展 ViewModel 并在 Name[= 时通知 Identifier 更改36=] 或 ID 更改。
更复杂(如果需要)将返回对象数组而不是字符串,因此您不会在转换时丢失数据(ID.ToString()
)<- 需要更多内存。
您可以使用组合框的 SelectedItem
属性 访问所选实例。
使用前只需要转换为 Eqipment
类型,因为 SelectedItem
是 object
.
类型
var selectedEquipment = (Equipment)combobox.SelectedItem;
您也可以使用数据绑定来保持您的视图模型"loosely coupled"
cboCategory.DataSource = viewModel.categoryOptions;
cboCategory.DisplayMember = "Name";
cboCategory.ValueMember = "Id";
cboCategory.DataBinding.Add("SelectedItem", viewModel, "SelectedEquipment", true);
使用数据绑定 viewmodel.SelectedEquipment
属性 将在您更改组合框中的选定项目时更新。
我有一个 ComboBox,目前使用简单的 class,包含 Name 和 ID。 名称用作DisplayMember
,而ID用作ValueMember
。但是,我实际上想在选择项目时同时传递 Name 和 ID,因为这样可以省去查找操作后来的名字。当然,我可以将它们分开存放,但这似乎是重复的,因为它们来自同一个地方。
因此我的问题出现了:是否可以将 class(我从中获取名称和 ID)用作 ComboBox
的 ValueMember
?
我在想这样的事情:
cboCategory.DataSource = viewModel.categoryOptions; // Type: BindingList<Equipment>
cboCategory.DisplayMember = "Name";
cboCategory.ValueMember = ??? // <--- This is where I run out of ideas
我的装备class是这样的:
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; }
}
}
如果不在组合 Name 和 ID 的地方添加第三个 属性,则无法使用纯 C# 实现此目的. 您可以考虑第 3 个 属性 安全性,例如:
- 只有
get
够吗? - 够不够
protected
? - 等等
当您使用 XAML 或 WinForms 时,有 MultiBinding
机制可以实现类似的行为。恕我直言,在大多数情况下,多重绑定是开销,创建第三个 属性.
所以你的 class 看起来像:
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; }
}
}
您可以使用 INotifyPropertyChanged
扩展 ViewModel 并在 Name[= 时通知 Identifier 更改36=] 或 ID 更改。
更复杂(如果需要)将返回对象数组而不是字符串,因此您不会在转换时丢失数据(ID.ToString()
)<- 需要更多内存。
您可以使用组合框的 SelectedItem
属性 访问所选实例。
使用前只需要转换为 Eqipment
类型,因为 SelectedItem
是 object
.
var selectedEquipment = (Equipment)combobox.SelectedItem;
您也可以使用数据绑定来保持您的视图模型"loosely coupled"
cboCategory.DataSource = viewModel.categoryOptions;
cboCategory.DisplayMember = "Name";
cboCategory.ValueMember = "Id";
cboCategory.DataBinding.Add("SelectedItem", viewModel, "SelectedEquipment", true);
使用数据绑定 viewmodel.SelectedEquipment
属性 将在您更改组合框中的选定项目时更新。