如何在(WPF) DataGrid中清除单元格(使其获取NULL值)?

7
我们有一个绑定到可为空的 SQL 整数值的列。当用户尝试在 DataGrid 中“清除”单元格时,我们会得到验证错误:“...无法转换”。如何使其为空并将“null”值绑定到底层列?我已经搜索了这个问题2天了,但没有找到任何答案。我尝试编辑我的评论给你 HCL,但它从来没有保存过。我熟悉 IValueConverters。我编写了一个处理百分比的转换器(所以用户可以输入“50%”,然后转换为“0.5”)。我正在尝试做类似的事情,但当值返回为 Null 时(我编写了一个虚拟的 IValueConterter 来调试它),我只想将其保存到数据库中作为 Null。也许我只需要将它设置为 DBNullValue?对于我认为可能具有内置属性的东西来说,这似乎是很多工作。我尝试在列(DataGridBoundColumn)上使用 TargetNullValue 属性,并将其设置为 DBNull.Value,但它没有更改值(根据我的虚拟 IValueConverter,它仍然作为常规(字符串)NULL 进入)。我只想能够将 null 值保存到此(整数类型)列的数据库中。最新添加:好的点子 HCL,我有时忘记整个世界不是 ADO。我正在绑定到 SQL 表。问题中的列是允许 NULL 的 int。这些列是使用 AutoGeneratingColumn 创建的,因此它基本上只是“自动地”连接它们(某些样式,如右对齐,是在此方法中应用的,但不适用于此列)。采用这种方法是因为该应用程序基本上是一个“Access”替代品。我们的 CIO 要求我们从用户中删除 Access,所以这就是解决方案(创建我们自己的 MS Access)。无论如何,由于它可以打开任何表格(并创建表格、列等),因此它只是基于打开的表格“自动生成”列。虽然,由于有一些应用程序本身知道的列,例如 Discount_Pct,当遇到这些列之一时,它确实会做一些“特殊的事情”(例如分配我上面描述的 IValueConverter)。虽然,正如我所说... 对于这个特定的列,没有任何“特殊”的处理。它只是一个常规的 SQL 整数(可为空),是“自动生成”的。

我们能看到验证代码吗? - SQLMason
没有什么特别的。这是一个相当普通的网格。 - Shayne
3个回答

8

我刚找到了我一直在寻找的属性!

TargetNullValue(目标空值)

这篇文章解释了它: 这里

问题是,这些列使用“AutoGenerateColumns”生成(因为数据源...一个SQL表...是“动态的”)。 如果我能弄清楚如何获取表列(原始)类型,那么我已经知道如何查看它是否可为空,然后我可以为该列设置该值。(我仍然不明白为什么AutoGenerateColumns不会自动处理这个问题!!)


我知道如何获取类型...它作为“e.PropertyType”传递给AutoGenerateColumn处理程序。问题是,它并不是真正的“类型”...它不可为空,但数据库列却可为空。所以,我只能通过列名硬编码来解决这个问题。 :( - Shayne

5

在Shayne的自我答案的基础上,我发现DataGridBoundColumn对象上可用TargetNullValue属性。您可以使用此评论中描述的附加逻辑来进行条件判断。不幸的是,该帖子没有解释如何将其逻辑与DataGrid相关联,因此这是我的解决方案:

<DataGrid AutoGenerateColumns="True" AutoGeneratingColumn="m_grid_AutoGeneratingColumn"/>

并且...

public void m_grid_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
    // Make all columns nullable
    ((DataGridBoundColumn)e.Column).Binding.TargetNullValue = string.Empty;
}

我曾因这个问题非常沮丧,希望这可以帮助到其他人。


1
谢谢,不过我遇到的问题是我的DataGridTextColumn无法使用TargetNullValue - 当我尝试使用<DataGridTextColumn Width="52" Header="Carb" Binding="{Binding Carb}" TargetNullValue="" />时,VS会说它不在模式中。啊!没关系,我找到了解决方法,应该这样写:<DataGridTextColumn Width="52" Header="Carb" Binding="{Binding Carb,TargetNullValue='' }" />。 - Dronz

1
我决定在这个字段中采用IValueConverter方法。
以下是我编写的代码(它有效,但我仍然觉得一定有更简单的方法!lol):
    [ValueConversion(typeof(Int32), typeof(String))]
    public class IntDBNullConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (value == null)
                return "";
            else if (DBNull.Value.Equals(value))
                return "";
            else
                return value.ToString();
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            string str = value as string;
            if (String.IsNullOrEmpty(str))
                return DBNull.Value; // returns DBNull.Value 

            Int32 result = 0;

            Int32.TryParse(str, out result);

            return result;
        }
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接