Изменена SolidColorBrush в стиле TextBox

Я уже пытался спросить, но, вероятно, я не предоставил достаточно информации. Я пытаюсь создать свою собственную тему WPF. Все было хорошо, пока я не создал этот стиль.

    <Style TargetType="{x:Type TextBox}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type TextBox}">
                <Grid>
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal"/>
                            <VisualState x:Name="Disabled">
                                <Storyboard>
                                    <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="PART_ContentHost">
                                        <EasingDoubleKeyFrame KeyTime="0" Value="0.5"/>
                                    </DoubleAnimationUsingKeyFrames>
                                    <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="Background">
                                        <EasingColorKeyFrame KeyTime="0" Value="Red"/>
                                    </ColorAnimationUsingKeyFrames>
                                    <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Stroke).(SolidColorBrush.Color)" Storyboard.TargetName="Background">
                                        <EasingColorKeyFrame KeyTime="0" Value="Yellow"/>
                                    </ColorAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="ReadOnly"/>
                            <VisualState x:Name="MouseOver"/>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                    <Rectangle x:Name="Background" Fill="{StaticResource OniiControlBackgroundBrush}" Stroke="{StaticResource OniiNormalBrush}" RadiusX="2" RadiusY="2"/>
                    <ScrollViewer x:Name="PART_ContentHost" Margin="2" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" FontFamily="{TemplateBinding FontFamily}"/>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Setter Property="Foreground" Value="Black"/>
    <Setter Property="SnapsToDevicePixels" Value="True"/>
</Style>

Предполагается, что он меняет цвет фона TextBox и BorderBrush, когда TextBox отключен.

Цвета определены в том же ResourceDictionary

<Color x:Key="MainColor">#FF595959</Color>
<Color x:Key="OniiControlBackgroundColor">#FF333333</Color>

<SolidColorBrush x:Key="OniiNormalBrush" Color="{StaticResource MainColor}"/>
<SolidColorBrush x:Key="OniiControlBackgroundBrush" Color="{StaticResource OniiControlBackgroundColor}" />

А в чем на самом деле моя проблема я не знаю. Что я знаю:

1/ "Когда TextBox отключен, он меняет цвет всего, что использует OniiControlBackgroundBrush, на красный цвет"

  • OniiControlBackgroundBrush упоминается в других стилях как StaticResource.

2/ "Когда я переключаю эти цвета, меняется только OniiControlBackgroundBrush, но на этот раз на желтый"

<Rectangle x:Name="Background" Fill="{StaticResource OniiNormalBrush}" Stroke="{StaticResource OniiControlBackgroundBrush}" RadiusX="2" RadiusY="2"/>
  • OniiNormalBrush также упоминается в других стилях как StaticResource.

3/ "Все определено в одном словаре ресурсов"

    <Application.Resources>
    <ResourceDictionary Source="Theme/OniiResourceDictionary.xaml">
    </ResourceDictionary>
</Application.Resources>

4/ "Я попытался воспроизвести эту проблему в меньшем решении с меньшим количеством настраиваемых стилей, но мне это не удалось"

  • Я использовал тот же стиль TextBox.

    <TextBox Height="32" HorizontalAlignment="Left" Margin="38,51,0,0" Name="textBox1" VerticalAlignment="Top" Width="215" />
    <CheckBox Content="Enabled" Height="16" HorizontalAlignment="Left" Margin="259,51,0,0" Name="checkBox1" VerticalAlignment="Top" Checked="checkBox1_Checked" Unchecked="checkBox1_Unchecked" />
    <Border Height="148" HorizontalAlignment="Left" Margin="254,126,0,0" Name="border1" VerticalAlignment="Top" Width="98" />
    <Rectangle Fill="{StaticResource OniiNormalBrush}" StrokeThickness="20" Stroke="{StaticResource OniiControlBackgroundBrush}" Height="148" HorizontalAlignment="Left" Margin="358,126,0,0" Name="rectangle5" VerticalAlignment="Top" Width="99" />
    
  • Текстовое поле отключено и включено флажком, граница использует собственный стиль с обоими цветами как StaticResources

5/ "Когда я добавляю следующий код к исходному решению, проблема исчезает"

<Rectangle Height="71" HorizontalAlignment="Left" Margin="130,131,0,0" Name="rectangle2" StrokeThickness="20" Stroke="{StaticResource OniiControlBackgroundBrush}" Fill="{StaticResource OniiNormalBrush}" VerticalAlignment="Top" Width="98" />

Я действительно что-то упустил? Или я просто очень глупый? В любом случае Ваша помощь будет оценена по достоинству. Я действительно потерян. Ну и последнее, что я не хочу использовать x:Shared="false" в основном потому, что вижу, что нет проблем с изменением OniiNormalBrush. Спасибо.


person Kapitán Mlíko    schedule 12.11.2012    source источник


Ответы (1)


Проблема, похоже, заключается в привязках ваших ресурсов. Когда вы используете StaticResource, это означает, что ресурс загружается при инициализации окна, а затем больше никогда не загружается. Таким образом, в большинстве случаев, когда вы изменяете ресурс, связанные с ним элементы управления не знают об изменении.

В № 4 вы не столкнулись с проблемой, потому что использовали DynamicResource, который позволяет обновлять ресурс во время выполнения.

Редактировать: при просмотре вещей во второй раз кажется, что это может быть одна из двух вещей.

Во-первых, статическая привязка цвета не позволяет обновлять. Устраняет ли проблему изменение статического на динамическое при привязке цвета к кисти?

<Color x:Key="MainColor">#FF595959</Color>
<Color x:Key="OniiControlBackgroundColor">#FF333333</Color>

<SolidColorBrush x:Key="OniiNormalBrush" Color="{DynamicResource MainColor}"/>
<SolidColorBrush x:Key="OniiControlBackgroundBrush" Color="{DynamicResource OniiControlBackgroundColor}" />

Два... Анимация задает цвет кисти... что, по сути, очищает привязку, назначая ей прямой цвет. Я бы предположил, что когда анимация закончится, цвет вернется к привязке, но это может быть не так. Имеет ли это какое-либо влияние:

<SolidColorBrush x:Key="OniiNormalBrush" Color="#FF595959"/>
<SolidColorBrush x:Key="OniiControlBackgroundBrush" Color="#FF333333" />
person Bill Tarbell    schedule 12.11.2012
comment
Нет проблем с изменением цвета текстового поля... цвет кисти OniiControlBackgroundBrush везде меняется. Я не хочу этого. В № 4, когда я ссылаюсь на Brush как на StaticResource, у него, похоже, тоже нет проблем. - person Kapitán Mlíko; 12.11.2012
comment
Верно, но в верхних примерах вы статически привязываете цвет кисти. Цвет={MainColorСтатикРесурса}. Я предполагаю, что в ваших нижних примерах вы этого не делаете. Ресурсы дают вам ссылку на объект. В случае цветов, если вы добавите новый цвет, ссылка изменится, и все, на что ссылаются статически, не получит обновление, но ссылки dynamicResource увидят новый цвет. Кроме того, значение по умолчанию для x:Shared равно true, поэтому установка его вручную не имеет никакого дополнительного эффекта. - person Bill Tarbell; 12.11.2012
comment
Да, это проблема. у меня обе кисти везде упоминаются как StaticResource. Так что я не жду, что они изменятся. Худшая проблема заключается в том, что одна из этих кистей обновляется там, где должна, а вторая обновляется ВЕЗДЕ, где она используется. Прошу прощения за то, что x:Shared=true запутался. То, что я упомянул, было x:Shared=false. И я также отредактировал # 4, где на этот раз я использовал StaticResource. Все тот же результат. Один цвет обновляется везде, а второй только там, где должен. - person Kapitán Mlíko; 13.11.2012