2014-04-02 18 views
2

我有DataGrid,它绑定到DataTable,因为我不知道编译时的列数量。在绑定到DataTable时更改DataGrid上的空值外观

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); 
    } 
} 
+0

我只是猜测在这里...我们可以继承DataTable并使用这个新的DataTable类型进行绑定吗? – Savaratkar

+0

@theinsaneone我不明白它可以如何帮助 –

+0

哦sry ...下面的答案是最好的办法...我为这个解决方案做得太过分了:P我的坏... – Savaratkar

回答

1

您可以订阅AutoGeneratingColumn-Event并将绑定替换为一个,其中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; 
     } 
    } 
+0

这是个好主意,谢谢。我创建了'MyDataTable:DataTable',并根据你的方法修改了'OnAutoGeneratingColumn'方法。 –

+1

但我有一个问题:为什么要克隆绑定对象? –

+1

啊,对。在这种情况下,这不是必需的。如果绑定是通过BindingOperations.GetBinding()获得的,它会在尝试更改绑定的值时引发异常。由于此处的绑定仅设置为CLR属性,因此您不需要克隆它。 – user3411327

2

试图改变DataTable中的空值,如下图所示:

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

     } 
    } 
} 
+0

谢谢,这是一种方法这样做,但我试图找到一个解决方案,而无需更改DataTable,如果可能的话。 –

+0

您可以在网格单元格中执行相同的值并替换 –

+0

我想留在MVVM模式中,而不是使用一些手动编辑 –

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无能为力这里。

+0

谢谢,这是一种方法,但我试图找到一个解决方案而不更改数据表如果可能的话。 –

0

也许你可以创建一个ViewModel类继承DataTable或只是保留该类的参考DataTable类。该ViewModel类是您绑定到DataGrid的ItemSource。然后ViewModel应该知道它应该或不应该将哪些数据转换(null s为“ - ”)并返回到DataGrid。这样DataTable保持不变。

相关问题