2014-04-02 21 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保持不變。

相關問題