views:

264

answers:

1

I'm trying to bind a table of structures to a DataGridView. Loading and viewing the table is working fine but I can't edit a value and get it stored back into the table. Here's what I'm doing.

I have a "primitive" data type, Real defined by

public struct MyReal:IMyPrimative
{
    public Double m_Real;
    //...
    public MyReal(String val)
    {
        m_Real = default(Double);
        Init(val); 
    }
    //...
}

It gets used in a structure:

public struct MyReal_Record : IMyRecord
{
    public MyReal Freq { get; set;}
    MyReal_Record(String[] vals)
    {
        Init(vals);
    }
}

And the structure is used to define a table using a generic Binding List

public class MyTable<S> : BindingList<S> where S: struct, IMyRecord
{
    public Type typeofS;
    public MyTable() 
    {
        typeofS = typeof(S);
        // ... 
    }

This table is used as a binding source for a grid, dynamically.

    private void miLoadFile_Click(object sender, EventArgs e)
    {
        MyModel.Table<Real_Record> RTable = new MyModel.Table<Real_Record>();
        //... Table initialized here

        //set up grid with virtual mode
        dataGridView1.DataSource = RTable;
    }

All of this works fine and I can create RTable, initialize it and display it in a grid. The grid allows editing and has events set for CellParsing and CellFormatting which look like:

    private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
    {
        if (e.DesiredType != typeof(String))
            return;
        e.Value = e.Value.ToString();
    }

    private void dataGridView1_CellParsing(object sender, DataGridViewCellParsingEventArgs e)
    {
        if (e.DesiredType != typeof(MyReal))
            return;
        e.Value = new MyReal(e.Value.ToString());
        e.ParsingApplied = true;
        this.dataGridView1.UpdateCellValue(e.ColumnIndex, e.RowIndex);
    }

When I edit a value in a cell, I can change the text. On leaving the cell, CellParsing fires and the event handler is called. Everything seems to be correct going into the CellParsing handler. e.DesiredType is MyReal. e.Value is a string with the new value. After the new MyReal is created from the string, e.Value is set correctly. RowIndex and ColumnIndex are correct. ReadOnly is set false.

However, when I leave the cell, the system restores the original value to the cell. I thought the UpdateCellValue would replace the value in the dataSource but I seem to be missing something.

What did I miss?

Thanks, Max

A: 

I found the answer on another forum (social.msdn.microsoft.com) thanks to Aland Li.

"When we bind a List of objects to a control, the objects in the list must be of reference type, not value type. In other words, Real_Record must defined as class.

If Real_Record is of value type, a copy of the Real_Record item in the list is transferred to the DataGridView to initialize the binding. When the Real value is modified, the copy of the Real_Record is changed, but the old item in the list is not modified."

If anyone knows how to get around this limitation, I'd love to hear it. Max

Max Yaffe