views:

147

answers:

2

(Using VS 2010 Beta 2 - .Net 4.0 B2 Rel)

I have a class, MyTable, derived from BindingList where S is a struct. S is made up of several other structs, for example:

public class MyTable<S>:BindingList<S> where S: struct
{
    ...
}

public struct MyStruct
{
    public MyReal r1;
    public MyReal r2;

    public MyReal R1 {get{...} set{...}}
    public MyReal R2 {get{...} set{...}}

    ...
}

public struct MyReal
{
    private Double d;

    private void InitFromString(string) {this.d = ...;}

    public MyReal(Double d) { this.d = d;}
    public MyReal(string val) { this.d = default(Double);  InitFromString(val);}

    public override string ToString() { return this.real.ToString();}
    public static explicit operator MyReal(string s) { return new MyReal(s);}
    public static implicit operator String(MyReal r) { return r.ToString();}
    ...
}

OK, I use the MyTable as a binding source for a DataGridView. I can load the data grid easily using InitFromString on individual fields in MyStruct.

The problem comes when I try to edit a value in a cell of the DataGridView. Going to the first row, first column, I change the value of the existing number. It gives an exception blizzard, the first line of which says:

System.FormatException: Invalid cast from 'System.String' to 'MyReal'

I've looked at the casting discussions and reference books but don't see any obvious problems.

Any ideas?

A: 

I (almost) fixed this problem by handling the CellParsing event, e.g.

private void dataGridView1_CellParsing(object sender, DataGridViewCellParsingEventArgs e)
{
    ... // (checking goes here)
    e.Value = new MyReal(e.Value.ToString());
    e.ParsingApplied = true;
}

e.Value is being set correctly but the DataGridView still shows the old value. How does the new value get placed in the BindingList?

Do I need an explicit method call to force the new value into the BindingList and, if so, where?

Max Yaffe
A: 

I tried your method of handling CellParsing, and it worked. Although I did it a little differently, handling any types:

    private void dataGridView1_CellParsing(object sender, DataGridViewCellParsingEventArgs e)
    {
        e.Value = Activator.CreateInstance(e.DesiredType, new object[] { e.Value });
        e.ParsingApplied = true;
    }
Jonathon Reinhart