7

アニメ化する方法はありTextBox.ForegroundPropertyますか?

<Color x:Key="NormalColor">#FF666666</Color>
<SolidColorBrush x:Key="NormalBrush" Color="{StaticResource NormalColor}" />

<Color x:Key="MouseOverColor">#FF666666</Color>
<SolidColorBrush x:Key="MouseOverBrush" Color="{StaticResource MouseOverColor}" />

<ControlTemplate x:Key="RegularTextBoxTemplate" TargetType="{x:Type TextBox}">
    <Grid>
        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="CommonStates">
                <VisualStateGroup.Transitions>
                    <VisualTransition GeneratedDuration="0:0:0.1"/>
                </VisualStateGroup.Transitions>
                <VisualState x:Name="Normal"/>
                <VisualState x:Name="MouseOver">
                    <Storyboard>
                        <!-- storyboard to animating foreground here... -->
                    </Storyboard>
                </VisualState>
            </VisualStateGroup >
        </VisualStateManager>
        <ScrollViewer x:Name="PART_ContentHost" 
                      BorderThickness="0"
                      IsTabStop="False"
                      Background="{x:Null}"/>
    </Grid>
</ControlTemplate>

<Style x:Key="RegularTextBox" TargetType="{x:Type TextBox}">
    <Setter Property="Foreground" Value="{StaticResource NormalBrush}"/>
    <Setter Property="Template" Value="{StaticResource RegularTextBoxTemplate}"/>
</Style>

私が試したストーリーボードは次のとおりです。

<ColorAnimationUsingKeyFrames Storyboard.TargetName="PART_ContentHost"
                  Storyboard.TargetProperty="(Foreground).(SolidColorBrush.Color)">
    <EasingColorKeyFrame KeyTime="0" Value="{StaticResource MouseOverColor}" />
</ColorAnimationUsingKeyFrames>

<ColorAnimationUsingKeyFrames Storyboard.TargetName="PART_ContentHost"
              Storyboard.TargetProperty="(Control.Foreground).(SolidColorBrush.Color)">
    <EasingColorKeyFrame KeyTime="0" Value="{StaticResource MouseOverColor}" />
</ColorAnimationUsingKeyFrames>

<ColorAnimationUsingKeyFrames Storyboard.TargetName="PART_ContentHost"
          Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)">
    <EasingColorKeyFrame KeyTime="0" Value="{StaticResource MouseOverColor}" />
</ColorAnimationUsingKeyFrames>

<ColorAnimationUsingKeyFrames
                  Storyboard.TargetProperty="(Foreground).(SolidColorBrush.Color)">
    <EasingColorKeyFrame KeyTime="0" Value="{StaticResource MouseOverColor}" />
</ColorAnimationUsingKeyFrames>

<ColorAnimationUsingKeyFrames
              Storyboard.TargetProperty="(TextBox.Foreground).(SolidColorBrush.Color)">
    <EasingColorKeyFrame KeyTime="0" Value="{StaticResource MouseOverColor}" />
</ColorAnimationUsingKeyFrames>

<ColorAnimationUsingKeyFrames
              Storyboard.TargetProperty="(Control.Foreground).(SolidColorBrush.Color)">
    <EasingColorKeyFrame KeyTime="0" Value="{StaticResource MouseOverColor}" />
</ColorAnimationUsingKeyFrames>

<ColorAnimationUsingKeyFrames
          Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)">
    <EasingColorKeyFrame KeyTime="0" Value="{StaticResource MouseOverColor}" />
</ColorAnimationUsingKeyFrames>

それらのどれも機能しません。何か案が?それは可能ですか?

4

3 に答える 3

11

さて、私を助けようとしてくれたすべての人のおかげで、私は自分の答えを見つけました. プロパティをリソースに設定TextBox.Foregroundすると、ストーリーボードはそれをアニメーション化できないようです。したがって、スタイルは次のようになります。

<Style x:Key="RegularTextBox" TargetType="{x:Type TextBox}">
    <Setter Property="Foreground">
        <Setter.Value>
            <SolidColorBrush Color="{DynamicResource NormalColor}"/>
        </Setter.Value>
    </Setter>
    <Setter Property="Template" Value="{StaticResource RegularTextBoxTemplate}"/>
</Style>

これが私が抱えていた唯一の問題でした。しかし、覚えておくべき注意事項があります。ストーリーボードでテンプレート化された親をターゲットにしたい場合、それにバインドする必要はありません。そのままにしておく必要があります。

<!-- It's not necessary to set Storyboard.TargetName in storyboard -->
<!-- It will automatically target the TemplatedParent -->
<ColorAnimationUsingKeyFrames
              Storyboard.TargetProperty="(TextBox.Foreground).(SolidColorBrush.Color)">
    <EasingColorKeyFrame KeyTime="0" Value="{DynamicResource MouseOverColor}" />
</ColorAnimationUsingKeyFrames>

これは私にとってはうまくいきます。


これが実際の例です。

于 2013-08-25T02:06:36.960 に答える
9

これが思った以上に問題でした。これが私の元の答えです:


それは間違いなく可能です - それが ColorAnimationXXX クラスの目的です。

コードは、代わりに ColorAnimation を使用して色をアニメーション化するコード例hereと非常によく似ています。この例のプロパティは、アニメーションで簡単に参照できるように、XAML で定義され、名前が付けられた Brush (TextBox.Foreground と同様) を受け取ります。

したがって、あなたの場合、関連するコードは次のようになります。

<VisualState Name="...">
   <Storyboard>
      <ColorAnimation To="Green" 
                      Storyboard.TargetName="tbBrush" 
                      Storyboard.TargetProperty="Color"/>
    </Storyboard>
</VisualState>

と:

<TextBox.Foreground>
  <SolidColorBrush x:Name="tbBrush" Color="#FF666666"/>
</TextBox.Foreground>

理論的には、それがスタイルで機能しないことに気付くまで、それはすべて非常にうまくいっていました. スタイル内の GridのBackgroundプロパティは、次のようなもので簡単にアニメーション化できます。

Storyboard.TargetProperty="(Grid.Background).(SolidColorBrush.Color)"

テキストの前景に影響を与えるアニメーション化するプロパティを見つけることは、はるかに困難です。最初に私が試したTextElement.Foreground、これは直感的なようで、このプロパティを Grid および ScrollViewer レベルで設定することができました。これは、下にあるすべての子オブジェクトに影響を与えると予想していました。これには、TextBox のテキストを含む最下レベルのオブジェクトが含まれます。私の仮定では、TextBox コンテンツは内部で TextBlock に設定され、それに設定された Foreground 添​​付プロパティの値に従います。私の仮定が間違っていたようで、PART_ContentHost ScrollViewer のコンテンツは、TextBox 内の制御ロジックによって、最上位の TextBox とそれ自体の間のオブジェクト ツリーの Foreground 依存関係プロパティに従わない下位レベルのオブジェクトに設定されます。

問題は、スタイル設定されている TextBox のスタイル内で TextBox の Foreground プロパティを設定する方法です。テストのために、これを TwoWay TemplatedParent バインディングで設定しようとしました。SolidColorBrush の Color への PropertyPath を正しく取得したと思いますが、その時点で Color プロパティが明らかに不変であるため、まだ機能しませんでした。この問題はここに文書化されていると思います。

機能しないという事実に加えて、Foreground プロパティを内部で設定することは、外部のコンシューマーがそのプロパティの値を制御していると期待するため、適切ではないように思われました。そのため、TextBox の Foreground がスタイルの何にも従わないことを考えると、TextBox スタイル内にネストされた TextBox を使用して機能を実装するのが最適であるという結論に達しました。外側のスタイルにはステート マネージャーとほとんどのレイアウトが含まれ、内側の TextBox にはテキスト ビットを表示するためだけに設計された独自のスタイルとコントロール テンプレートがあります。外側のスタイルは内側の TextBox の Foreground プロパティを設定でき、内側のスタイルはこれに従います。重要なことに、外側のスタイルは状態マネージャーでこの値を設定できます。

<ControlTemplate x:Key="RegularTextBoxTemplate" TargetType="{x:Type TextBox}"> 
    <Grid>
        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="CommonStates">
                <VisualStateGroup.Transitions>
                    <VisualTransition GeneratedDuration="0:0:0.1"/>
                </VisualStateGroup.Transitions>
                <VisualState x:Name="Normal"/>
                <VisualState x:Name="MouseOver">
                    <Storyboard>
                        <ColorAnimation To="HotPink"
                            Storyboard.TargetName="InternalTextBox"
                            Storyboard.TargetProperty="(TextBox.Foreground).(SolidColorBrush.Color)"/>
                    </Storyboard>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>
        <TextBox Foreground="Black" Text="{TemplateBinding Text}" x:Name="InternalTextBox">
            <TextBox.Style>
                <Style TargetType="{x:Type TextBox}">
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="{x:Type TextBox}">
                                <Grid Background="{x:Null}">
                                    <ScrollViewer x:Name="PART_ContentHost"
                                        BorderThickness="0"
                                        IsTabStop="False"
                                        Background="{x:Null}" />
                                </Grid>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </TextBox.Style>
        </TextBox>
    </Grid>
</ControlTemplate>

<Style x:Key="RegularTextBox" TargetType="{x:Type TextBox}">
    <Setter Property="Template" Value="{StaticResource RegularTextBoxTemplate}"/>
</Style>

このアプローチについて他の人のコメントを聞くことに興味があります。問題を解決し、結果のアプリケーションをスヌーピングしようとした私の試みに基づいて、これは現時点で私が見ることができる最も簡単な解決策です。

于 2013-08-24T22:07:45.293 に答える
2

Storyboard.TargetTemplatedParent にバインドできます。

<ColorAnimationUsingKeyFrames
        Storyboard.Target="{Binding RelativeSource={RelativeSource TemplatedParent}}"
        Storyboard.TargetProperty="(TextBox.Foreground).(SolidColorBrush.Color)">
    <EasingColorKeyFrame KeyTime="0" Value="{StaticResource MouseOverColor}" />
</ColorAnimationUsingKeyFrames>

残念ながら、通常の前景ブラシがスタイルに設定されておらず、TextBox 要素に直接設定されている場合にのみ、これを機能させることができました。

<TextBox Foreground="{StaticResource NormalBrush}" Style="{StaticResource RegularTextBox}" />

スタイルで設定されている場合、MouseOver 状態をトリガーすると、「不変オブジェクト インスタンスで '(0).(1)' をアニメーション化できません」がスローされます。 edit : これは、TextBox の前景を初期化後に再度設定した場合にも発生します。

于 2013-08-25T01:45:05.570 に答える