Is there a way to highlight all the modified rows on a DataGrid? Since the grid is bound to a System.Data.DataTable
I figured I might be able to bind the colour of each row to it's RowState (example below), but that doesn't seem to work.
Any ideas?
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>
INotifyPropertyChanged
is not the only interface that WPF binding can use for change notification, it's just the one we're most used to. As Bea Stollnitz writes, the ADODataView
implementsIBindingList
, which implements change notification by raisingListChanged
when the list or an item in it changes.This suggests a way to get what you want, though I haven't tried it to see how it works. You can derive a class from
DataView
that listens to theDataTable.RowChanged
event and raisesListChanged
if the row is in the view and itsRowState
changed.You won't be able to instantiate this new
DataView
in XAML without using any code-behind or implementing a view model, since if you just bind to theDataTable
it will create a normalDataView
. But you can fix that, too: subclassDataTable
and overrideGetDefaultView
to make it return an instance of your newDataView
, and then subclassDataSet
and overrideTables
to make it return an instance of your newDataTable
. (None of these classes appear to be sealed, thank goodness.)Edit
Of course it's not as simple as that. The list that
DataView
exposes is a collection ofDataRowView
objects.DataRowView
implementsINotifyPropertyChanged
. I think that WPF uses theIBindingList
interface onDataView
for collection-changed notification and listens toPropertyChanged
onDataRowView
, though honestly I'd need to dig quite a bit more to be sure.DataRowView
only raisesPropertyChanged
when the value of a column in its row changes. I can't see any way to inject change-notification for other properties into that without subclassingDataRowView
, and while that's possible in principle, I can't see a straightforward way of subclassingDataView
to create these newDataRowView
objects.I know this thread is old, but since this issue wasn't fixed in .Net 4, I figured I'd post my workaround. It's a bit clunky (not elegant), but at least it uses data triggers and works.
This works and, best of all, you don't need to do an Items.Refresh every time you modify a row. With that said, if anyone has a better (more elegant) way to accomplish this, then please post.
Update
After you have posted also your xaml, it's obvious that the problem is not to be found in the xaml. I have shortly looked at msdn for the DataTable-class and I can not see a mechanism that let WPF detect changes of the
RowState
-property. Therefore, direct binding to this property will not give you reliable results.It seems that you have to wrap your data items. I recommend to make a ViewModel for the items and add a property that says if the row has changed with change notification (
INotifyPropertyChanged
or DP) and bind to this property. Surely there will be also other alternatives, but IMO creating a VM per item is in most cases the best solution.