WpfToolkit DataGrid:突出显示已修改的行

时间:2011-02-09 16:51:25

标签: c# wpf wpfdatagrid wpftoolkit

有没有办法突出显示DataGrid上的所有已修改行?由于网格绑定到System.Data.DataTable,我想我可以将每行的颜色绑定到它的RowState(下面的示例),但这似乎不起作用。

有什么想法吗?

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>

3 个答案:

答案 0 :(得分: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中找不到问题。我很快就看了msdn的DataTable类,我看不到让WPF检测到RowState - 属性变化的机制。因此,直接绑定此属性不会给您可靠的结果 看来你必须包装你的数据项。我建议为项目创建一个ViewModel,并添加一个属性,说明该行是否已通过更改通知(INotifyPropertyChanged或DP)更改并绑定到此属性。肯定会有其他替代方案,但IMO在每个项目上创建一个VM在大多数情况下是最佳解决方案。

答案 1 :(得分:2)

我知道这个帖子已经过时了,但由于这个问题在.Net 4中没有修复,我想我会发布我的解决方法。它有点笨重(不优雅),但至少它使用数据触发器和工作。

  1. 向DataTable添加一个伪ModifiedDate列(或者如果您不关心日期,只需添加一个虚拟列来指示rowstate)。
  2. 在XAML中添加DataTrigger,引用ModifiedDate列和您想要的格式。
  3. 在引用RowState的XAML中添加一个DataTrigger(这只会处理Adds并保持不变,所以要担心的事情要少一些)。
  4. 将一个RowChanged事件添加到ADO.Net数据集中,该数据集填充ModifiedDate列中的内容(应与您的第一个DataTrigger对应)。
  5. 在将数据推送到数据库的已保存事件中,在结尾处清空虚拟ModifiedDate列(其中RowState =未更改)(重要提示:请务必检查rowstate以确认在保存期间未发生错误。
  6. 这是有效的,最重要的是,每次修改行时都不需要执行Items.Refresh。话虽如此,如果有人有更好(更优雅)的方式来完成这个,那么请发帖。

答案 2 :(得分:1)

INotifyPropertyChanged不是WPF绑定可用于更改通知的唯一接口,它只是我们最常用的接口。作为Bea Stollnitz writes,ADO DataView实施IBindingList,当列表或其中的项目发生更改时,ListChanged会通过提升DataView来实施更改通知。

这表明了一种获得你想要的东西的方法,尽管我还没有尝试过它是如何工作的。您可以从DataTable.RowChanged派生一个听取ListChanged事件的类,如果该行在视图中并且其RowState已更改,则会引发DataView

如果不使用任何代码隐藏或实现视图模型,您将无法在XAML中实例化此新DataTable,因为如果您只是绑定到DataView,它将创建一个正常{ {1}}。但你也可以解决这个问题:子类DataTable并覆盖GetDefaultView以使其返回新DataView的实例,然后继承DataSet并覆盖Tables使其返回新DataTable的实例。 (这些类似乎都没有密封,谢天谢地。)

修改

当然不是那么简单。 DataView公开的列表是DataRowView个对象的集合。 DataRowView实施INotifyPropertyChanged。我认为WPF使用IBindingList上的DataView接口进行收集更改通知,并在PropertyChanged上收听DataRowView,但老实说,我需要挖掘更多可以肯定。

DataRowView仅在其行中的列值发生更改时才会引发PropertyChanged。我没有看到任何方法在没有子类化DataRowView的情况下将其他属性的更改通知注入其中,虽然原则上这是可能的,但是我看不到一种直接的方法来创建这些子类DataView新的DataRowView个对象。