是什么导致ComboBox显示`System.Data.DataRowView`? [英] What causes ComboBox to show `System.Data.DataRowView`

查看:116
本文介绍了是什么导致ComboBox显示`System.Data.DataRowView`?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好的,所以这个有点奇怪。

OK, so this one is a bit odd.

我有一个非常简单的 DataTable

I have a pretty straightforward DataTable:

DataTable dt = new DataTable();
dt.Columns.Add("Display", typeof(string));
dt.Columns.Add("Value", typeof(string));
dt.Rows.Add("Equals", "==");
dt.Rows.Add("Is Less Than", "<");
dt.Rows.Add("Is Less Than Or Equal To", "<=");
dt.Rows.Add("Is Greater Than", ">");
dt.Rows.Add("Is Greater Than Or Equal To", ">=");

现在,如果我将此 DataTable 附加到一个全新的 ComboBox ,一切正常。

Now, if I attach this DataTable to a brand new ComboBox, everything works as it should.

 comboBox1.DataSource = dt;
 comboBox1.ValueMember = "Value";
 comboBox1.DisplayMember = "Display";

此控件显示等于小于,等等。

在我的表单中,我还有另一个 ComboBox ,根据它位于 TableLayoutPanel 中的哪一行给出动态名称,等等。
当我使用完全相同的代码,它为每个下拉选择显示 System.Data.DataRowView

In my form, however, I have another ComboBox that is dynamically created, given a dynamic name based on which row in a TableLayoutPanel it is in, etc. When I use the exact same code for it, it displays System.Data.DataRowView for each dropdown selection:

所以,而不是我一个接一个地浏览每一行代码并试图对其进行反向工程,告诉我会导致这种情况发生的原因吗?是否存在某种可预测且可重复的方式来导致这种行为?我已经尝试过以下所有操作来反向,但是没有任何作用:

So, rather than me going through each line of code one by one and trying to reverse engineer this, can someone tell me what would cause this to happen? Is there some predictable and repeatable way to cause this behaviour? I've tried all of the following to reverse it but nothing works:

dtecComboAction.DataSource = null;
dtecComboAction.DataBindings.Clear();
dtecComboAction.Items.Clear();
dtecComboAction.BindingContext = this.BindingContext;

我确定我在代码中的其他地方做了明显的事情,但我不知道

I'm sure I'm doing something obvious somewhere else in my code but I can't figure it out.

谢谢!

推荐答案

该问题由OwnerDrawn ComboBox(从ComboBox派生的自定义控件)的自定义图形确定。

The unexpected behaviour described in the question is determined by a custom drawing of the OwnerDrawn ComboBox (a Custom Control derived from ComboBox).

当ListControl的DataSource是复杂对象时-在这种情况下, DataTable.DefaultView (a DataView )-列表中的每个项目本身都是一个复杂的对象,即在这里 DataRowView

When the DataSource of a ListControl is a complex object - as in this case, a DataTable.DefaultView (a DataView) - each Item in the list is a complex object itself, a DataRowView here.

因此,在绘制OwnerDrawn ListControl的项目(覆盖 OnDrawItem 方法)时,该项目的文本(如控件的可见区域中所示),应使用ListControl的 GetItemText()方法。

For this reason, when drawing the Items of an OwnerDrawn ListControl (overriding the OnDrawItem method), the Item's text, as displayed in the Control's visible area, should be fetched using the ListControl's GetItemText() method.

此方法将获取项目的文本(如果定义了DataSource,则使用内部Datamanager;如果未定义,则使用TypeDescriptor),无论项目的类型是什么:

This method fetches an Item's text (using the internal Datamanager if a DataSource has beed defined, or the TypeDescriptor if not), no matter what the Item's Type is:


如果未指定DisplayMember属性,则
GetItemText(Object)返回的值是该项的ToString方法的值。
否则,该方法返回在DisplayMember属性中为项目
参数中指定的对象指定的成员
的字符串值。

If the DisplayMember property is not specified, the value returned by GetItemText(Object) is the value of the item's ToString method. Otherwise, the method returns the string value of the member specified in the DisplayMember property for the object specified in the item parameter.

。Net的ListControl.GetItemText()

在绘制项目文本以将其转换为字符串时,这是一个经典错误:< br>
如果Item的文本是一个简单的字符串,而不是一个复杂的对象,则可以使用。在这种情况下, [ComplexObject] .ToString() 返回对象的数据类型( System.Data.DataRowView ,在这种情况下)。

A classic mistake when drawing an Item's text it to convert to string the Item's object:
This can work if the Item's text is a simple string, not if it's a complex object. In this case [ComplexObject].ToString() returns the object's data type (System.Data.DataRowView, in this case).

protected override void OnDrawItem(DrawItemEventArgs e)
{
    // (...)
    e.DrawBackground();
    using (var brush = new SolidBrush(this.ForeColor)) {
        e.Graphics.DrawString(this.Items[e.Index].ToString()), this.Font, brush, e.Bounds);
    }
    // (...)
}

简化的示例代码,请勿使用:)

使用 GetItemText() DisplayMember 的属性值将作为字符串返回。由于 comboBox1.DisplayMember = Display; ,它将返回数据表的 Display 列的内容。

Using GetItemText(), the property value of DisplayMember is returned as a string. Since comboBox1.DisplayMember = "Display";, it will return the content of the DataTable's Display Column.

protected override void OnDrawItem(DrawItemEventArgs e)
{
    // (...)
    e.DrawBackground();
    using (var brush = new SolidBrush(this.ForeColor)) {
        e.Graphics.DrawString(this.GetItemText(this.Items[e.Index]), this.Font, brush, e.Bounds);
    }
    // (...)
}

这篇关于是什么导致ComboBox显示`System.Data.DataRowView`?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆