Есть ли способ выделить все измененные строки в 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>
<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
-property. Поэтому прямая привязка к этому свойству не даст вам надежных результатов.
Кажется, что вам нужно обернуть элементы данных. Я рекомендую сделать ViewModel для элементов и добавить свойство, которое говорит, изменила ли строка с уведомлением об изменении (INotifyPropertyChanged
или DP) и привязана к этому свойству. Разумеется, будут и другие альтернативы, но IMO, создающая VM для каждого элемента, в большинстве случаев является лучшим решением.
Я знаю, что эта ветка устарела, но поскольку эта проблема не была исправлена в .Net 4, я решил, что опубликую свое обходное решение. Это немного неуклюжий (не элегантный), но по крайней мере он использует триггеры данных и работает.
Это работает и, самое главное, вам не нужно делать Items.Refresh каждый раз, когда вы изменяете строку. С учетом сказанного, если у кого-то есть лучший (более элегантный) способ сделать это, тогда, пожалуйста, напишите.
INotifyPropertyChanged
не является единственным интерфейсом, который может использовать привязка WPF для уведомления об изменении, это просто тот, к которому мы больше всего привыкли. Поскольку Bea Stollnitz пишет, ADO DataView
реализует IBindingList
, который реализует уведомление об изменении, поднимая ListChanged
, когда список или элемент в он изменяется.
Это предлагает способ получить то, что вы хотите, хотя я не пробовал его видеть, как это работает. Вы можете получить класс из DataView
, который прослушивает событие DataTable.RowChanged
и поднимает ListChanged
, если строка находится в представлении и его RowState
изменен.
Вы не сможете создать экземпляр нового DataView
в XAML без использования кода или реализации модели представления, так как если вы просто привяжетесь к DataTable
, он создаст нормальный DataView
. Но вы также можете исправить это: subclass DataTable
и переопределить GetDefaultView
, чтобы он возвращал экземпляр вашего нового DataView
, а затем подкласс DataSet
и переопределял Tables
, чтобы вернуть экземпляр вашего нового DataTable
. (Ни один из этих классов, кажется, не запечатан, слава богу.)
Edit
Конечно, это не так просто. Список, который DataView
предоставляет, представляет собой набор объектов DataRowView
. DataRowView
реализует INotifyPropertyChanged
. Я думаю, что WPF использует интерфейс IBindingList
на DataView
для уведомления об изменении коллекции и прослушивает PropertyChanged
на DataRowView
, хотя, честно говоря, мне нужно было бы копать еще немного, чтобы быть уверенным.
DataRowView
вызывает только PropertyChanged
, когда изменяется значение столбца в его строке. Я не вижу никакого способа вносить уведомление об изменении для других свойств в него без подкласса DataRowView
, и, хотя это возможно в принципе, я не вижу прямого способа подкласса DataView
для создания этих новых DataRowView
объекты.