使用Visual State Manager设置问题的前景 [英] Problem setting Foreground with Visual State Manager

查看:103
本文介绍了使用Visual State Manager设置问题的前景的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个WPF应用程序,并且我尝试使用.Net v4视觉状态管理器为TextBox设置样式.具体来说,我正在尝试为MouseOver状态设置前景和背景的颜色.

I have a WPF application, and I am attempting to style a TextBox using the .Net v4 Visual State Manager. Specifically, I am attempting to set the colors of the Foreground and Background for the MouseOver state.

正在发生的事情是,尽管背景和边框发生了完美的变化,但前景却没有变化.如果我使用的画笔通过StaticResource获得了颜色,则前景根本不会改变.如果我使用的画笔通过DynamicResource获得颜色,那么当我将鼠标悬停在TextBox上时,所有TextBoxes的前景都会改变.显然,要么我做错了事,要么我想做的事根本无法通过VSM进行(这会令人失望).

What is happening is that, while the background and border are changing perfectly, the foreground is not. If the brushes that I am using get their color via a StaticResource, then the foreground does not change at all. If the brushes that I am using get their color via a DynamicResource, then when I mouse over a TextBox, the foreground of all TextBoxes change. Clearly, either I'm doing something wrong, or what I want to do is simply not possible with VSM (which would be rather disappointing).

以下是我正在使用的资源:

Here are the resources that I am using:

<Color x:Key="ControlBackgroundColor" R="178" G="178" B="178" A="255" />
<Color x:Key="ControlForegroundColor" R="0" G="0" B="0" A="255" />
<Color x:Key="BorderColor" R="127" G="127" B="127" A="255" />
<Color x:Key="MouseOverControlBackgroundColor" R="0" G="0" B="0" A="255" />
<Color x:Key="MouseOverControlForegroundColor" R="255" G="255" B="255" A="255" />
<Color x:Key="MouseOverBorderColor" R="178" G="178" B="178" A="255" />

<SolidColorBrush PresentationOptions:Freeze="True" x:Key="ControlBackgroundBrush" Color="{DynamicResource ControlBackgroundColor}" />
<SolidColorBrush PresentationOptions:Freeze="True" x:Key="ControlForegroundBrush" Color="{DynamicResource ControlForegroundColor}" />
<SolidColorBrush PresentationOptions:Freeze="True" x:Key="BorderBrush" Color="{DynamicResource BorderColor}" />

<SolidColorBrush PresentationOptions:Freeze="True" x:Key="MouseOverControlBackgroundBrush" Color="{DynamicResource MouseOverControlBackgroundColor}" />
<SolidColorBrush PresentationOptions:Freeze="True" x:Key="MouseOverControlForegroundBrush" Color="{DynamicResource MouseOverControlForegroundColor}" />
<SolidColorBrush PresentationOptions:Freeze="True" x:Key="MouseOverBorderBrush" Color="{DynamicResource MouseOverBorderColor}" />

<Style TargetType="{x:Type TextBox}" >
    <Setter Property="BorderThickness" Value="1"/>
    <Setter Property="Padding" Value="2"/>
    <Setter Property="Margin" Value="1" />
    <Setter Property="BorderBrush" Value="{DynamicResource BorderBrush}" />
    <Setter Property="Background" Value="{DynamicResource ControlBackgroundBrush}" />
    <Setter Property="Foreground" Value="{DynamicResource ControlForegroundBrush}" />

    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="TextBox">
                <Grid x:Name="RootElement">
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal"/>
                            <VisualState x:Name="MouseOver">
                                <Storyboard>
                                    <ColorAnimation Storyboard.TargetName="MouseOverBorder" Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)" To="{DynamicResource MouseOverBorderColor}" Duration="0:0:0.3"/>
                                    <ColorAnimation Storyboard.TargetName="MouseOverBorder" Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" To="{DynamicResource MouseOverControlBackgroundColor}" Duration="0:0:0.3"/>
                                    <ColorAnimation Storyboard.TargetName="PART_ContentHost" Storyboard.TargetProperty="(Foreground).(SolidColorBrush.Color)" To="{DynamicResource MouseOverControlForegroundColor}" Duration="0:0:0.3"/>
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                    <Border x:Name="Border" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="1" Opacity="1" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}">
                        <Grid x:Name="ContentGrid">
                            <Border x:Name="MouseOverBorder" BorderThickness="1" BorderBrush="Transparent" Background="Transparent">
                                <ScrollViewer x:Name="PART_ContentHost" Padding="{TemplateBinding Padding}" Foreground="{TemplateBinding Foreground}" BorderThickness="0" IsTabStop="False"/>
                            </Border>
                        </Grid>
                    </Border>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

对于我来说很奇怪的是,以完全相同的方式创建和设置动画的背景和边界画笔,无论我使用静态还是动态资源,都可以完美地工作,而前景颜色却不使用.

It is very odd to me that the background and boarder brushes, which are created and animated in exactly the same way, work perfectly regardless of whether I use Static or Dynamic resources, but that the Foreground color does not.

如果有人有任何想法,或者有更好的方法可以做到这一点,我很想听听.

If anyone has any ideas, or if there is a better way to do this, I'd love to hear it.

大卫·穆林(David Mullin) IMA Technologies

David Mullin IMA Technologies

推荐答案

VisualStateManager无法控制其值是通过绑定设置的属性.在您的示例中,BackgroundBorderBrush都设置为局部值(Transparent),因此VSM可以为其设置动画.另一方面,Foreground是使用TemplateBinding设置的,因此,如果绑定值生效,则VSM将无法对其进行动画处理.

The VisualStateManager cannot control properties whose values are set via a binding. In your example, both Background and BorderBrush are set to local values (Transparent) and therefore the VSM can animate them. On the other hand, Foreground is set using a TemplateBinding and so the VSM will be unable to animate it if a binding value is in effect.

这是VisualStateManager的一般限制,您将在使用它的所有示例中看到它.解决此问题的一种典型策略是,当实际发生的是从一个元素淡入另一个元素时,使用图层和不透明性给人以色彩动画的错觉.之所以可行,是因为您可以完全控制隐藏层,而不必将其绑定到任何东西.不幸的是,这不能满足您的需求,因为该元素不是静态的.您不能有两个文本框.

This is a general limitation of the VisualStateManager and you will see it in all the examples where it is used. A typical strategy to work around the problem is to use layers and opacity to give the illusion of color animation when really what is happening is a fade from one element to another. This works because you have total control over the hidden layer and don't have to bind it to anything. Unfortunately this won't work for your needs though because the element is not static; you cannot have two text boxes.

最终效果是,我认为您不能同时为文本前景色设置动画,也不能让用户指定前景色.

The net effect is that I do not think you can both animate the text foreground color and allow the foreground color to be specified by the user.

这篇关于使用Visual State Manager设置问题的前景的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆