Как анимировать ресурс SolidColorBrush? - PullRequest
0 голосов
/ 06 июня 2019

Я пытаюсь анимировать SolidColorBrush, который является ресурсом моего пользовательского элемента управления. Эта кисть используется как заливка для пяти прямоугольников.

При времени разработки все работает как положено, но при времени выполнения приложение немедленно закрывается с System.InvalidOperationException, указывая, что имя кисти не может быть найдено.

Я запустил пример проекта, имеющий:

  • 1 кисть, которую я хотел бы оживить
<SolidColorBrush x:Name="rectBrush" x:Key="rectangleBrush" Color="#b266b2" />
  • 5 прямоугольников, которые заполнены с помощью этой кисти.
<Grid>
    <StackPanel
        Orientation="Horizontal"
        VerticalAlignment="Center"
        HorizontalAlignment="Center">
        <Rectangle
            Fill="{StaticResource rectangleBrush}" />
        <Rectangle
            Fill="{StaticResource rectangleBrush}" />
        <Rectangle
            Fill="{StaticResource rectangleBrush}" />
        <Rectangle
            Fill="{StaticResource rectangleBrush}" />
        <Rectangle
            Fill="{StaticResource rectangleBrush}" />
    </StackPanel>
</Grid>

Я использую Blend для Visual Studio, чтобы проверить, правильно ли работает раскадровка.

При запуске я получаю:

System.InvalidOperationException: имя '' rectBrush 'не может быть найдено в области имен' AnimationExample.MainWindow '

Полная разметка XAML:

<Window x:Class="AnimationExample.MainWindow"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="200" d:DesignWidth="200">
    <Window.Resources>
        <SolidColorBrush x:Name="rectBrush" x:Key="rectangleBrush" Color="#b266b2" />
        <Style TargetType="Rectangle">
            <Setter Property="Width" Value="6" />
            <Setter Property="Height" Value="6" />
            <Setter Property="Margin" Value="1" />
            <Setter Property="HorizontalAlignment" Value="Left" />
            <Setter Property="VerticalAlignment" Value="Bottom" />
            <Setter Property="RadiusX" Value="3" />
            <Setter Property="RadiusY" Value="3" />
        </Style>
        <Storyboard 
            x:Key="NowPlayingAnimation"
            RepeatBehavior="Forever"
            AutoReverse="True">
            <ColorAnimation
                Storyboard.TargetName="rectBrush"
                Storyboard.TargetProperty="Color"
                From="#b266b2"
                To="#6666ff"
                Duration="0:0:1" />
            <ColorAnimation
                Storyboard.TargetName="rectBrush"
                Storyboard.TargetProperty="Color"
                From="#6666ff"
                To="#66b266"
                Duration="0:0:1"
                BeginTime="0:0:1"/>
            <ColorAnimation
                Storyboard.TargetName="rectBrush"
                Storyboard.TargetProperty="Color"
                From="#66b266"
                To="#ffff66"
                Duration="0:0:1"
                BeginTime="0:0:2"/>
            <ColorAnimation
                Storyboard.TargetName="rectBrush"
                Storyboard.TargetProperty="Color"
                From="#ffff66"
                To="#ffc966"
                Duration="0:0:1"
                BeginTime="0:0:3" />
            <ColorAnimation
                Storyboard.TargetName="rectBrush"
                Storyboard.TargetProperty="Color"
                From="#ffc966"
                To="#ff4c4c"
                Duration="0:0:1"
                BeginTime="0:0:4" />
        </Storyboard>
    </Window.Resources>
    <Window.Triggers>
        <EventTrigger RoutedEvent="FrameworkElement.Loaded">
            <BeginStoryboard Storyboard="{StaticResource NowPlayingAnimation}"/>
        </EventTrigger>
    </Window.Triggers>
    <Grid>
        <StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center">
            <Rectangle Fill="{StaticResource rectangleBrush}" />
            <Rectangle Fill="{StaticResource rectangleBrush}" />
            <Rectangle Fill="{StaticResource rectangleBrush}" />
            <Rectangle Fill="{StaticResource rectangleBrush}" />
            <Rectangle Fill="{StaticResource rectangleBrush}" />
        </StackPanel>
    </Grid>
</Window>

У меня два вопроса:

  1. Почему во время разработки все работает нормально, и я могу видеть, что на самом деле хотел бы получить?

  2. Есть ли способ достичь этого?

    • полностью в XAML;
    • без анимации заливки каждого прямоугольника в отдельности?

Заранее спасибо.

1 Ответ

0 голосов
/ 06 июня 2019

У вас есть два варианта:

  1. Поместите анимацию в стиль и непосредственно анимируйте Background.Color.
  2. Поместите кисть в то место, где она или ее родитель находятся в визуальном дереве, где можно разрешить имя.

Версия 2:

<Window.Resources>
    <SolidColorBrush x:Name="rectBrush" x:Key="rectangleBrush" Color="#b266b2" />
    <Style TargetType="Rectangle">
        <Setter Property="Width" Value="6" />
        <Setter Property="Height" Value="6" />
        <Setter Property="Margin" Value="1" />
        <Setter Property="HorizontalAlignment" Value="Left" />
        <Setter Property="VerticalAlignment" Value="Bottom" />
        <Setter Property="RadiusX" Value="3" />
        <Setter Property="RadiusY" Value="3" />
    </Style>
    <Storyboard 
        x:Key="NowPlayingAnimation"
        RepeatBehavior="Forever"
        AutoReverse="True">
        <ColorAnimation
            Storyboard.TargetName="BrushCarrier"
            Storyboard.TargetProperty="Tag.Color"
            From="#b266b2"
            To="#6666ff"
            Duration="0:0:1" />
        <ColorAnimation
            Storyboard.TargetName="BrushCarrier"
            Storyboard.TargetProperty="Tag.Color"
            From="#6666ff"
            To="#66b266"
            Duration="0:0:1"
            BeginTime="0:0:1"/>
        <ColorAnimation
            Storyboard.TargetName="BrushCarrier"
            Storyboard.TargetProperty="Tag.Color"
            From="#66b266"
            To="#ffff66"
            Duration="0:0:1"
            BeginTime="0:0:2"/>
        <ColorAnimation
            Storyboard.TargetName="BrushCarrier"
            Storyboard.TargetProperty="Tag.Color"
            From="#ffff66"
            To="#ffc966"
            Duration="0:0:1"
            BeginTime="0:0:3" />
        <ColorAnimation
            Storyboard.TargetName="BrushCarrier"
            Storyboard.TargetProperty="Tag.Color"
            From="#ffc966"
            To="#ff4c4c"
            Duration="0:0:1"
            BeginTime="0:0:4" />
    </Storyboard>
</Window.Resources>
<Window.Triggers>
    <EventTrigger RoutedEvent="FrameworkElement.Loaded">
        <BeginStoryboard Storyboard="{StaticResource NowPlayingAnimation}"/>
    </EventTrigger>
</Window.Triggers>
<Grid>
    <FrameworkElement
        x:Name="BrushCarrier"
        Tag="{StaticResource rectangleBrush}"
        />
    <StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center">
        <Rectangle Fill="{StaticResource rectangleBrush}" />
        <Rectangle Fill="{StaticResource rectangleBrush}" />
        <Rectangle Fill="{StaticResource rectangleBrush}" />
        <Rectangle Fill="{StaticResource rectangleBrush}" />
        <Rectangle Fill="{StaticResource rectangleBrush}" />
    </StackPanel>
</Grid>

Версия 1. Здесь раскадровка не определяется как ресурс, и вы не запускаете ее при загрузке окна.Каждый прямоугольник заботится о своей собственной анимации.

<Style TargetType="Rectangle" x:Key="ColorShiftRectangle">
    <Setter Property="Width" Value="6" />
    <Setter Property="Height" Value="6" />
    <Setter Property="Margin" Value="1" />
    <Setter Property="HorizontalAlignment" Value="Left" />
    <Setter Property="VerticalAlignment" Value="Bottom" />
    <Setter Property="RadiusX" Value="3" />
    <Setter Property="RadiusY" Value="3" />
    <Setter Property="Fill" Value="#b266b2" />
    <Style.Triggers>
        <EventTrigger RoutedEvent="Loaded">
            <BeginStoryboard>
                <Storyboard 
                    RepeatBehavior="Forever"
                    AutoReverse="True">
                    <ColorAnimation
                        Storyboard.TargetProperty="Fill.Color"
                        From="#b266b2"
                        To="#6666ff"
                        Duration="0:0:1" />
                    <ColorAnimation
                        Storyboard.TargetProperty="Fill.Color"
                        From="#6666ff"
                        To="#66b266"
                        Duration="0:0:1"
                        BeginTime="0:0:1"/>
                    <ColorAnimation
                        Storyboard.TargetProperty="Fill.Color"
                        From="#66b266"
                        To="#ffff66"
                        Duration="0:0:1"
                        BeginTime="0:0:2"/>
                    <ColorAnimation
                        Storyboard.TargetProperty="Fill.Color"
                        From="#ffff66"
                        To="#ffc966"
                        Duration="0:0:1"
                        BeginTime="0:0:3" />
                    <ColorAnimation
                        Storyboard.TargetProperty="Fill.Color"
                        From="#ffc966"
                        To="#ff4c4c"
                        Duration="0:0:1"
                        BeginTime="0:0:4" />
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>

    </Style.Triggers>
</Style>

Использование:

    <Rectangle Style="{StaticResource ColorShiftRectangle}" />
...