How to change the row style in a WPF DataGrid control when changing the property of an element in this row

I have a DataGrid control in my WPF application that contains an object. There is a logical property of this object that can be changed by user actions. I need the line style to change when the property value changes.

I wrote a class that descends from StyleSelector :

 public class LiveModeSelector : StyleSelector { public Style LiveModeStyle { get; set; } public Style NormalStyle { get; set; } public override Style SelectStyle( object item, DependencyObject container ) { DataGridRow gridRow = container as DataGridRow; LPRCamera camera = item as LPRCamera; if ( camera != null && camera.IsInLiveMode ) { return LiveModeStyle; } return NormalStyle; } } 

The presented View Model class implements INotifyPropertyChanged , and it raises the PropertyChanged event when the corresponding property changes.

 // Note: The ModuleMonitor class implements INotifyPropertyChanged and raises the PropertyChanged // event in the SetAndNotify generic method. public class LPRCamera : ModuleMonitor, ICloneable { . . . public bool IsInLiveMode { get { return iIsInLiveMode; } private set { SetAndNotify( "IsInLiveMode", ref iIsInLiveMode, value ); } } private bool iIsInLiveMode; . . . /// </summary> public void StartLiveMode() { IsInLiveMode = true; . . . } public void StopLiveMode() { IsInLiveMode = false; . . . } } 

The value of the property changes when the user performs the required action, but the style does not change.

I set a breakpoint in the SelectStyle method, and I see that the breakpoint is hit when the control first loads, but it doesn't hit when the property value changes.

What am I missing?

+4
source share
2 answers

I found a way to do this that came from @Rachel's answer to my question. However, the details of the code are slightly different, and I want to show exactly what works.

The first step was to merge two different Styles into one for the DataGridRow class:

 <Style TargetType="DataGridRow" x:Key="CameraStyle"> <Setter Property="Foreground" Value="{DynamicResource TextForeground}" /> <Setter Property="Background" Value="{DynamicResource DataBackground}" /> <Style.Triggers> <DataTrigger Binding="{Binding Path=IsInLiveMode}" Value="True"> <Setter Property="Foreground" Value="Red" /> <Setter Property="Background" Value="Yellow" /> </DataTrigger> </Style.Triggers> </Style> 

The second step was to set the DataGrid control RowStyle to this new style:

 <DataGrid . . . RowStyle={StaticResource CameraStyle}"> . . . </DataGrid> 

It works. The foreground and background of the line changes when the user places the LPRCamera associated with this line in Live Mode and returns to normal when it is taken out of Live Mode, and this is what I am going to do.

Thanks @Rachel!

+4
source

I do not think StyleSelector listens for PropertyChange notifications, so it will not restart when the IsInLiveMode property IsInLiveMode .

Put your style in a DataTrigger based on IsInLiveMode instead, and it will be re-evaluated at any time when a notification of a property change is raised.

 <DataGrid.Resources> <Style TargetType="{x:Type DataGridRow}" x:Key="Style1"> <Setter Property="Background" Value="Red" /> </Style> <Style TargetType="{x:Type DataGridRow}" x:Key="Style2"> <Setter Property="Background" Value="Blue" /> </Style> </DataGrid.Resources> <DataGrid.Style> <Style TargetType="{x:Type DataGrid}"> <Setter Property="RowStyle" Value="{StaticResource Style1}" /> <Style.Triggers> <DataTrigger Binding="{Binding ElementName=MyDataGrid, Path=DataContext.IsInLiveMode}" Value="True"> <Setter Property="RowStyle" Value="{StaticResource Style2}" /> </DataTrigger> </Style.Triggers> </Style> </DataGrid.Style> 
+4
source

All Articles