DataGridView -значение не сохраняется, если выделение не потеряно из ячейки

#c# #datagridview #combobox

#.net #datagridview

Вопрос:

Я использую элемент управления DataGridView для чтения и записи XML-файла посредством сериализации XML.

У меня проблема, как описано ниже:

  1. Я читаю XML-файл и заполняю элементы управления DataGridView десериализованным объектом.
  2. Я обновляю все значения в DataGridView в ячейке.
  3. Я выбираю опцию сохранения файла как, не теряя фокуса на последней ячейке.

После этого значение конкретной ячейки не обновляется. Если я намеренно смещаю фокус (скажем, я нажимаю на другую ячейку в той же сетке), значение обновляется.

Кто-нибудь может предложить какое-либо решение для этого?

Ответ №1:

Лучший способ (хотя и быстрый и грязный) — присвоить значение CurrentCell Nothing .

Например, в методе сохранения выполните:

 dgvMyGrid.CurrentCell = Nothing
  

а затем продолжайте дальше.

Комментарии:

1. У меня такая же ситуация, и ваше решение сработало отлично. Мне все еще интересно, как это возможно.

Ответ №2:

Это потому, что отредактированное значение ячейки не фиксируется в источнике данных до тех пор, пока оно не будет проверено, что происходит, когда ячейка теряет фокус. Если вы хотите немедленно зафиксировать изменения, вы можете обработать событие CurrentCellDirtyStateChanged и вызвать метод CommitEdit в обработчике :

 void dataGridView1_CurrentCellDirtyStateChanged(object sender,
    EventArgs e)
{
    if (dataGridView1.IsCurrentCellDirty)
    {
        dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit);
    }
}
  

Комментарии:

1. чем это лучше, чем datagridview1.EndEdit()

2. Это не подходит, если есть проверка, потому что некоторые допустимые записи не могут быть введены без прохождения через недопустимое состояние. Например, вы не можете ввести 1.6e-19 в ячейку, для которой требуется двойное значение, потому что ошибка проверки появится, как только вы дойдете до 1.6e.

Ответ №3:

Если я правильно вас понимаю, ячейка находится в режиме редактирования, и вы пытаетесь программно остановить редактирование и передать значение в базовый источник данных?

Я использую несколько «грязный» подход для этого в одном из моих приложений:

 if (dataGridView1.CurrentCell.IsInEditMode)    
{    
    int y = dataGridView1.CurrentCellAddress.Y;    
    int x = dataGridView1.CurrentCellAddress.X;    
    if (y > 0)      
        dataGridView1.CurrentCell = dataGridView1.Rows[y - 1].Cells[x];    
    else    
        dataGridView1.CurrentCell = dataGridView1.Rows[y   1].Cells[x];    
    dataGridView1.CurrentCell = dataGridView1.Rows[y].Cells[x];    
}
  

Этот фрагмент кода сначала проверяет, находится ли текущая ячейка в режиме редактирования. Затем он программно изменяет текущую ячейку (либо на предыдущую строку, либо на следующую строку, если мы находимся в первой строке). После этого он восстанавливает текущее выделение ячейки.

Вы бы вызвали этот код в своем обработчике «Сохранить файл как».

Ответ №4:

У меня была такая же ситуация, и я даже использовал клавиши акселератора для кнопки сохранения для сохранения значений сетки. Когда я нажимаю на кнопку сохранения, фокус теряется из DGV, и, следовательно, значение ячейки фиксируется, но когда я использую клавиши акселератора, фокус не теряется из DGV, следовательно, значение ячейки не фиксируется.

После просмотра ответа Амита Кармакара из любопытства я попробовал этот ответ, и он сработал. Чтобы узнать больше деталей, я углубился в отладку DGV и обнаружил, что это действительно то же самое, что и commitedit, который каким-то образом не работает, если вы используете его при нажатии кнопки сохранения.

Когда мы устанавливаем для CurrentCell DGV значение null, прежде чем установить для него значение null, DGV сначала получает отредактированное значение и помещает его в значение ячейки, а затем устанавливает ссылку на CurrentCell в значение null. Здесь это не означает, что для базовой ячейки DGV устанавливается значение null. Следовательно, это отлично подходит для вышеуказанной проблемы.

Примечание: это решение может работать некорректно, если у вас есть события проверки для ячейки, и если пользователь вводит неверные данные, которые не пройдут проверку. В этом случае установка текущей ячейки в значение null также завершается неудачей, поскольку она не может перенести значение в ячейку.

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

Ответ №5:

ХОРОШО, это НЕКРАСИВО, но это работает, чтобы получить ОКОНЧАТЕЛЬНЫЕ ИЗМЕНЕНИЯ из сетки БЕЗ необходимости перехода в другую строку:

 With DataGridView1
    .DataSource = Nothing
    .DataSource = gridDataTable
    Dim changedFoo As DataTable = gridDataTable.GetChanges
End With
  

Однако мне по-прежнему больше всего нравится ответ Амита Кармакара.
Я добавил ‘dataGridView1.CurrentCell = Ничего’ к событию dataGridView1 LostFocus.

Ответ №6:

Вы можете получить значение ячейки, которая еще не зафиксирована, используя свойство EditedFormattedValue для текущей ячейки, как показано ниже

 dataGridView1.CurrentCell.EditedFormattedValue