【问题标题】:Problem at the beginning of a ColorAnimation for a GradientStop in a VisualStateVisualState 中 GradientStop 的 ColorAnimation 开始时的问题
【发布时间】:2011-03-27 22:43:05
【问题描述】:

我对 ColorAnimation 有一个非常奇怪的问题。我想做的很简单(我认为):我有一个带有 GradientBrush 作为背景的矩形。这个矩形有不同的 VisualStates 来改变渐变的颜色。我想为状态之间的过渡制作动画。我的问题是当我改变状态时,动画不是以当前颜色开始,而是以默认颜色开始。

这里有一个代码 sn-p 可以帮助你重现这个:

<Window x:Class="TestColorAnimation.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="350" Width="525">

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition Height="30" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>

    <Rectangle Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" x:Name="rect">
        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup>
                <VisualStateGroup.Transitions>
                    <VisualTransition GeneratedDuration="0:0:0.5"/>
                </VisualStateGroup.Transitions>
                <VisualState x:Name="OrangeState">
                    <Storyboard>
                        <ColorAnimation Storyboard.TargetProperty="Color"
                                        Storyboard.TargetName="stop1"
                                        To="Orange" />
                    </Storyboard>
                </VisualState>
                <VisualState x:Name="RedState">
                    <Storyboard>
                        <ColorAnimation Storyboard.TargetProperty="Color"
                                        Storyboard.TargetName="stop1"
                                        To="Red" />
                    </Storyboard>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>
        <Rectangle.Fill>
            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                <GradientStop x:Name="stop1" Color="LightGray" Offset="0" />
                <GradientStop x:Name="stop2" Color="LightGray" Offset="1" />
            </LinearGradientBrush>
        </Rectangle.Fill>
    </Rectangle>

    <Button Grid.Row="1" Grid.Column="0" Content="Go to orange"
     x:Name="orangeButton" Click="orangeButton_Click" />
    <Button Grid.Row="1" Grid.Column="1" Content="Go to red"
     x:Name="redButton" Click="redButton_Click" />
</Grid>
</Window>

事件处理程序只是调用状态更改:

private void orangeButton_Click(object sender, RoutedEventArgs e)
{
    VisualStateManager.GoToElementState(this.rect, "OrangeState", true);
}

private void redButton_Click(object sender, RoutedEventArgs e)
{
    VisualStateManager.GoToElementState(this.rect, "RedState", true);
}

在这种情况下,如果我进入橙色状态,动画会从灰色变为橙色。但是,当我进入红色状态时,动画从灰色变为红色。我希望(并且期望)它从橙色变为红色。

我尝试使用SolidColorBrush 而不是LinearGradientBrush,并且转换按预期进行。我还尝试在VisualStates 之外使用故事板(但使用LinearGradientBrush),它也可以按预期工作。我重现此问题的唯一情况是示例中的情况:LinearGradientBrushColorAnimation 中的VisualState

我做错了吗?我想要的可能吗?

【问题讨论】:

    标签: wpf gradient visualstates coloranimation


    【解决方案1】:

    如果您直接将目标更改为 GradientStop 颜色,则可以为 LinearGradient 设置动画:

    <VisualState x:Name="OrangeState">
        <Storyboard>
            <ColorAnimation 
                Storyboard.TargetProperty = "(Rectangle.Fill).(LinearGradientBrush.GradientStops)[0].(GradientStop.Color)"
                Storyboard.TargetName="rect"
                To="Orange" />
        </Storyboard>
    </VisualState>
    <VisualState x:Name="RedState">
        <Storyboard>
            <ColorAnimation 
                Storyboard.TargetProperty = "(Rectangle.Fill).(LinearGradientBrush.GradientStops)[0].(GradientStop.Color)"
                Storyboard.TargetName="rect"
                To="Red" />
        </Storyboard>
    </VisualState>
    

    【讨论】:

    • 确实如此!非常感谢@Gimno!我不太确定为什么……是因为动画应该引用具有视觉状态的对象吗?
    • 不幸的是我也不知道答案。我很少使用 VisualStateManager,所以我最初认为上面的示例应该可以工作。
    • 我明白了。不过我很想知道,因为这并没有解决我在实际应用程序中的问题。 (此代码只是重现我的问题的 sn-p)。我正在尝试缩小范围以重现它,但到目前为止我还没有成功。
    • 我将其标记为已回答,因为它解决了我在问题中提出的问题,但我仍在寻找更完整的解释...
    最近更新 更多