C# WpfToolkit数据网格:高亮显示修改的行

C# WpfToolkit数据网格:高亮显示修改的行,c#,wpf,wpfdatagrid,wpftoolkit,C#,Wpf,Wpfdatagrid,Wpftoolkit,有没有办法突出显示DataGrid上所有修改的行?由于网格绑定到一个System.Data.DataTable上,我想我可能能够将每一行的颜色绑定到它的行状态(下面的示例),但这似乎不起作用 有什么想法吗 xmlns:data=“clr命名空间:System.data;assembly=System.data” 更新 在您也发布了xaml之后,很明显在xaml中找不到问题。我很快就查看了DataTable类的msdn,但没有看到一种机制可以让WPF检测到RowState-属性的更改。因此,

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

有什么想法吗

xmlns:data=“clr命名空间:System.data;assembly=System.data”



更新
在您也发布了xaml之后,很明显在xaml中找不到问题。我很快就查看了DataTable类的msdn,但没有看到一种机制可以让WPF检测到
RowState
-属性的更改。因此,直接绑定到此属性将无法提供可靠的结果。

似乎您必须包装数据项。我建议为项目创建一个ViewModel,并添加一个属性,说明行是否已随更改通知而更改(
INotifyPropertyChanged
或DP),并绑定到此属性。当然也会有其他替代方案,但IMO在大多数情况下为每个项目创建VM是最好的解决方案。

INotifyPropertyChanged
并不是WPF绑定可以用于更改通知的唯一接口,它正是我们最习惯使用的接口。如前所述,ADO
DataView
实现了
IBindingList
,当列表或其中的一个项目发生更改时,它通过引发
ListChanged
来实现更改通知

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

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

编辑

当然不是那么简单。
DataView
公开的列表是
DataRowView
对象的集合<代码>数据行视图实现了
INotifyPropertyChanged
。我认为WPF使用
DataView
上的
IBindingList
接口来发送集合更改通知,并侦听
DataRowView
上的
PropertyChanged
,不过老实说,我还需要进一步挖掘才能确定


DataRowView
仅在行中某列的值更改时引发
PropertyChanged
。如果不将
DataRowView
子类化,我看不到为其他属性注入更改通知的任何方法,虽然原则上这是可能的,但我看不到一种简单的方法,可以将
DataView
子类化来创建这些新的
DataRowView
对象。

我知道这个线程很旧,但是由于这个问题在.NET4中没有解决,我想我应该发布我的解决方法。它有点笨重(不优雅),但至少它使用了数据触发器并能正常工作

  • 向DataTable中添加一个伪ModifiedDate列(或者,如果不关心日期,只需添加一个伪列来指示rowstate)
  • 在XAML中添加引用ModifiedDate列和所需格式的DataTrigger
  • 在XAML中添加一个引用RowState的DataTrigger(这将只处理添加和未更改,因此不需要担心一个事件)
  • 向ADO.Net数据集中添加RowChanged事件,该事件填充ModifiedDate列中的内容(应与第一个DataTrigger相对应)
  • 在将数据推送到数据库的已保存事件中,在末尾(其中RowState=unchanged)清空伪ModifiedDate列(重要提示:确保选中RowState以验证在保存过程中没有发生错误)

  • 这是有效的,最重要的是,你不需要做一个项目。每次修改一行时都要刷新。也就是说,如果有人有更好(更优雅)的方法来完成这项工作,那么请发布。

    这对你有用吗?我看不出它与我的有什么不同。顺便说一句,我已经更新了这个问题。
    <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>
    
    <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>