【问题标题】:DataGridViews, DataBinding and non validating cell valuesDataGridView、数据绑定和非验证单元格值
【发布时间】:2010-05-11 19:02:47
【问题描述】:

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

class Foo
{
    public string Name { get; set; }
    public int Age { get; set; }
    public int height{ get; set; }
    ...
}

我有一个DataGridView.DataSource 绑定到具有 N 列的 BindingList<Foo>,每列绑定到每个属性。

我需要:

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

有什么简单的方法吗?

【问题讨论】:

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

标签: c# winforms data-binding datagridview


【解决方案1】:

我昨天在日期列上遇到了同样的问题。

我发现了 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 保存在 DataSet 中。在空字符串的情况下,它只会保存 DBNull。

【讨论】:

    【解决方案2】:

    我不能全部回答,但我可以回答红色背景。

    您首先需要做的当然是在活动期间处理DataGridView.CellValidating 并将e.Cancel 设置为true。

    如果您想要整个红色背景而不是红色感叹号(这是默认行为),您需要创建 DataGridTextBox 的继承类并覆盖 DataGridViewCell.PaintErrorIcon,这将允许您将单元格绘制为红色有红色感叹号。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多