2010-09-02 64 views
2

使用WPF DataGrid我需要根據相關值更改DataGridCell的各種顯示和相關屬性 - 例如Foreground,FontStyle,IsEnabled等 - 單元格對象屬性。將單元格對象的屬性綁定到WPF DataGrid中的DataGridCell中

現在,這是很容易的代碼來執行,例如(使用ObservableDictionaries的觀察集合):

var b = new Binding("IsLocked") { Source = row[column], Converter = new BoolToFontStyleConverter() }; 
    cell.SetBinding(Control.FontStyleProperty, b); 

和工作正常,但我看不出如何做到這一點的XAML,因爲我找不到方法將路徑設置爲單元格對象的屬性。

一個XAML的嘗試是:

<Setter Property="FontStyle"> 
    <Setter.Value> 
     <MultiBinding Converter="{StaticResource IsLockedToFontStyleConverter}" Mode="OneWay" UpdateSourceTrigger="PropertyChanged"> 
       <Binding /> 
       <Binding RelativeSource="{x:Static RelativeSource.Self}"/> 
     </MultiBinding> 
    </Setter.Value> 
</Setter> 

但沒有結合到IsLocked財產

public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) 
{ 
    var row = (RowViewModel) values[0]; 
    var cell = (DataGridCell) values[1]; 
    if (cell != null && row != null) 
    { 
     var column = DataGridMethods.GetColumn(cell); 
     return row[column].IsLocked ? "Italic" : "Normal"; 
    } 

    return DependencyProperty.UnsetValue; 
} 

請注意,以前的版本返回行[山口] .IsLocked和使用DataTrigger設置FontStyle,但返回的對象不是數據綁定。

請注意,當然,應用程序不知道在設計時列是什麼。

最後DataTable對於我的需求來說效率太低了,但是我很想看看DataTables是如何完成的,如果有這樣的解決方案,這可能對別處有用(儘管我更喜歡使用集合)。

當然,這是一個常見問題,我是一個WPF noobie嘗試在我的項目中使用所有MVVM,但是這個問題阻礙了我使用WPF DataGrid。

回答

4

那麼這裏是我找到的最簡單的解決方案。 (事實上​​,在我發佈這個以及其他問題之前,我已經擁有了它,但是在這樣的解決方案中感到尷尬。由於在這裏沒有聽到任何其他信息,只是在其他人面臨同樣問題的情況下,我想我會分享它。)

在DataGridCell標記屬性中放置對單元對象的引用。我這樣做是用XAML和代碼轉換器內部結合的組合如下:

public class CellViewModelToTagConverter : IMultiValueConverter 
{ 
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) 
    { 
     var row = values[0] as RowViewModel; 
     var cell = values[1] as DataGridCell; 
     if (row != null && cell != null) 
     { 
      var column = DataGridMethods.GetColumn(cell); 
      // hack within hack!!! (using tag way is itself a hack?) 
      var b = new Binding("Self") {Source = row[column]}; 
      cell.SetBinding(FrameworkElement.TagProperty, b); 
      //... 
      //return row[column]; 
      return DependencyProperty.UnsetValue; 
     } 
     return DependencyProperty.UnsetValue; 
    } 

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) 
    { 
     throw new NotSupportedException(); 
    } 
} 

你可以告訴我怎麼想的這個解決方案由我的轉換器內的評論(我不得不向Cell對象添加一個Self屬性,並在構造函數中使Self = this)。

它仍然使我的Datagrid編碼完全是MVVM - 如果您接受我在轉換器內完成的操作與MVVM一致。無論如何,它的作品!

因此,通過這種方式,我可以查看和管理XAML中的所有內容,例如通過將XAML放置在相關列單元格中(即不通過DataGrid.CellStyle執行此操作)來控制僅在特定列上的綁定。

無論如何,使用的一個例子是

<Style.Triggers> 
     <DataTrigger Value="true" Binding="{Binding RelativeSource={RelativeSource Self}, Path=Tag.IsLocked}"> 
      <Setter Property="FontStyle" Value="Italic"/> 
      <Setter Property="IsEnabled" Value="False"/> 
     </DataTrigger> 
</Style.Triggers> 

在XAML水平它的結構簡單,IMHO優雅(特別是關於各種工具提示和彈出窗口用於我使細胞對象的屬性的大量使用)。不過,我相信有這樣做的更好方法,是嗎?

希望這一切都會消失,當我可以使用Net 4.0和動態對象,但對於這個項目我不能。

+0

感謝您的分享。這是非常醜陋的,但這也是迄今爲止我所見過的最簡單的解決方案... – David 2011-02-07 08:42:08

+0

我意識到這是一箇舊的帖子,但我發現我可以簡單地把'return row [column];'在if ...塊中,它工作。上面的代碼做了什麼不同(即創建綁定)? – 2013-02-13 14:51:23

+0

除了在轉換器中,綁定不會發生。如果您不在轉換器內進行綁定並返回行[column],然後更新引用的單元格,則它未綁定,並且您在DataGrid中看不到更新。雖然XAML更復雜,但我有一個更好的和非常好的解決方案。當我有時間時,我會在這裏添加它。 – Martino 2013-06-07 08:19:23

相關問題