【问题标题】:WPFToolkit DataGrid: Highlight modified rowsWPFToolkit DataGrid:突出显示修改的行
【发布时间】:2011-06-24 06:59:50
【问题描述】:

有没有办法突出显示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>

【问题讨论】:

    标签: c# wpf datagrid wpftoolkit


    【解决方案1】:
    <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-property 更改的机制。因此,直接绑定到这个属性不会给你可靠的结果。
    看来您必须包装数据项。我建议为项目创建一个 ViewModel 并添加一个属性,说明该行是否已通过更改通知(INotifyPropertyChanged 或 DP)发生更改并绑定到此属性。当然还有其他选择,但在大多数情况下,IMO 为每个项目创建一个 VM 是最好的解决方案。

    【讨论】:

    • 这对你有用吗?我看不出它和我的有什么不同。顺便说一句,我已经更新了问题。
    【解决方案2】:

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

    1. 向您的 DataTable 添加一个虚拟的 ModifiedDate 列(或者如果您不关心日期,只需添加一个虚拟列来指示行状态)。
    2. 在 XAML 中添加引用 ModifiedDate 列和所需格式的 DataTrigger。
    3. 在 XAML 中添加一个引用 RowState 的 DataTrigger(这只会处理添加和未更改的内容,因此需要担心的事件更少)。
    4. 向您的 ADO.Net 数据集添加一个 RowChanged 事件,该事件会填充您的 ModifiedDate 列中的某些内容(应该与您的第一个 DataTrigger 对应)。
    5. 在将数据推送到数据库的已保存事件中,将最后的虚拟 ModifiedDate 列清空(其中 RowState=unchanged(重要提示:请务必检查 rowstate 以确认在保存期间没有发生错误。

    这很有效,而且最重要的是,您无需在每次修改行时都执行 Items.Refresh。话虽如此,如果有人有更好(更优雅)的方式来实现这一点,那么请发帖。

    【讨论】:

      【解决方案3】:

      INotifyPropertyChanged 不是 WPF 绑定可以用于更改通知的唯一接口,它只是我们最常用的接口。与Bea Stollnitz writes 一样,ADO DataView 实现了IBindingList,它通过在列表或其中的项目发生更改时引发ListChanged 来实现更改通知。

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

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

      编辑

      当然没那么简单。 DataView 公开的列表是 DataRowView 对象的集合。 DataRowView 实现 INotifyPropertyChanged。我认为 WPF 使用DataView 上的IBindingList 接口进行集合更改通知,并在DataRowView 上收听PropertyChanged,但老实说,我需要进一步挖掘才能确定。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-12-20
        • 2011-01-27
        • 2023-03-19
        • 2011-10-01
        • 2023-03-29
        • 2013-06-11
        • 1970-01-01
        • 2012-07-10
        相关资源
        最近更新 更多