我想使用 CellValidating 验证Winforms 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 = "";
}
答案 0 :(得分:11)
您看到的行为实际上是由于绘画问题,而不是由于未显示错误图标。发生的事情是,当你设置单元格的错误文本时,会显示图标,但是编辑模式下单元格的文本框被涂在图标上,因此没有向用户显示图标!
你有两种方法可以解决这个问题 - 一种是简单地使用行的错误文本,而不是:
this.datagridviewX.Rows[e.RowIndex].Cells[e.ColumnIndex].ErrorText = "Errortext";
e.Cancel = true;
你有:
this.datagridviewX.Rows[e.RowIndex].ErrorText = "Errortext";
e.Cancel = true;
另一个选项是更改单元格的单元格填充(移动编辑控件)并在其中绘制图标。
我实际上找到了解决问题here的技术并在下面复制了他们的代码(在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.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感到不满意 - 如果我有更多的时间,那就是我要解决的问题。