4

Я много искал для этой ошибки, о котором уже задал тот же вопрос, но он не решает мою проблему. Я получаюКак преобразовать DataGridViewComboBoxCell в DataGridViewTextBoxCell

Операции недопустима, так как это приводит к возвратному вызову функции SetCurrentCellAddressCore.

Сценарий У меня есть datagridview с TextboxColumn Я использую CellBeginEdit, чтобы преобразовать его в ComboBoxColumn, и после CellValidate я снова изменить ComboBoxColumn к TextboxColumn. Коды работают для всех. но получение указанной ошибки в точной строке e.RowIndex = 2 вызывает это исключение, но другие дозы строк не показывают ошибку. если я опустил эту ошибку и продолжаю, то значение e.RowIndex = 2 будет пустым, а значение других строк будет работать.

Вот код CellBeginEdit

if (e.ColumnIndex == 2 && e.RowIndex >= 0) 
    { 
    try 
    { 
     string s = Convert.ToString(_dgvCoarseAggegateTest[e.ColumnIndex, e.RowIndex].Value); 
     string s1 = Convert.ToString(_dgvCoarseAggegateTest[e.ColumnIndex, 0].Value); 
     DataGridViewComboBoxCell c = new DataGridViewComboBoxCell(); 

     string _SizeName = _cGetParrent._mGetParentCellValue(ref _dgvCoarseAggegateTest, e.RowIndex, 1);     
     _mFillSieveSizeGridCombo(_mGetMetalSizeID(_SizeName), ref c); // Here My Combo Will GetValues from SQL and it Returning Value 
     _dgvCoarseAggegateTest[e.ColumnIndex, e.RowIndex] = c; // Heres the error When e.RowIndex == 2 and if e.RowIndex != 2 then no error 
     _dgvCoarseAggegateTest[e.ColumnIndex, e.RowIndex].Value = s; 
     _dgvCoarseAggegateTest[e.ColumnIndex, 0].Value = s1; 
    } 
    catch (Exception ex) 
     { 
     MessageBox.Show(ex.Message); 
     } 
    } 

Как решить эту проблему.

UPDATE: не Нет строк там пользователь добавит новую строку и выберите значения, базовая вещь я хочу показать комбо и заполнить значения из базы данных, значения заполнения, зависит от состояния, поэтому каждый раз, когда новые значения приходят,

Примеры данных

testTable 
1  A 
2  B 
3  C 
4  D 
5  E 
6  F 
7  G 
8  H 
9  I 

в column1 я добавил один комбо со значениями от 1 до 9, в _mFillSieveSizeGridCombo Я передаю идентификатор к SQL Server 2008 и заполнения комбо с использованием Combo.Item.Add(x) метода.

+0

Странно. Я не могу воспроизвести. Сколько строк есть? Является ли значение в строке 2 отличным от других? Можете ли вы изменить его на тот, который работает? это происходит с мышью и с F2? (Я только догадываюсь, очевидно,). Что-нибудь особенное происходит с ячейкой c в mFillSieveSizeGridCombo из-за его rownumber? – TaW

+0

@taw нет строки там пользователь будет добавлять новую строку и выбирать значения, базовая вещь - я хочу показать комбо и значения заливки из базы данных, значения заполнения зависят от состояния, поэтому каждый раз, когда появятся новые значения, –

+0

Если вы прокомментируете вызов '_mFillSieveSizeGridCombo' элементов ячейки не заполняется. но происходит ли ошибка? – TaW

ответ

2

Внутри SetCurrentCellAddressCore() есть флаг, предотвращающий разрывание внутренних вызовов от DataGridView. Usaully событие было поднято с флагом = true и сброшено в конце события.

Чтобы обойти это, вы можете просто добавить обертку BeginInvoke() внутри события, чтобы запустить ваш процесс после события с помощью async.

EDIT

Проблему можно воспроизводить в режиме EditOnEnter и законодательница ячейки вне события в BeginInvoke результатах бессрочного цикла

private bool _suppressCellBeginEdit = false; 
private void dgv_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e) 
{ 
    var dgv = sender as DataGridView; 
    if (_suppressCellBeginEdit) 
     return; 

    if (e.ColumnIndex == 2 && e.RowIndex >= 0) 
    { 
     string s = Convert.ToString(dgv[e.ColumnIndex, e.RowIndex].Value); 
     string s1 = Convert.ToString(dgv[e.ColumnIndex, 0].Value); 
     DataGridViewComboBoxCell c = new DataGridViewComboBoxCell(); 

     c.Items.Add(string.Format("x{0}:y{1} {2}", e.RowIndex, e.ColumnIndex, 0)); 
     c.Items.Add(string.Format("x{0}:y{1} {2}", e.RowIndex, e.ColumnIndex, 1)); 
     c.Items.Add(string.Format("x{0}:y{1} {2}", e.RowIndex, e.ColumnIndex, 2)); 

     // special handling 
     if (e.RowIndex == e.ColumnIndex) 
     { 
      this.BeginInvoke(new Action(() => 
      { 
       _suppressCellBeginEdit = true; 
       this.Invoke(new Action(() => 
        { 
         c.Value = s; 
         dgv[e.ColumnIndex, e.RowIndex] = c; 
         dgv[e.ColumnIndex, 0].Value = s1; 
        })); 
       _suppressCellBeginEdit = false; 
      })); 
     } 
     else 
     { 
      c.Value = s; 
      dgv[e.ColumnIndex, e.RowIndex] = c; 
      dgv[e.ColumnIndex, 0].Value = s1; 
     } 
    } 
} 
+0

@Эрик не работает, используя ваш код переходит в бесконечный цикл, когда индекс строки == 2, и комбо не отображается в других строках, поскольку он уже работает. –

+0

@ImranAliKhan Есть ли какие-либо другие события dgv, которые вы обработали? Кажется, что это конфликт с чем-то еще – Eric

+0

@ImranAliKhan Это вызвано 'EditOnEnter', и вам нужно вручную переключить событие, см. Мое редактирование. – Eric

2

Как вы можете сказать от неприятностей вы реализуя это, DataGridView очень недоволен тем, что вы пытаетесь вытащить коврик. Он явно запрещает изменение объекта ячейки в критические моменты. В то время как он обрабатывает событие, это очень важный момент. Общая проблема с событиями, называемая re-entrancy. Проблема, с которой вы сталкиваетесь с подходом Эрика, показывает, что это действительно сложная проблема.

Так что вы делаете не хотите изменить тип ячейки или ссылку. Следите за мячом, что вы действительно хотите сделать, это изменить содержимое выпадающего списка. Это не проблема. Вернитесь к дизайнеру и измените свойство ColumnType этого столбца на DataGridViewComboBoxColumn.И используйте событие CellBeginEdit для динамического изменения коллекции элементов combobox. Простой пример:

private void _dgvCoarseAggegateTest_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e) { 
     var dgv = (DataGridView)sender; 
     if (e.ColumnIndex == 2) { 
      var cell = (DataGridViewComboBoxCell)dgv.Rows[e.RowIndex].Cells[e.ColumnIndex]; 
      cell.Items.Clear(); 
      // Run your dbase query here to fill cell.Items 
      //... 
      // We'll just fake it here for demo purposes: 
      cell.Items.Add(e.RowIndex.ToString()); 
      cell.Items.Add((e.RowIndex+1).ToString()); 
      cell.Items.Add((e.RowIndex+2).ToString()); 
     } 
    } 
+0

Это была моя первая мысль, но исходный код отлично работает здесь, а также в OP, за исключением одной ячейки в одной строке. Разве он не всегда придумывал эту ошибку? – TaW

+0

Я не пробовал исходный код, но исключение, однако, является абсолютно нормальным для * своего рода вещей, которые он пытается сделать. Это зависит от того, как ячейка помещается в режим редактирования, есть несколько способов. –

+0

Я могу сделать это с помощью F2 или с помощью мыши без проблем, кроме смешного feelig ;-) – TaW

1

Вот обходной путь: В CellBeginEdit событие сначала проверьте, чтобы увидеть, если ColumnTypeDataGridViewComboBoxCell является. Если это не так, мы cancel события, вызовите функцию, которая изменяет тип столбца, а затем вызвать событие еще раз:

void switchCellType(object sender, DataGridViewCellCancelEventArgs e) 
{ 
    DataGridViewComboBoxCell c = new DataGridViewComboBoxCell(); 
    // prepare the cell: 
    //.. 
    // fill the drop down items.. 
    c.Items.Add("1"); // use 
    c.Items.Add("2"); // your 
    c.Items.Add("3"); // code here! 
    DGV[e.ColumnIndex, e.RowIndex] = c; // change the cell 
    DGV_CellBeginEdit(sender, e);  // restart the edit with the original parms 
} 


private void DGV_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e) 
{ 

    DataGridViewCell cell = DGV[e.ColumnIndex, e.RowIndex]; 
    if (!(cell is DataGridViewComboBoxCell)) 
    { 
     e.Cancel = true; 
     switchCellType(sender, e); 
     return; 
    } 
    //.. 

Теперь ваш код может продолжаться, очевидно, без изменения клеток. Возможно, вы хотите передать в текстовое значение, чтобы установить, как хорошо ..

Примечание, что вы должны убедиться, что CellEndEdit событие не возвращается изменение раньше времени !! Может быть, флаг, может быть, в Tag поможет. Если вы хотите, я могу взглянуть на ваш код CellEndEdit, если он есть.

Смежные вопросы