代码之家  ›  专栏  ›  技术社区  ›  Anthony Waqas Raja

WPF:我能把彩色动画做成一种风格吗?

  •  3
  • Anthony Waqas Raja  · 技术社区  · 15 年前

    这是XAML中的一个简单WPF窗口:

    <Window x:Class="AnimateTest.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window1" Height="300" Width="300"
            x:Name="MainWindow"
            Style="{StaticResource TestStyle}">
        <Grid>
        </Grid>
    </Window>
    

    请注意,这是一种样式。我们能用这种风格做什么?这就是 App.xaml 它的背景是浅蓝色的

    <Application x:Class="AnimateTest.App"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        StartupUri="Window1.xaml">
        <Application.Resources>
            <Style x:Key="TestStyle">
                <Setter Property="Window.Background" Value="AliceBlue" />
            </Style>
        </Application.Resources>
    </Application>
    

    为了变得更复杂,这是一个背景,给它一个蓝色的渐变背景:

    <Application x:Class="AnimateTest.App"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        StartupUri="Window1.xaml">
        <Application.Resources>
            <LinearGradientBrush x:Key="BackgroundBrush"
                EndPoint="0.6,0.6" StartPoint="0,0">
                <GradientStop Color="#FFFFFFFF" Offset="0" />
                <GradientStop Color="#FFD0D0F0" Offset="1" />
            </LinearGradientBrush>
            <Style x:Key="TestStyle">
                <Setter Property="Window.Background" Value="{StaticResource BackgroundBrush}" />
            </Style>
        </Application.Resources>
    </Application>
    

    最后一步,我要做的是动画这种颜色。我有

    <Application x:Class="AnimateTest.App"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        StartupUri="Window1.xaml">
        <Application.Resources>
            <LinearGradientBrush x:Key="BackgroundBrush"
                EndPoint="0.6,0.6" StartPoint="0,0">
                <GradientStop Color="#FFFFFFFF" Offset="0" />
                <GradientStop Color="#FFD0D0F0" Offset="1" />
            </LinearGradientBrush>
            <Style x:Key="TestStyle">
                <Setter Property="Window.Background" Value="{StaticResource BackgroundBrush}" />
            </Style>
            <Storyboard x:Key="ThemeAnimation">
                <ColorAnimationUsingKeyFrames
                Storyboard.TargetName="(UIElement)"
                Storyboard.TargetProperty="Background.GradientStops[1].Color"
                Duration="0:0:10"
                RepeatBehavior="Forever">
                    <ColorAnimationUsingKeyFrames.KeyFrames>
                        <LinearColorKeyFrame Value="#FFD0D0F0" KeyTime="0:0:0" />
                        <LinearColorKeyFrame Value="#FFF0D0F0" KeyTime="0:0:10" />
                    </ColorAnimationUsingKeyFrames.KeyFrames>
                </ColorAnimationUsingKeyFrames>
            </Storyboard>
        </Application.Resources>
    </Application>
    

    所以我可以在窗口构造函数中这样做:

            object themeAnimationObject = this.FindResource("ThemeAnimation");
            Storyboard themeAnimation = themeAnimationObject as Storyboard;
            themeAnimation.Begin(this);
    

    但我有一个例外:

    (UIElement)' name cannot be found in the name scope of 'AnimateTest.Window1'
    

    我尝试了动画的各种值组合 Storyboard.TargetName Storyboard.TargetProperty 属性,但它们不起作用,我只是在黑暗中摸索。最好的结果是能够将样式、动画和所有内容应用到任何窗口,而不需要任何或使用最少的C代码

    更新:以下是基于iTowlson答案的working app.xaml:

    <Application x:Class="AnimateTest.App"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        StartupUri="Window1.xaml">
        <Application.Resources>
            <LinearGradientBrush x:Key="BackgroundBrush"
                EndPoint="0.6,0.6" StartPoint="0,0">
                <GradientStop Color="#FFFFFFFF" Offset="0" />
                <GradientStop Color="#FFD0D0F0" Offset="1" />
            </LinearGradientBrush>
            <Style x:Key="TestStyle" TargetType="FrameworkElement">
                <Setter Property="Window.Background" Value="{StaticResource BackgroundBrush}" />
                <Style.Triggers>
                    <EventTrigger RoutedEvent="Loaded">
                        <BeginStoryboard>
                            <Storyboard>
                                <ColorAnimationUsingKeyFrames
                                    Storyboard.TargetProperty="Background.GradientStops[1].Color"
                                    Duration="0:0:10"
                                    RepeatBehavior="Forever"
                                    AutoReverse="True">
                                    <ColorAnimationUsingKeyFrames.KeyFrames>
                                        <LinearColorKeyFrame Value="#FFD0D0F0" KeyTime="0:0:0" />
                                        <LinearColorKeyFrame Value="#FFF0D0F0" KeyTime="0:0:10" />
                                    </ColorAnimationUsingKeyFrames.KeyFrames>
                                </ColorAnimationUsingKeyFrames>
                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger>
                </Style.Triggers>
            </Style>
        </Application.Resources>
    </Application>
    
    1 回复  |  直到 13 年前
        1
  •  4
  •   itowlson    15 年前

    您没有任何名为“(uielement)”的内容,因此targetname无法解析。Storyboard.begin(frameworkelement)的文档说“没有targetname的动画应用于 升水对象 “,因此您应该可以不使用targetname,动画将应用于背景。渐变停止点[1]。要传入的窗口的颜色。”

    或者,为了避免代码隐藏的需要,为什么不在样式中使用EventTrigger来运行故事板?有关示例,请参阅msdn中的EventTrigger文档。