C# DataGridView、数据绑定和非验证单元格值

C# DataGridView、数据绑定和非验证单元格值,c#,winforms,data-binding,datagridview,C#,Winforms,Data Binding,Datagridview,让我们简化一下。假设我有一门课: class Foo { public string Name { get; set; } public int Age { get; set; } public int height{ get; set; } ... } 我有一个DataGridView.DataSource绑定到一个bindingslist上,有N列,每个列绑定到每个属性 我需要: 允许用户输入未验证的年龄、身高等(例如“aaa”) 使用非验证值(红色背景)

让我们简化一下。假设我有一门课:

class Foo
{
    public string Name { get; set; }
    public int Age { get; set; }
    public int height{ get; set; }
    ...
}
我有一个
DataGridView.DataSource
绑定到一个
bindingslist
上,有N列,每个列绑定到每个属性

我需要:

  • 允许用户输入未验证的年龄、身高等(例如“aaa”)
  • 使用非验证值(红色背景)为单元格着色
  • 在表单关闭之前保留显示的非验证值(我不希望在表单关闭之前丢失输入的值,因此用户可以在关闭表单之前随时更正坏单元格)
  • 保留为每个单元格输入的最后一个正确值和输入的非验证值
  • 关闭表单时,放弃非验证值并保留最后输入的正确值

有什么简单的方法可以做到这一点吗?

我不能回答所有问题,但我可以回答红色背景的问题

当然,您首先需要做的是在事件期间处理并将
e.Cancel
设置为true


如果您想要整个红色背景而不是红色感叹号(这是默认行为),则需要创建一个继承的类
DataGridTextBox
,并重写该类,以允许您将单元格绘制为红色,而不是红色感叹号。

我昨天遇到了与日期列相同的问题

我发现了CellFormatting和CellParsing事件,但BindingSource似乎忽略了它们。所以我就这样做了。我用过手机。标记属性。dgv在这里是DataGridView

  private void dgv_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
    {
        if (IsBirthdayColumn(e.ColumnIndex))
        {
            e.Value = dgv[e.ColumnIndex, e.RowIndex].Tag;
            if (e.Value is DateTime)
            {
                e.Value = ((DateTime)e.Value).ToShortDateString();
            }
            e.FormattingApplied = true;
        }
    }

    private void dgv_CellParsing(object sender, DataGridViewCellParsingEventArgs e)
    {
        DateTime date;
        if (IsBirthdayColumn(e.ColumnIndex))
        {
            if (e.Value != null && DateTime.TryParse(e.Value.ToString(), out date))
            {
                e.Value = date;
                dgv[e.ColumnIndex, e.RowIndex].Tag = e.Value;
            }
            else
            {
                dgv[e.ColumnIndex, e.RowIndex].Tag = e.Value;
                e.Value = DBNull.Value;
            }
            e.ParsingApplied = true;
        }
    }

   private void dgv_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
    {
        DateTime date;
        if (IsBirthdayColumn(e.ColumnIndex))
        {
            var cell = dgv[e.ColumnIndex, e.RowIndex];
            if (e.FormattedValue != null && !DateTime.TryParse(e.FormattedValue.ToString(), out date))
            {
                if (e.FormattedValue.ToString().Trim().Equals(""))
                {
                    cell.ErrorText = string.Empty;
                    return;
                }
                cell.ErrorText = "Invalid date format";
            }
            else
            {
                cell.ErrorText = string.Empty;
            }
        }
    }
此外,您还需要处理DataError事件

    private void dgv_DataError(object sender, DataGridViewDataErrorEventArgs e)
    {
        ......
        e.Cancel = false;
        ......
    }

现在你可以在日期栏写任何东西了。如果日期无效,它将显示u错误图标,并在数据集中保存DBNull。对于空字符串,它将只保存DBNull。

对于问题部分“放弃非验证值并保留最后输入的正确值”。如果有人更改了名称,则更改了年龄您希望保存名称更改吗?否。我只想保留正确的值,以保持数据库一致。