Reputation: 173
I have the following template setup
<LinearGradientBrush x:Key="BorderBrush" StartPoint="0,0" EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="White" Offset="0"/>
<GradientStop Color="White" Offset="1"/>
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
<LinearGradientBrush x:Key="PressedBorderBrush" StartPoint="0,0" EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="White" Offset="0"/>
<GradientStop Color="White" Offset="1"/>
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
<Style x:Key="GridViewColumnHeaderGripper" TargetType="Thumb">
<Setter Property="Width" Value="18"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Thumb}">
<Border Padding="{TemplateBinding Padding}" Background="Transparent">
<Rectangle HorizontalAlignment="Center" Width="1" Fill="{TemplateBinding Background}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="{x:Type GridViewColumnHeader}" TargetType="GridViewColumnHeader">
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Bottom"/>
<Setter Property="Foreground" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=HeaderForeground, Converter={StaticResource ColorToBrushConverter}}"/>
<Setter Property="FontWeight" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=HeaderFontWeight}" />
<Setter Property="Padding" Value="4"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="GridViewColumnHeader">
<Grid>
<Border Name="HeaderBorder" Padding="{TemplateBinding Padding}" BorderThickness="0,0,0,0" BorderBrush="{StaticResource BorderBrush}" Background="{StaticResource BackgroundBrush}">
<ContentPresenter Name="HeaderContent" Margin="0,0,0,0" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Border>
<Thumb x:Name="PART_HeaderGripper" HorizontalAlignment="Right" Margin="0,0,-9,0" Style="{StaticResource GridViewColumnHeaderGripper}" Cursor="ScrollSE"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="HeaderBorder" Property="Background" Value="{StaticResource HighlightBackgroundBrush}"/>
<Setter TargetName="HeaderBorder" Property="CornerRadius" Value="2"/>
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter TargetName="HeaderBorder" Property="Background" Value="{StaticResource PressedBorderBrush}"/>
<Setter TargetName="HeaderContent" Property="Margin" Value="0,0,0,0"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="Role" Value="Floating">
<Setter Property="Opacity" Value="0.7"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="GridViewColumnHeader">
<Canvas Name="PART_FloatingHeaderCanvas">
<Rectangle Fill="#60000000" Width="{TemplateBinding ActualWidth}" Height="{TemplateBinding ActualHeight}"/>
</Canvas>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="Role" Value="Padding">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="GridViewColumnHeader">
<Border Name="HeaderBorder" BorderThickness="0,0,0,0" BorderBrush="{StaticResource BorderBrush}" Background="{StaticResource BackgroundBrush}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
In my codebehind during the DataContextChanged event i am attempting to change the Header Column bakcground properties. Using the following logic I am able to change the BackgroundBrush and the BorderBrush
var backgroundBrush = FindResource("BackgroundBrush") as LinearGradientBrush;
if (backgroundBrush != null) {
if (backgroundBrush.GradientStops[0].Color != Color.FromArgb(255, 195, 193, 194)) {
backgroundBrush.GradientStops[0].Color = Color.FromArgb(255, 195, 193, 194);
backgroundBrush.GradientStops[1].Color = Color.FromArgb(255, 157, 157, 157);
}
}
However when I try to do something simular to adjust the HighlightBackgroundBrush
var highlightBrush = FindResource("HighlightBackgroundBrush") as LinearGradientBrush;
if (highlightBrush != null) {
if (highlightBrush.GradientStops[0].Color != Color.FromArgb(255, 195, 193, 194)) {
highlightBrush.GradientStops[0].Color = Color.FromArgb(255, 195, 193, 194);
highlightBrush.GradientStops[1].Color = Color.FromArgb(255, 157, 157, 157);
}
}
I get the following error: "Cannot set a property on object '#FFFFFFFF,0' because it is in a read-only state."
Does anyone know what I am doing wrong or what is the best way of achiving this.
Upvotes: 2
Views: 949
Reputation: 84657
When the IsMouseOver
trigger kicks in, Freeze()
is called on your LinearGradientBrush
, which in turn makes it unmodifiable (as pointed out by Stewbob). A frozen object cannot be made unfrozen so if you need to modify that particular resource, I see no other way than to clone it, remove it from the resources and then re-add it. This would also require you to use a DynamicResource
instead of a StaticResource
Trigger
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="HeaderBorder"
Property="Background"
Value="{DynamicResource HighlightBackgroundBrush}"/>
<!-- Additional setters.. -->
</Trigger>
Code..
var highlightBrush = FindResource("HighlightBackgroundBrush") as LinearGradientBrush;
if (highlightBrush != null)
{
if (highlightBrush.GradientStops[0].Color != Color.FromArgb(255, 195, 193, 194))
{
this.Resources.Remove("HighlightBackgroundBrush");
highlightBrush = highlightBrush.Clone();
highlightBrush.GradientStops[0].Color = Color.FromArgb(255, 195, 193, 194);
highlightBrush.GradientStops[1].Color = Color.FromArgb(255, 157, 157, 157);
this.Resources.Add("HighlightBackgroundBrush", highlightBrush);
}
}
Upvotes: 3
Reputation: 16899
Your GradientStopCollection has become Frozen. According to MSDN, when this happens you need to create a clone and modify that:
Dim hb0 As LinearGradientBrush = FindResource("BackgroundBrush")
If hb0.GradientStops.IsFrozen Then
Dim gs As GradientStopCollection = hb0.GradientStops.Clone
gs(0).Color = Color.FromArgb(255, 195, 193, 194)
gs(1).Color = Color.FromArgb(255, 157, 157, 157)
End If
Dim hb As LinearGradientBrush = FindResource("HighlightBackgroundBrush")
If hb.GradientStops.IsFrozen Then
Dim gs As GradientStopCollection = hb.GradientStops.Clone
gs(0).Color = Color.FromArgb(255, 195, 193, 194)
gs(1).Color = Color.FromArgb(255, 157, 157, 157)
End If
Upvotes: 2