winforms ComboBox的SelectedValue不是我期望的类型

p8h8hvxi  于 2023-08-07  发布在  其他
关注(0)|答案(2)|浏览(116)

考虑一个由接口IMyInterface定义的复杂对象。我有一个这些对象的集合,我想在ComboBox中呈现以选择特定的示例:

IEnumerable<IMyInterface> myCollection = GetCollectionFromWhereverItOriginates();
cmb_MyBox.DataSource = myCollection.Select(x => new {Display = x.Name, Value = x}).ToList();
cmb_MyBox.DisplayMember = "Display";
cmb_MyBox.ValueMember = "Value";

字符串
首先,这产生了期望的结果。显示给用户的正是我指定的内容。但是当我想检索实际选择的对象/值时,事情开始崩溃。

private void cmb_MyBox_SelectedIndexChanged(object sender, EventArgs e)
{
    IMyInterface theSelectedObject = (IMyInterface)cmb_MyBox.SelectedValue; //Things fall apart
    DoSomethingAwesome(theSelectedObject);
}


我得到了一个InvalidCastException,因为匿名类型不能转换为IMyInterface。很奇怪。考虑到这可能与匿名类型有关,我创建了一个中间层:

class ComboBoxItem
{
    public string DisplayText {get; set;}
    public IMyObject TheValue {get; set;} //Chose "TheValue" on purpose to avoid any collisions with the reserved name "value" (No capitals!)
}

cmb_MyBox.DataSource = myCollection.Select(x => new ComboBoxItem() {Display = x.Name, TheValue = x}).ToList();


这改变了一些事情,异常仍然存在,但现在它告诉我,ComboBoxItem不能转换为IMyInterface
如果我正确理解了documentation(显然我没有),那么我会期望以下行为:

  • DataSource中的匿名类型有两个属性:Display(类型为string,因为IMyInterface.Name被定义为string)和Value(类型为IMyInterface,因为我创建所有内容的集合中的项类型为IMyInterface
  • 类似地,ComboBoxItem也有这两种类型的属性
  • 设置DisplayMemberValueMember指向 * 数据源中对象的属性 *,或者如文档所述:

获取或设置要用作ListControl中项的实际值的属性的路径。

  • ComboBoxSelectedValue被定义为object,因此需要转换为我需要检索它的具体类型。同样,documentation表示SelectedValue是DataSource对象的 * 属性,而不是DataSource对象本身 *

获取或设置由ValueMember属性指定的成员属性的值。
编译器显然有不同的意见,我想了解一下
1.为什么会这样?
1.我错过了什么?
1.我如何才能达到我想要的行为?

prdp8dxp

prdp8dxp1#

问题是我做事的顺序。
首先设置member-properties,然后再设置DataSource,这样就得到了预期的行为。即使是匿名类型。
剩下的问题是:为什么没有记录?给出的示例还首先设置DataSource,然后设置member-properties。但是在这个例子中,所有的属性都是字符串,所以这可能会使行为倾向于“它会以某种方式工作”。

wbgh16ku

wbgh16ku2#

如果你有一个接口

public interface IMyInterface
{
    string Display { get; set; }
    int Value { get; set; }
}

字符串
然后分配

cmb_MyBox.DataSource = <some collection of `IMyInterface`>;
cmb_MyBox.DisplayMember = "Display";
cmb_MyBox.ValueMember = "Value";


然后,

  • SelectedValue的类型为int
  • SelectedItem的类型为IMyInterface

相关问题