9

WPFアプリケーションがあり、.Net v4 VisualStateManagerを使用してTextBoxのスタイルを設定しようとしています。具体的には、MouseOver状態の前景と背景の色を設定しようとしています。

何が起こっているのかというと、背景と境界線は完全に変化していますが、前景は変化していません。私が使用しているブラシがStaticResourceを介して色を取得する場合、前景はまったく変化しません。使用しているブラシがDynamicResourceを介して色を取得している場合、TextBoxの上にマウスを置くと、すべてのTextBoxの前景が変わります。明らかに、私が何か間違ったことをしている、または私がやりたいことはVSMでは単純に不可能です(これはかなり残念です)。

私が使用しているリソースは次のとおりです。

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

まったく同じ方法で作成およびアニメーション化される背景ブラシとボーダーブラシが、静的リソースと動的リソースのどちらを使用するかに関係なく完全に機能するのは非常に奇妙ですが、前景色は機能しません。

誰かが何かアイデアを持っているか、これを行うためのより良い方法があれば、私はそれを聞いてみたいです。

David Mullin IMA Technologies

4

1 に答える 1

16

VisualStateManagerバインディングを介して値が設定されるプロパティを制御することはできません。この例では、Backgroundとの両方BorderBrushがローカル値(Transparent)に設定されているため、VSMはそれらをアニメーション化できます。一方、Foregroundはaを使用して設定さTemplateBindingれるため、バインディング値が有効な場合、VSMはそれをアニメーション化できません。

これはの一般的な制限であり、VisualStateManager使用されているすべての例で確認できます。この問題を回避するための一般的な戦略は、レイヤーと不透明度を使用して、実際に起こっていることが1つの要素から別の要素へのフェードである場合に、カラーアニメーションの錯覚を与えることです。これが機能するのは、非表示のレイヤーを完全に制御でき、何にもバインドする必要がないためです。残念ながら、要素は静的ではないため、これはニーズには機能しません。テキストボックスを2つ持つことはできません。

正味の効果は、テキストの前景色をアニメーション化することと、ユーザーが前景色を指定できるようにすることの両方ができるとは思わないことです。

于 2011-04-24T22:57:04.400 に答える