将我自己的行添加到具有文本和组合值的DataGridView的异常

时间:2016-06-08 11:40:06

标签: c# winforms datagridview

我现在正用这个把头发拉出来。我无法弄清楚如何使用DataSource做到这一点所以我决定采用更加手动的方法。

我有一些XML:

<?xml version="1.0" standalone="yes"?>
<GenioCodes>
  <Code Layer="BI" Colour="1" />
  <Code Layer="BP" Colour="1" />
  <Code Layer="BS" Colour="1" />
  <Code Layer="C" Colour="1" />
  <Code Layer="CC" Colour="1" />
  <Code Layer="CR" Colour="1" />
</GenioCodes>

我有一个自定义单元格值:

public class ComboboxColorItem
{
    public string Name { get; set; }
    public ushort Index { get; set; }
    public Color Value { get; set; }

    public ComboboxColorItem(string Name, ushort Index, Color Value)
    {
        this.Name = Name;
        this.Index = Index;
        this.Value = Value;
    }
    public override string ToString()
    {
        return Name;
    }

    static public ComboboxColorItem Create(ushort iColourIndex)
    {
        OdCmColor oColour = new OdCmColor();

        oColour.setColorIndex(iColourIndex);

        CultureInfo cultureInfo = Thread.CurrentThread.CurrentCulture;
        TextInfo textInfo = cultureInfo.TextInfo;

        String strColour = textInfo.ToTitleCase(oColour.colorNameForDisplay());
        if (iColourIndex > 7)
            strColour = String.Format("Colour {0}", iColourIndex);
        ComboboxColorItem oColorItem = new ComboboxColorItem(
            strColour,
            iColourIndex,
            Color.FromArgb(oColour.red(), oColour.green(), oColour.blue()));

        oColour.Dispose();

        return oColorItem;
    }
}

我读取了XML文件并尝试将其添加到表中:

private void GENIO_Code_Editor_Load(object sender, EventArgs e)
{
    try
    {
        buttonDetect.Enabled = m_dbDatabase != null;

        cboColumn = new DataGridViewComboBoxColumn();
        cboColumn.Name = "Color";
        cboColumn.DataPropertyName = "ComboboxColorItem";
        cboColumn.DisplayMember = "Name";
        cboColumn.ValueMember = "Value";

        List<ushort> listColors = new List<ushort>();
        listColors.Add(1);
        listColors.Add(2);
        listColors.Add(3);
        listColors.Add(4);
        listColors.Add(5);
        listColors.Add(6);
        listColors.Add(7);
        listColors.Add(8);
        listColors.Add(9);
        listColors.Add(250);
        listColors.Add(251);
        listColors.Add(252);
        listColors.Add(253);
        listColors.Add(254);
        listColors.Add(255);

        foreach (ushort iColorIndex in listColors)
            cboColumn.Items.Add(ComboboxColorItem.Create(iColorIndex));

        //this.DataGridView1.Columns.Add(cboColumn);

        dataGridView.Columns.Add("Layer", "Layer");
        dataGridView.Columns.Add(cboColumn);

        if (textBoxXML.Text != "")
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(textBoxXML.Text);
            XmlNodeList listCodes = doc.SelectNodes("GenioCodes/Code");

            foreach(XmlNode oCode in listCodes)
            {
                int iRow = dataGridView.Rows.Add();
                dataGridView.Rows[iRow].Cells["Layer"].Value = oCode.Attributes["Layer"].Value;

                ComboboxColorItem ocbItem = ComboboxColorItem.Create(Convert.ToUInt16(oCode.Attributes["Colour"].Value));
                dataGridView.Rows[iRow].Cells["Color"].Value = ocbItem;

                //dataGridView.Rows.Add(oCode.Attributes["Layer"].Value, 
                //                      ComboboxColorItem.Create(Convert.ToUInt16(oCode.Attributes["Colour"].Value)));
            }
            /*
            m_dataSet.ReadXml(textBoxXML.Text);
            dataGridView.DataSource = m_dataSet.Tables[0];
            */
        }
    }
    catch(Exception ex)
    {
        MessageBox.Show(ex.ToString());

    }
}

但它给了我一个噩梦。添加行时,我不断收到组合单元格的dataError异常。我尝试处理RowsAdded但我还无法访问该行的单元格。

异常的上下文是格式化|显示即可。但我已经有了处理程序。例如:

private void dataGridView_CellParsing(object sender, DataGridViewCellParsingEventArgs e)
{
    MessageBox.Show("Cell Parsing " + e.ColumnIndex.ToString());

    if (dataGridView.Columns[e.ColumnIndex].Name != "Color")
        return;

    foreach (ComboboxColorItem item in cboColumn.Items)
    {
        if (item.Name == (string)e.Value)
        {
            e.Value = item;
            e.ParsingApplied = true;
            break;
        }
    }

    if(!e.ParsingApplied)
    {
        ComboboxColorItem ocbItem = ComboboxColorItem.Create((ushort)e.Value);
        cboColumn.Items.Add(ocbItem);
        e.Value = ocbItem;
        e.ParsingApplied = true;
    }
}

但是在解析前会引发此错误。怎么办?

当我尝试在表中添加一行时会引发错误(请参阅加载事件)。

DataError的异常:

-       e   {System.Windows.Forms.DataGridViewDataErrorEventArgs}   System.Windows.Forms.DataGridViewDataErrorEventArgs
        Cancel  false   bool
        ColumnIndex 1   int
        Context Formatting | Display    System.Windows.Forms.DataGridViewDataErrorContexts
+       Exception   {"DataGridViewComboBoxCell value is not valid."}    System.Exception {System.ArgumentException}
        RowIndex    0   int
        ThrowException  false   bool
        cancel  false   bool
        columnIndex 1   int
        context Formatting | Display    System.Windows.Forms.DataGridViewDataErrorContexts
+       exception   {"DataGridViewComboBoxCell value is not valid."}    System.Exception {System.ArgumentException}
        rowIndex    0   int
        throwException  false   bool
+       Static members      

在格式化单元格之前,似乎会出现错误。但它确实继续并填充单元格。我不断得到错误。甚至在添加细胞后(例如,当形式刚刚重新粉刷时)。实际上,错误发生在CellFormatting / CellPainting之前。

更新:添加行时不会导致此问题。我可以调试跟踪所有行添加调用。当网格显示时必须在此之后。

更新:继续提供答案....谢谢!

我不得不更改此代码:

cboColumn.ValueMember = "Value";

为:

cboColumn.ValueMember = "Name";

然后我必须调整我的解析事件处理程序使用:

if(item.Name == (string)e.Value)

我尝试将ValueMember设置为并将e.Value转换为(Color),但它引发了异常。 IDE显示&#34; 255,0,0和#34;例如。所以我改为改为字符串属性。

然后我在答案中做了你的建议:

dataGridView.Columns.Add("Layer", "Layer");
dataGridView.Columns.Add(cboColumn);

if (textBoxXML.Text != "")
{
    XmlDocument doc = new XmlDocument();
    doc.Load(textBoxXML.Text);
    XmlNodeList listCodes = doc.SelectNodes("GenioCodes/Code");

    foreach(XmlNode oCode in listCodes)
    {
        int iRow = dataGridView.Rows.Add();

        dataGridView.Rows[iRow].Cells["Layer"].Value = oCode.Attributes["Layer"].Value;

        ushort iColourIndex = Convert.ToUInt16(oCode.Attributes["Colour"].Value);
        ComboboxColorItem ocbItem2 = null;
        foreach(ComboboxColorItem ocbItem in cboColumn.Items)
        {
            if (ocbItem.Index == iColourIndex)
            {
                ocbItem2 = ocbItem;
                break;
            }
        }
        if(ocbItem2 == null)
        {
            ocbItem2 = ComboboxColorItem.Create(iColourIndex);
            cboColumn.Items.Add(ocbItem2);
        }
        dataGridView.Rows[iRow].Cells["Color"].Value = ocbItem2;

    }
}

1 个答案:

答案 0 :(得分:1)

在这一行

ComboboxColorItem ocbItem = ComboboxColorItem.Create(Convert.ToUInt16(oCode.Attributes["Colour"].Value));
dataGridView.Rows[iRow].Cells["Color"].Value = ocbItem;

ocbItem是ComboboxColorItem的新实例,它不属于Items,而DataGridViewComboBoxCell也不接受它作为有效值。

可能的解决方法:

  1. Items集合中查找相应的项目并将其用作单元格值
    1. 覆盖Equals
    2. ComboboxColorItem