2011-02-09 73 views
2

是否有突出顯示DataGrid上所有修改行的方法?由於網格綁定到System.Data.DataTable我想我可能能夠將每行的顏色綁定到它的RowState(下面的示例),但這似乎不起作用。WpfToolkit DataGrid:突出顯示修改後的行

任何想法?

xmlns:data="clr-namespace:System.Data;assembly=System.Data"

<Style x:Key="DataGridRowStyle" TargetType="{x:Type toolkit:DataGridRow}"> 
    <Style.Triggers> 
     <Trigger Property="IsSelected" Value="true"> 
      <Setter Property="Background" Value="Blue" /> 
     </Trigger> 
     <DataTrigger Binding="{Binding RowState}" Value="{x:Static data:DataRowState.Modified}"> 
      <Setter Property="Background" Value="LightYellow" /> 
     </DataTrigger> 
    </Style.Triggers> 
</Style> 

回答

4
<DataGrid.RowStyle> 
    <Style TargetType="DataGridRow"> 
    <Style.Triggers> 
     <DataTrigger Binding="{Binding RowState}" Value="{x:Static data:DataRowState.Modified}"> 
      <Setter Property="Background" Value="LightYellow" />    
     </DataTrigger> 
    </Style.Triggers> 
    </Style> 
</DataGrid.RowStyle> 

更新
你也貼出你的XAML後,很明顯,這個問題是不是在XAML中找到。我很快就看到了DataTable類的msdn,我看不到一種讓WPF檢測到RowState屬性更改的機制。因此,直接綁定到這個屬性將不會給你可靠的結果。
看來你必須包裝你的數據項。我建議爲這些項目創建一個ViewModel,並添加一個屬性,指出該行是否隨更改通知(INotifyPropertyChanged或DP)發生更改並綁定到此屬性。當然也會有其他的選擇,但是IMO爲每個項目創建一個虛擬機在大多數情況下是最好的解決方案。

+0

這是否適合你?我看不到它與我的不同。我更新了這個問題btw。 – 2011-02-09 17:13:00

+1

@Phil:我已經更新了我的答案。 – HCL 2011-02-10 09:30:33

1

INotifyPropertyChanged不是WPF綁定可用於更改通知的唯一接口,它只是我們最習慣的接口。如Bea Stollnitz writes所示,ADO DataView實現IBindingList,該列表或列表中的項目發生更改時,通過提高ListChanged來實施更改通知。

這提示了一種獲得你想要的東西的方法,雖然我沒有試過看它是如何工作的。如果該行在視圖中並且其RowState已更改,則可以從DataView中派生出一個類,用於偵聽DataTable.RowChanged事件,並提升ListChanged

你將不能夠實例化XAML這個新DataView不使用任何代碼隱藏或實現視圖模型,因爲如果你只是綁定到DataTable它會創建一個正常的DataView。但是,您也可以修復該問題:子類DataTable並覆蓋GetDefaultView以使其返回新的DataView的實例,然後子類DataSet並覆蓋Tables以使其返回新的DataTable的實例。 (這些類中沒有出現被密封,謝天謝地。)

編輯

當然這不是那麼簡單。 DataView公開的列表是DataRowView對象的集合。 DataRowView執行INotifyPropertyChanged。我認爲WPF使用DataView上的IBindingList接口進行收集更改通知,並在DataRowView上收聽PropertyChanged,但說實話,我需要深入挖掘更多信息。

DataRowView僅在其行中的列值發生變化時才引發PropertyChanged。我看不出有什麼辦法可以將其他屬性的更改通知注入到DataRowView的子類中,雖然原則上這是可能的,但我無法看到直接創建DataView以創建這些新對象的方法。

2

我知道這個線程是舊的,但由於這個問題沒有在.Net 4中修復,我想我會發布我的解決方法。這有點笨重(不夠優雅),但至少它使用數據觸發器和工作。

  1. 爲您的DataTable添加一個dummy ModifiedDate列(或者如果您不關心日期,只需添加一個虛擬列來指示rowstate)。
  2. 在XAML中添加一個引用ModifiedDate列和所需格式的DataTrigger。
  3. 在引用RowState的XAML中添加一個DataTrigger(這將只處理添加並保持不變,所以這是一個不必擔心的事件)。
  4. 將RowChanged事件添加到您的ADO.Net數據集中,該數據集填充ModifiedDate列中的某些內容(應該與您的第一個DataTrigger相對應)。
  5. 在你保存的情況下,在年底將數據推送到你的數據庫,空出你的虛擬ModifiedDate列(其中的RowState =不變(要點:一定要檢查RowState的驗證過程中節省發生任何錯誤

這是有效的,最重要的是,每次修改行時都不需要執行Items.Refresh。如果有人有更好(更優雅)的方法來完成此操作,請發帖。