#c# #.net #winforms #datagridview
#c# #.net #winforms #datagridview
Вопрос:
Я хочу проверить ячейку Winforms datagridview с помощью CellValidating. Если значение не было задано пользователем правильно, я устанавливаю ErrorText и использую e.Cancel
, чтобы курсор оставался в ячейке. Теперь проблема в том, что символ ошибки (и текст ошибки) не отображаются (в ячейке). Когда я удаляю e.Отмена, ячейка теряет фокус и отображается символ ошибки. Как я могу добиться того, чтобы ячейка оставалась в режиме редактирования, и символ ошибки тоже отображался?
if (...)
{
this.datagridviewX.Rows[e.RowIndex].Cells[e.ColumnIndex].ErrorText = "Errortext";
e.Cancel = true;
}
else
{
this.datagridviewX.Rows[e.RowIndex].Cells[e.ColumnIndex].ErrorText = "";
}
Комментарии:
1. Как я уже сказал в своем ответе — то, что вы описываете, не является готовым поведением, поэтому вы, должно быть, делаете что-то необычное. Не могли бы вы предоставить какой-нибудь код?
Ответ №1:
Поведение, которое вы видите, на самом деле связано с проблемой рисования, а не с тем, что значок ошибки не отображается. Происходит то, что при установке текста ошибки ячейки отображается значок, но текстовое поле ячейки в режиме редактирования закрашивается поверх значка, поэтому значок не отображается пользователю!
У вас есть два варианта для исправления этого — один из них — просто использовать текст ошибки строки, поэтому вместо:
this.datagridviewX.Rows[e.RowIndex].Cells[e.ColumnIndex].ErrorText = "Errortext";
e.Cancel = true;
У вас есть:
this.datagridviewX.Rows[e.RowIndex].ErrorText = "Errortext";
e.Cancel = true;
Другой вариант — изменить заполнение ячейки в ячейке (переместив элемент управления редактированием) и закрасить значок.
Я действительно нашел этот метод для решения проблемы здесь и воспроизвел их код ниже (на C # и не VB.Net ).
Сначала у вас есть событие проверки ячейки, в котором вы добавляете некоторый код для изменения заполнения ячейки:
void dataGridView1_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
{
if (string.IsNullOrEmpty(e.FormattedValue.ToString()))
{
DataGridViewCell cell = dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex];
cell.ErrorText =
"Company Name must not be empty";
if (cell.Tag == null)
{
cell.Tag = cell.Style.Padding;
cell.Style.Padding = new Padding(0, 0, 18, 0);
}
e.Cancel = true;
}
else
{
dataGridView1.Rows[e.RowIndex].ErrorText = string.Empty;
}
}
Это позволяет видеть значок, а не элемент управления редактированием, за исключением того, что значок тоже переместился! Поэтому нам также нужно нарисовать новый значок.
void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
if (dataGridView1.IsCurrentCellDirty)
{
if (!string.IsNullOrEmpty(e.ErrorText))
{
GraphicsContainer container = e.Graphics.BeginContainer();
e.Graphics.TranslateTransform(18,0);
e.Paint(this.ClientRectangle, DataGridViewPaintParts.ErrorIcon);
e.Graphics.EndContainer(container);
e.Handled = true;
}
}
}
Затем, когда вы завершаете редактирование ячейки, вам необходимо сбросить заполнение:
void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
if (!string.IsNullOrEmpty(dataGridView1[e.ColumnIndex, e.RowIndex].ErrorText))
{
DataGridViewCell cell = dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex];
cell.ErrorText = string.Empty;
cell.Style.Padding = (Padding)cell.Tag;
cell.Tag = null;
}
}
В сообщении, в котором я обнаружил это, игнорируется наведение курсора мыши на новый нарисованный значок — вот примерный код, который решает эту проблему, у меня нет времени, чтобы заставить его действительно работать, поэтому есть некоторые небольшие ошибки, которые, как я думал, можно исправить — я исправлю это, если у меня будет минута позже.
Я установил DataGridView.Покажите celltooltips = true и введите логическую ошибку, чтобы отслеживать, есть ли у нас ошибка редактирования. Затем я обрабатываю событие наведения курсора мыши:
void dataGridView1_MouseHover(object sender, EventArgs e)
{
if (inError)
{
Point pos = this.PointToClient(Cursor.Position);
if (r.Contains(pos.X - 20, pos.Y - 5))
{
t.Show("There was an error", dataGridView1.EditingControl, 3000);
}
}
}
t в этом коде представляет собой элемент управления всплывающей подсказкой на уровне формы, а r — прямоугольник.
Я заполняю r, как показано ниже, в обработчике рисования ячеек:
void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
if (dataGridView1.IsCurrentCellDirty)
{
if (!string.IsNullOrEmpty(e.ErrorText))
{
GraphicsContainer container = e.Graphics.BeginContainer();
r = dataGridView1.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, true);
e.Graphics.TranslateTransform(18, 0);
e.Paint(this.ClientRectangle, DataGridViewPaintParts.ErrorIcon);
e.Graphics.EndContainer(container);
e.Handled = true;
}
}
}
Меня не устраивают значения минус 20 и минус 5 в точке положения — это то, что я бы исправил, если бы у меня было немного больше времени.
Комментарии:
1. Я попробовал именно это с dataGridView1.Rows[e. RowIndex]. Ячейки[e. ColumnIndex].ErrorText = …
2. @Kottan предоставьте некоторый код (вероятно, лучший для всей формы, если не слишком большой), и мы можем посмотреть.
3. @Kottan — хорошо, теперь я тебя понял. В вашем вопросе вообще не было ясно, что вы устанавливаете ошибку в ячейке, а не в строке. Предоставление кода всегда полезно.
4. Это работает, если я использую только dataGridView1.Rows[e. RowIndex].Текст ошибки. Значок ошибки отображается в заголовке строки (не в ячейке).
5. Привет, у меня есть пользовательский редактор, размещенный в ячейке, и значок уведомления об ошибке не отображается в ячейке, он отображается в виде белой области, но при наведении курсора мыши на эту область отображается всплывающая подсказка. Однако при использовании стандартных datagridviewcolumns отображаются как значок уведомления об ошибке, так и всплывающая подсказка, так что не так? Я использую ApplyCellStyleToEditingControl для применения стиля ячейки к редактору, чтобы применить то же заполнение.