Проблема цветовой анимации раскадровки ControlTemplate - PullRequest
5 голосов
/ 14 апреля 2011

У меня проблема с цветной анимацией.Это мой источник:

 <Window.Resources>
    <hedit:BrushToColorConverter x:Key="BrushToColorConverter" />
    <Style x:Key="MyButtonStyle" TargetType="Button">
        <Setter Property="OverridesDefaultStyle" Value="True"/>
        <Setter Property="Margin" Value="5"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Button">
                    <ControlTemplate.Resources>
                        <Storyboard x:Key="buttonAnimIn">
                            <!-- Problem line -->
                            <ColorAnimation Storyboard.TargetName="bntBack" Storyboard.TargetProperty="Color" To="{Binding Path=Foreground, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}, Converter={StaticResource BrushToColorConverter}}" />
                        </Storyboard>
                        <Storyboard x:Key="buttonAnimOut">
                            <ColorAnimation Storyboard.TargetName="bntBack" Storyboard.TargetProperty="Color" To="Blue" />
                        </Storyboard>
                        <Storyboard x:Key="buttonAnimForegroundIn">
                            <ColorAnimation Storyboard.TargetName="btnFore" Storyboard.TargetProperty="Color" To="Blue" />
                        </Storyboard>
                        <Storyboard x:Key="buttonAnimForegroundOut">
                            <ColorAnimation Storyboard.TargetName="btnFore" Storyboard.TargetProperty="Color" To="Red" />
                        </Storyboard>
                    </ControlTemplate.Resources>
                    <Border Name="border" 
                        BorderThickness="1"
                        Padding="4,2" 
                        BorderBrush="DarkGray" 
                        CornerRadius="3">
                        <Border.Background>
                            <SolidColorBrush Color="Blue" x:Name="bntBack" />
                        </Border.Background>
                        <ContentControl HorizontalAlignment="Center" VerticalAlignment="Center" Content="{TemplateBinding Content}">
                            <ContentControl.Foreground>
                                <SolidColorBrush Color="Red" x:Name="btnFore" />
                            </ContentControl.Foreground>
                        </ContentControl >
                    </Border>
                    <ControlTemplate.Triggers>
                        <EventTrigger RoutedEvent="Button.MouseEnter">
                            <BeginStoryboard Storyboard="{StaticResource buttonAnimIn}" />
                            <BeginStoryboard Storyboard="{StaticResource buttonAnimForegroundIn}" />
                        </EventTrigger>
                        <EventTrigger RoutedEvent="Button.MouseLeave">
                            <BeginStoryboard Storyboard="{StaticResource buttonAnimOut}" />
                            <BeginStoryboard Storyboard="{StaticResource buttonAnimForegroundOut}" />
                        </EventTrigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>

Проблема:

Невозможно преобразовать значение в атрибуте 'Style' в объект типа 'System.Windows.Style'.Невозможно заморозить это дерево шкалы времени раскадровки для использования в разных потоках.Ошибка объекта 'System.Windows.Controls.Button' в файле разметки 'HLSLEditor; component / mainwindow.xaml' Строка 223, позиция 25.

При использовании фиксированных цветов это работает, но не может работать с цветом переднего планародителя ...

Как сделать анимацию на переднем плане или на цвет фона?

Спасибо!

Ответы [ 3 ]

6 голосов
/ 01 мая 2011

Вы не можете заморозить привязки, вы, вероятно, можете обойти эту проблему, объявив цвет в качестве ресурса, а затем привяжите к нему фон вашего элемента управления, используя StaticResource в анимации.

<ColorAnimation Storyboard.TargetProperty="Foreground.Color"
                Duration="0:0:1"
                To="{StaticResource Background}"/>

Альтернатива с использованием класса ресурсов:

public static class MyColors
{
    public static Color MyHighlightColor = Color.FromArgb(255, 0, 88, 0);
}
<ColorAnimation Storyboard.TargetProperty="Foreground.Color"
                Duration="0:0:1"
                To="{x:Static local:MyColors.MyHighlightColor}"/>
2 голосов
/ 31 мая 2011

Я думаю, что понимание ошибки может помочь вам решить проблему.

Анимация требует использования потоков помимо потока пользовательского интерфейса. Таким образом, раскадровки должны быть замораживаемыми, что означает, что все анимации в раскадровке должны быть замораживаемыми, а все, что используют эти анимации, также должно быть замораживаемым.

Привязки не замораживаются - в значительной степени по определению, поскольку они представляют собой механизм, посредством которого свойство зависимости может быть изменено. Вы не можете использовать динамическую привязку в цветной анимации - есть вероятность, что свойство может измениться во время работы анимации. То же самое происходит, привязываетесь ли вы к объекту или используете DynamicResource.

Дело в том, что это защищает вас от чего-то, чего вы на самом деле не хотите. Вы не хотите, чтобы цвета менялись во время анимации. Это не то, что вы пытаетесь достичь. Требуется изменить цветовые ресурсы, которые использует анимация, если пользователь выбирает другой скин.

Таким образом, вместо привязки раскадровок к ресурсам с поддержкой скинов, добавьте раскадровки в словарь ресурсов, которые устанавливаются при смене скина (используя статические привязки для установки цветов), и используйте динамическое связывание в триггерах событий. Это должно работать.

1 голос
/ 16 апреля 2013

Когда я столкнулся с этой проблемой, я обошел ее, изменив свой стиль так, чтобы он содержал два одинаковых элемента друг над другом - один для «нормального» состояния и один для «нажатого» состояния. У «нажатой» по умолчанию Opacity был установлен на 0, а у другой Opacity = 1. Моя анимация изменила прозрачность с 0 на 1 и наоборот.

Этот подход позволил избежать фактической анимации свойства Color, но дал тот же эффект, сохраняя все в XAML. Так как цвета были заданы в определении стиля, а не в анимации, их можно связывать по мере необходимости. Это, вероятно, не подходит для всех ситуаций, но для моего довольно простого стиля это был очень быстрый способ достичь желаемого эффекта.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...