Winforms:验证数据网格视图中的单元格的问题 [英] Winforms: Problems validating a cell in a datagridview

查看:16
本文介绍了Winforms:验证数据网格视图中的单元格的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to validate a Winforms datagridview cell with CellValidating. If a value was not set correctly by the user I set ErrorText and use e.Cancel, so that the cursor remains in the cell. The problem is now, that the error-symbol (and the error text) is not displayed (in the cell). When I delete e.Cancel the cell looses the focus and error-symbol is displayed. How can I achieve that the cell remains in edit mode and the error-symbol is displayed too?

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

推荐答案

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

The behaviour you are seeing is actually due to a painting issue and not due to the error icon not being shown. What is happening is that when you set the cell's error text the icon is displayed but the text box of the cell in edit mode is painted over the icon, hence no icon shown to the user!

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

You have two options for fixing this - one is to simply use the row's error text so instead of:

this.datagridviewX.Rows[e.RowIndex].Cells[e.ColumnIndex].ErrorText = "Errortext";  
e.Cancel = true;  

你有:

this.datagridviewX.Rows[e.RowIndex].ErrorText = "Errortext";
e.Cancel = true;

另一个选项是更改单元格的单元格填充(移动编辑控件)并在其中绘制图标.

The other option is to change the cell padding of the cell (moving the editing control) and painting the icon in.

我实际上找到了解决问题的技术此处 并在下面复制了他们的代码(使用 C# 而不是 VB.Net).

I actually found this technique for solving the problem here and reproduced their code below (in C# and not VB.Net).

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

First you have your cell validating event where you add some code to change the cell padding:

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

这样就可以在编辑控件移动的情况下看到图标,但图标也移动了!所以我们还需要绘制一个新的图标.

That allows the icon to be seen not the editing control has moved, except the icon has moved too! So we also need to paint a new icon.

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

然后当您结束对单元格的编辑时,您需要重置填充:

Then when you end editing on the cell you need to reset the padding:

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

我发现这个帖子忽略了将鼠标设置为新绘制的图标 - 这里有一些粗略的代码来解决这个问题,我没有时间让它真正工作,所以有一些轻微的胡说八道认为会修复 - 如果一分钟后我会整理它.

The post where I found this neglects to set the mouse over for the new painted icon - Here is some rough code that addresses that, I don't have time to get it really working so there are some slight fudges that thought would fix - I'll tidy that up if I get a minute later.

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

I set DataGridView.ShowCellToolTips = true and introduce a boolean inError to track if we currently have an editing error. I then handle the MouseHover event:

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 是一个矩形.

The t in that code is a form level ToolTip control, and r is a rectangle.

我在单元格绘制处理程序中按如下方式填充 r:

I populate r as below in the cell painting handler:

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 不满意 - 如果我有更多时间,这就是我要解决的问题.

I'm not happy about the minus 20 and minus 5 on the position point - that is what I'd fix up if I had a bit more time.

这篇关于Winforms:验证数据网格视图中的单元格的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆