Winforms:validationdatagridview中的单元格的问题

我想用CellValidatingvalidationWinforms datagridview单元格。 如果用户未正确设置值,我设置ErrorText并使用e.Cancel ,以便光标保留在单元格中。 现在的问题是, 错误符号 (和错误文本 )没有显示(在单元格中)。 当我删除e.Cancel时,单元格会丢失焦点并显示错误符号。 如何实现单元格保持编辑模式并显示错误符号?

 if (...) { this.datagridviewX.Rows[e.RowIndex].Cells[e.ColumnIndex].ErrorText = "Errortext"; e.Cancel = true; } else { this.datagridviewX.Rows[e.RowIndex].Cells[e.ColumnIndex].ErrorText = ""; } 

您看到的行为实际上是由于绘画问题而不是由于未显示错误图标。 发生的事情是,当您设置单元格的错误文本时,会显示图标,但编辑模式下单元格的文本框会显示在图标上,因此不会向用户显示图标!

你有两种方法可以解决这个问题 – 一种是简单地使用行的错误文本,而不是:

 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中)。

首先,您有单元validation事件,您可以在其中添加一些代码来更改单元格填充:

 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; } } 

我发现这个post忽略了将鼠标设置为新绘制的图标 – 这里有一些粗略的代码可以解决这个问题,我没有时间让它真正起作用所以有一些想要解决的轻微捏造 – 我如果我在一分钟后得到它,我会整理一下。

我设置DataGridView.ShowCellToolTips = true并引入一个布尔值inError来跟踪我们当前是否有编辑错误。 然后我处理MouseHover事件:

 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是表单级别的ToolTip控件,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感到不满 – 如果我有更多的时间,那就是我要解决的问题。