InvalidCastException в DataGridView - PullRequest
       20

InvalidCastException в DataGridView

3 голосов
/ 24 марта 2010

(Использование VS 2010 Beta 2 - .Net 4.0 B2 Rel)

У меня есть класс MyTable, производный от BindingList, где S - это структура. S состоит из нескольких других структур, например:

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();}
    ...
}

ОК, я использую MyTable в качестве источника привязки для DataGridView. Я могу легко загрузить сетку данных, используя InitFromString для отдельных полей в MyStruct.

Проблема возникает, когда я пытаюсь редактировать значение в ячейке DataGridView. Переходя к первому ряду, первому столбцу, я меняю значение существующего числа. Это дает исключение метель, первая строка которой гласит:

System.FormatException: недопустимое приведение из «System.String» к «MyReal»

Я смотрел на кастинговые обсуждения и справочники, но не вижу очевидных проблем.

Есть идеи?

Ответы [ 3 ]

3 голосов
/ 07 июня 2010

Я попробовал ваш метод обработки CellParsing, и он сработал. Хотя я сделал это немного по-другому, обрабатывая любые типы:

    private void dataGridView1_CellParsing(object sender, DataGridViewCellParsingEventArgs e)
    {
        e.Value = Activator.CreateInstance(e.DesiredType, new object[] { e.Value });
        e.ParsingApplied = true;
    }
0 голосов
/ 01 июля 2016

Мои ячейки сетки заполнены объектами типа GridValueGroup, и у них есть свойство ObjValue, отображаемое переопределением ToString. При изменении строки в ячейке сетки событие CellParsing обрабатывается:

  1. заполнение ячейки-значения и
  2. изменив e.Value (который изначально имеет тип string, тогда как DesiredType равен GridValueGroup), чтобы он стал желаемым типом.

Таким образом, я избегаю создания нового объекта, потому что в ячейке уже есть этот объект.

Также сохраняет введенное значение в источнике данных. Пока не известно, блокирует ли он другие события (CellValueChanged иногда должен обрабатываться после анализа значения).

     private void grid_CellParsing(object sender, DataGridViewCellParsingEventArgs e) {
        string val = e.Value.ToString();

        DataGridViewCell cell = this.dgvGroup1[e.ColumnIndex, e.RowIndex];

        if (e.DesiredType == typeof(GridValueGroup))
        {
            ((GridValueGroup)cell.Value).ObjValue = val;
            e.Value = ((GridValueGroup)cell.Value);
        }
        e.ParsingApplied = true;

    }
0 голосов
/ 26 марта 2010

Я (почти) решил эту проблему, обработав событие CellParsing, например,

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

e.Value устанавливается правильно, но DataGridView по-прежнему показывает старое значение. Как новое значение помещается в BindingList?

Нужен ли явный вызов метода для принудительного ввода нового значения в BindingList и, если да, где?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...