首先感谢 Adam Robinson,我确信您的回答是正确的,但这并不是我想听到的。我以不同的方式解决了我的问题,我认为它可能对其他人有用,所以我在这里发布。
我所做的是我创建了一个新类,在我的例子中,我将它命名为 ListObject,它有一个属性 DataRow(稍后您将看到它也适用于其他类型,我只是使用它,因为这是我真正想要的作为我的项目值属性)。它还覆盖了方法:
- 字符串 ToString()
- bool Equals(object obj)
- int GetHashCode() -- 在我的情况下不需要,但是 Visual Studio
警告你它应该被覆盖。
我的想法是我可以用我自己的类的对象填充 ComboBox.Items 集合,显示一个自定义字符串(如果我没有像这样解决它,我关于堆栈溢出的下一个问题可能是关于在阅读时自定义 DisplayMembers来自 DataRow 的项目)并仅比较一个类的项目(在我的情况下为 DataRow)。
所以这是代码,它工作得很好(至少对于我想用它做的)。
public class ListObject
{
public DataRow element;
public String DisplayObject = null;
public ListObject(DataRow dr)
{
element = dr;
}
public ListObject(DataRow dr, String dspObject)
{
element = dr;
DisplayObject = dspObject;
}
public override String ToString()
{
if (DisplayObject == null) throw new Exception("DisplayObject property was not set.");
return element[DisplayObject].ToString();
}
public override bool Equals(object obj)
{
if (obj.GetType() == typeof(ListObject))
return Equals(((ListObject)obj).element, this.element);
else return base.Equals(obj);
}
public override int GetHashCode()
{
return base.GetHashCode();
}
}
在我的情况下它工作得很好,因为我可以用 foreach 语句填充 ComboBox:
dtUsers.ReadXml(Program.Settings.xmlInputUsers);
foreach(DataRow dr in dtUsers.Rows)
{
cmbUser.Items.Add(new ListObject(dr, "Name"));
}
当我得到我想要选择的 DataRow 时,我只是这样做:
cmbUser.SelectedItem = new ListObject(dlg.SelectedDataRow);
我不必担心 DisplayMember 等,因为只会比较 DataRow,并且您的显示参数仍然会在您填充 ComboBox.Items 集合时设置。此外,由于 toString 方法被覆盖,您可以真正自定义输出。
只有在 ComboBox.SelectedItem 属性 上的 msdn 文章中才可能创建此类,其中指出 SelectedItem 属性使用 IndexOf 方法工作。此方法使用 Equals 方法来确定相等性。