绑定到DataTable时,更改DataGrid上的空值外观

时间:2014-04-02 06:08:10

标签: c# wpf mvvm datagrid datatable

我有DataGrid,绑定到DataTable,因为我不知道编译时列的数量。

XAML

<Window.Resources>
    <wpfApplication1:MainWindowViewModel x:Key="ViewModel" />
</Window.Resources>

<Grid DataContext="{StaticResource ViewModel}">
    <DataGrid x:Name="MyDataGrid" 
              ItemsSource="{Binding Path=DataTable}" />
</Grid>

MainWindowViewModel.cs

class MainWindowViewModel : INotifyPropertyChanged
{
    private DataTable dt;
    public event PropertyChangedEventHandler PropertyChanged;

    public MainWindowViewModel()
    {
        DataTable table = new DataTable();
        table.Columns.Add("Foo", typeof(int));
        table.Columns.Add("Bar", typeof(string));
        table.Rows.Add(1, "first");
        table.Rows.Add(2, null);
        DataTable = table;
    }

    private void OnPropertyChanged(string s)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(s));
        }
    }

    public DataTable DataTable
    {
        get { return dt; }
        set
        {
            dt = value;
            OnPropertyChanged("DataTable");
        }
    }
}

结果是:

simple table

单元格中没有null值。 我的问题是:如何将null值的所有单元格更改为“ - ”而不更改来源DataTable

我无法在绑定中使用转换器,因为它会尝试转换所有DataTable,而不是值。 我对DataGridCell样式也没有好运,因为我不知道如何获取数据值并对其进行更改。

Edit

我的最终解决方案基于其中一个答案。我创建了MyDataGrid类并覆盖了OnAutoGeneratingColumn方法。

class MyDataGrid : DataGrid
{
    protected override void OnAutoGeneratingColumn(DataGridAutoGeneratingColumnEventArgs e)
    {
        var textColumn = e.Column as DataGridTextColumn;

        if (textColumn != null)
        {
            var binding = textColumn.Binding;
            binding.TargetNullValue = "-";
        }

        base.OnAutoGeneratingColumn(e);
    }
}

4 个答案:

答案 0 :(得分:2)

尝试更改数据表中的空值,如下所示:

if (dt != null)
{
    foreach (DataRow row in dt.Tables[0].Rows)
    {
        foreach (DataColumn col in dt.Tables[0].Columns)
        {
            string type = col.DataType.Name;

            if (row.IsNull(col))
            {
                if (type == "String") //for string values
                {
                    row.SetField(col, "-");
                }
                else // for integer
                {
                    row.SetField(col, 0);
                }
            }

        }
    }
}

答案 1 :(得分:2)

您可以尝试使用此功能:

private string SomeString = null;

...

table.Rows.Add(2, ReturnNullValue(SomeString, "---"));

private string ReturnNullValue(string Value, string NullValue) 
{
    if (String.IsNullOrEmpty(Value) == true)
    {
        return NullValue;
    }

    return Value;
}

或者您可以使用其他逻辑添加该属性:

private string _someString = "";

public string SomeString
{
    get
    {
        return _someString;
    }

    set
    {
        if (String.IsNullOrEmpty(value) == false)
        {
            _someString = value;
        }
        else
        {
            _someString = "---";
        }
    }
}

并像这样使用:

SomeString = "";
table.Rows.Add(2, SomeString);

我认为我们可以在不编辑DataTable的情况下完成,这不是简单快捷的解决方案,因为转换器,样式和TargetNullValue无能为力。

答案 2 :(得分:1)

您可以订阅AutoGeneratingColumn-Event并将Binding替换为一个,其中FallbackValue / TargetNullValue设置为您喜欢的。对于克隆,我使用了this

    private void OnAutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
    {
        DataGridTextColumn textColumn;
        if ((textColumn = e.Column as DataGridTextColumn) != null)
        {
            var binding = textColumn.Binding;
            var clone = binding.CloneBinding();
            clone.FallbackValue = "-----";
            clone.TargetNullValue = "-----";
            textColumn.Binding = clone;
        }
    }

答案 3 :(得分:0)

也许您可以创建一个继承ViewModel的{​​{1}}类,或者仅保留该DataTable类的引用。 DataTable类就是您绑定到ViewModel的ItemSource的类。然后,DataGrid应该知道它应该或不应该将哪些数据转换为ViewModel s到&#34; - &#34;)并返回null。这样DataGrid保持不变。