I have two WPF cell styles and I want to apply them based on a Converter. I'm my sample below I'm trying to change the background colour (in real application I'll change more than this, but that isn't the point of the question so I'm just simplifying).
<Style TargetType="{x:Type DataGridCell}" x:Key="WinCellStyle">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<Border x:Name="border"
Background="LightGreen"
BorderBrush="Transparent"
BorderThickness="1"
SnapsToDevicePixels="True">
<ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type DataGridCell}" x:Key="LossCellStyle">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<Border x:Name="border"
Background="LightSalmon"
BorderBrush="Transparent"
BorderThickness="1"
SnapsToDevicePixels="True">
<ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I then have a Converter:
public class AmountToCellStyleConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var valueAsDecimal = (decimal?) value;
if (valueAsDecimal > 0)
{
return Application.Current.FindResource("WinCellStyle") as Style;
}
return Application.Current.FindResource("LossCellStyle") as Style;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
How do I then call this in the cell style?
XAML:
<Window.Resources>
<converter:AmountToCellStyleConverter x:Key="AmountToCellStyleConverter"/>
</Window.Resources>
...
<DataGridTextColumn CellStyle="{Binding ??? What goes here}" Binding="{Binding Path=MarketBookSelection.TotalWagerStakeWin, StringFormat=N2}" Header="Stake Win" Width="Auto" />
Maybe the answer is this isn't possible and I need to go down some other route?
Binding don't work in CellStyle
of the DataGridColumn, therefore try create your Styles for TextBox
target type instead of DataGridCell
and write a DataGridTemplateColumn
like this:
<DataGrid.Resources>
<local:AmountToCellStyleConverter x:Key="StyleConverter" />
</DataGrid.Resources>
...
<DataGridTemplateColumn Width="1.5*"
Header="SimpleHeader"
IsReadOnly="False">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox Style="{Binding Path=NumberValue, Converter={StaticResource StyleConverter}}"
Text="{Binding Path=NumberValue}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
Or than to write a one value instead of two, in this case type of input value of Converter will be String
:
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox Style="{Binding Path=Text,
RelativeSource={RelativeSource Mode=Self},
Converter={StaticResource StyleConverter}}"
Text="{Binding Path=NumberValue}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
Styles for TextBox
are located in App.xaml
:
<Application.Resources>
<Style x:Key="WinCellStyle" TargetType="{x:Type TextBox}">
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBoxBase}">
<Border Background="LightGreen"
BorderThickness="1">
<ScrollViewer x:Name="PART_ContentHost"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="LossCellStyle" TargetType="{x:Type TextBox}">
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Border Background="LightSalmon"
BorderThickness="1">
<ScrollViewer x:Name="PART_ContentHost"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Application.Resources>
Converter
looks like this:
public class AmountToCellStyleConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var valueAsDecimal = (int)value;
if (valueAsDecimal > 0)
{
return Application.Current.FindResource("WinCellStyle") as Style;
}
return Application.Current.FindResource("LossCellStyle") as Style;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
Or you can do so: change the logic of the Converter to return True
or False
and in the CellStyle you could write this:
<DataGridTextColumn Header="SimpleHeader"
Width="1.5*"
Binding="{Binding Path=NumberValue}">
<DataGridTextColumn.CellStyle>
<Style TargetType="{x:Type DataGridCell}">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=NumberValue, Converter={StaticResource MyConverter}}" Value="True">
<Setter Property="Background" Value="Yellow" />
<Setter Property="BorderThickness" Value="1" />
</DataTrigger>
<DataTrigger Binding="{Binding Path=NumberValue, Converter={StaticResource MyConverter}}" Value="False">
<Setter Property="Background" Value="Red" />
<Setter Property="BorderThickness" Value="1" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGridTextColumn.CellStyle>
</DataGridTextColumn>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With