Изменить цвет заголовка ListView HigghlightBackground во время выполнения - PullRequest
2 голосов
/ 13 июля 2011

У меня есть следующие настройки шаблона

<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>

В моем коде во время события DataContextChanged я пытаюсь изменить свойства bakcground столбца заголовка. Используя следующую логику, я могу изменить BackgroundBrush и 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);
            }
        }

Однако, когда я пытаюсь сделать что-то симулированное для настройки 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);
            }
        }

Я получаю следующую ошибку: «Невозможно установить свойство для объекта '# FFFFFFFF, 0', поскольку он находится в состоянии только для чтения."

Кто-нибудь знает, что я делаю неправильно или как это лучше всего сделать?

Ответы [ 2 ]

3 голосов
/ 14 июля 2011

Когда срабатывает триггер IsMouseOver, на вашем LinearGradientBrush вызывается Freeze(), что, в свою очередь, делает его немодифицируемым (как указывает Stewbob ).Замороженный объект нельзя сделать незамороженным, поэтому, если вам нужно изменить этот конкретный ресурс, я не вижу другого способа, кроме как клонировать его, удалить его из ресурсов и затем повторно добавить его.Для этого также потребуется использовать DynamicResource вместо StaticResource

Триггер

<Trigger Property="IsMouseOver" Value="true">
    <Setter TargetName="HeaderBorder"
            Property="Background"
            Value="{DynamicResource HighlightBackgroundBrush}"/>
    <!-- Additional setters.. -->
</Trigger>

Код ..

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);
    }
}
2 голосов
/ 13 июля 2011

Ваша коллекция градиентов стала замороженной.Согласно MSDN , когда это происходит, вам нужно создать клон и изменить его:

  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
...