【问题标题】:ColorAnimationUsingKeyFrames changes brushColorAnimationUsingKeyFrames 改变画笔
【发布时间】:2024-04-13 10:10:01
【问题描述】:

您好,我是 WPF 的新手,这是我第一次尝试更改 WPF 控件的样式。多亏了 Expression Blend,在我做出这种风格之前,一切都比预期的要好。

 <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 ControlBackgroundBrush}" Stroke="{StaticResource NormalBrush}" 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>

这两个画笔在这里:

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

<SolidColorBrush x:Key="NormalBrush" Color="{DynamicResource MainColor}"/>
<SolidColorBrush x:Key="ControlBackgroundBrush" Color="{StaticResource ControlBackgroundColor}" />

嗯,有什么问题。禁用 TextBox 应该会更改 TextBox 的 BorderColor 和 Background,但它也会更改使用 NormalBrush 的所有内容的颜色。我只想为所有控件提供几个通用的画笔,以便轻松修改主题。还有一件事我通常在其他样式中使用它们作为静态资源。非常感谢您的建议和帮助。

【问题讨论】:

  • 发生这种情况是因为您正在制作动画(逐步更改静态或共享资源)。如果您只需要影响本地元素,则需要创建一个本地模板。对于你想要完成的事情,我认为VisualState 方法是矫枉过正,记录在案。 ControlTemplate.Trigger 可以轻松触发局部彩色动画。
  • 另一种可能的方法(虽然我不确定这会对其他应用程序组件产生什么其他影响)是使画笔不共享:''

标签: wpf xaml blend visualstates


【解决方案1】:

StaticResource 根据定义为 STATIC(共享),因此为 STATIC 资源的属性设置动画将影响在其范围内使用 StaticResource 的所有元素。通过将 x:Shared 属性标记为 FALSE,WPF 将为每个使用它的元素创建一个实例,而不是一个静态资源:

<SolidColorBrush x:Key="OniiNormalBrush" x:Shared="False" Color="{StaticResource MainColor}"/>

【讨论】:

  • 不要只发布一段代码,请解释为什么这段代码可以解决所提出的问题。没有解释,这不是答案。
【解决方案2】:

嗯,我从来不知道为什么一种颜色会随处改变而第二种颜色不会。正如 cmets 中所建议的那样,我改变了这种风格以使用触发器而不是 visualStates 并且一切正常。

<Style TargetType="{x:Type TextBox}">
<Setter Property="Template">
    <Setter.Value>
        <ControlTemplate TargetType="{x:Type TextBox}">
            <Grid>
                <Rectangle x:Name="Background" Fill="{StaticResource ControlBackgroundBrush}" Stroke="{StaticResource NormalBrush}" RadiusX="2" RadiusY="2"/>
                <ScrollViewer x:Name="PART_ContentHost" Margin="2" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" FontFamily="{TemplateBinding FontFamily}"/>
            </Grid>
            <ControlTemplate.Triggers>
                <Trigger Property="IsEnabled" Value="False">
                    <Setter Property="Fill" TargetName="Background" Value="Red" />
                    <Setter Property="Stroke" TargetName="Background" Value="Green" />
                    <Setter Property="Foreground" Value="Blue" />
                </Trigger>
            </ControlTemplate.Triggers>
         </ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Foreground" Value="Black"/>
<Setter Property="SnapsToDevicePixels" Value="True"/>

编辑

一切都是由NormalBrush 的定义引起的,其中颜色是DynamicResource

【讨论】: