什么发生DataGridViewComboBoxColumn时的DisplayMember设置? [英] What happen to DataGridViewComboBoxColumn when DisplayMember is set?

查看:409
本文介绍了什么发生DataGridViewComboBoxColumn时的DisplayMember设置?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我有一个 DataGridViewComboBoxColumn 充满绑定值,如果我设置的<一个href="http://msdn.microsoft.com/en-us/library/system.windows.forms.datagridviewcomboboxcolumn.displaymember.aspx"相对=nofollow> 的DisplayMember 的财产,我得到的 DataError 事件提出了一个出现FormatException

的DataGridViewComboBoxCell值无效

DataGridViewComboBoxCell value is not valid

如果的DisplayMember 未设置,因此该视图显示的结果的ToString(),所有按预期工作。

If DisplayMember is not set, and so the view is showing the result of .ToString(), all work as expected.

下面是一个完整的例子:

Here is a complete example:

public partial class Form1 : Form
{
    public Form1() { InitializeComponent(); }

    private void Form1_Load(object sender, EventArgs e)
    {
        var categories = new[] { CustomerCategory.Cat1, CustomerCategory.Cat2, CustomerCategory.Cat3 };
        this.dataGridView1.AutoGenerateColumns = false;
        this.dataGridView1.DataError += new DataGridViewDataErrorEventHandler(dataGridView1_DataError);
        this.dataGridView1.CellParsing += new DataGridViewCellParsingEventHandler(dataGridView1_CellParsing);
        this.dataGridView1.Columns.Add(new DataGridViewComboBoxColumn()
        {
            DataSource = categories,
            HeaderText = "Category",
            DataPropertyName = "Category",
            DisplayMember = "Name" // if we omit this line, there is not DataError event raised
        });

        this.dataGridView1.DataSource = new[] 
        { 
              new Customer() { Category = CustomerCategory.Cat1 } 
            , new Customer() { Category = CustomerCategory.Cat2 } 
            , new Customer() { Category = CustomerCategory.Cat3 } 
        }.ToList();
    }

    void dataGridView1_DataError(object sender, DataGridViewDataErrorEventArgs e)
    {
        var value = this.dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value;
        var type = value != null ? value.GetType() : null;
        string message = "Error"
            + Environment.NewLine + " - Column : " + e.ColumnIndex
            + Environment.NewLine + " - Line  : " + e.RowIndex
            + Environment.NewLine + " - Value : " + Convert.ToString(value) + " (" + type + ")"
            + Environment.NewLine + " - Exception : " + e.Exception.Message;
        Debug.Fail(message);
    }

    void dataGridView1_CellParsing(object sender, DataGridViewCellParsingEventArgs e)
    {
        //http://stackoverflow.com/questions/631126/how-to-bound-a-datagridviewcomboboxcolumn-to-a-object
        if (this.dataGridView1.CurrentCell.OwningColumn is DataGridViewComboBoxColumn)
        {
            var editingControl = (DataGridViewComboBoxEditingControl)this.dataGridView1.EditingControl;
            e.Value = editingControl.SelectedItem;
            e.ParsingApplied = true;
        }
    }
}

型号:

public class CustomerCategory
{
    public static readonly CustomerCategory Cat1 = new CustomerCategory { Name = "Cat1" };
    public static readonly CustomerCategory Cat2 = new CustomerCategory { Name = "Cat2" };
    public static readonly CustomerCategory Cat3 = new CustomerCategory { Name = "Cat3" };

    public string Name { get; set; }
    public override string ToString() { return this.Name; }
}
public class Customer { public CustomerCategory Category { get; set; } }

我怎么可以指定自己的的DisplayMember 无需这恼人的 DataError 引发的事件?
该问题仅出现 DataGridViewComboBoxColumn 出现,不是一个普通的 组合框

How can I specify my own DisplayMember without having this annoying DataError event raised?
The problem appears only with DataGridViewComboBoxColumn, not with a regular ComboBox.

编辑:经过几次测试,我可以说:

Edit : After a few tests, I can say that:

[DisplayMember + Not ValueMember] = FAIL
[Not DisplayMember + ValueMember] = FAIL
[DisplayMember + ValueMember] = WIN

所以我的问题可能会被改写为:是否有解释precisely什么工作,什么都不会的任何文件;以及如何的DisplayMember + ValueMember 连接在一起喜欢它似乎是?

So my question could be rephrased as : Is there any documentation that explain precisely what will work and what won't; and how the DisplayMember + ValueMember are linked together like it seems to be?

重新编辑:

这是有趣的参考:与DataGridViewComboBoxColumn 问题一>

An interesting reference: Problems with the DataGridViewComboBoxColumn

不过,DataGridViewComboBoxColumn不会像这样工作,   虽然它会显示的ToString值,如果不设置   的DisplayMember,内部的东西出了问题时,它会尝试一下   向上的SelectedItem,你必须设置的DisplayMember到公共   类的财产。更糟糕的是,默认的行为,如果你不这样做   设置ValueMember属性是返回的DisplayMember,有   没有办法得到实际的项目本身。唯一的解决办法是添加   属性类返回本身和属性设置为   该ValueMember。当然,如果你的产品不是你能   改变(如框架类之一),你必须cludge   在一起的容器对象持有引用您的项目。

However, the DataGridViewComboBoxColumn doesn't work like this, although it will display the ToString value if you don't set the DisplayMember, something internally goes wrong when it tries to look up the SelectedItem, you have to set DisplayMember to a public property of your class. Even worse, the default behaviour if you don't set the ValueMember property is to return the DisplayMember, there's no way of getting actual item itself. The only work around is to add a property to your class that returns itself and set that property to the ValueMember. Of course, if your item isn't something you are able to change (such as one of the framework classes) you'll have to cludge together a container object that holds a reference to your item.

时有人有任何的信息在内部的东西出了问题部分?

Is somebody have any information about the something internally goes wrong part?

推荐答案

以下逻辑可以帮助您解决问题。

Following logic may help you to resolve your issue.

我觉得问题出在code线的顺序。分配显示成员属性后分配数据源可能导致错误。

I think problem is in the order of code line. Assigning datasource after assign display member property may causes the error.

更改此行;

this.dataGridView1.Columns.Add(new DataGridViewComboBoxColumn()
{
    DataSource = categories,
    HeaderText = "Category",
    DataPropertyName = "Category",
    DisplayMember = "Category" // if we omit this line, there is not DataError event raised
});

DataGridViewComboBoxColumn col = new DataGridViewComboBoxColumn();
col.HeaderText = "Category";
col.DataSource = categories;
col.DisplayMember = "Category";
col.DataPropertyName = "Category";
this.dataGridView1.Columns.Add(col);

数据源必须的DisplayMember和ValueMember前分配。

The datasource must be assigned before DisplayMember and ValueMember.

这篇关于什么发生DataGridViewComboBoxColumn时的DisplayMember设置?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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