Использование настраиваемого свойства элемента управления в анимации - PullRequest
1 голос
/ 04 февраля 2011

Как подключить настраиваемые свойства элемента управления, которые анимируются внутри шаблона элемента управления?

Я создаю настраиваемую кнопку с несколькими состояниями и хочу анимировать цвет текста кнопки в качестве состоянияизменения.Обычно текст серый, а при наведении мыши он становится черным.

Я создал NormalTextBrush для черного текста и FadedTextBrush для серого текста:

<SolidColorBrush x:Key="NormalTextBrush" Color="Black" />
<SolidColorBrush x:Key="FadedTextBrush" Color="DarkSlateGray" />

Пока все хорошо.Моя анимация запускается без ошибок.Когда мышь проходит над кнопкой, текст становится серым и черным.Но то, что я действительно хочу сделать, это позволить разработчику с помощью элемента управления указать цвет текста.

Итак, я переопределяю обе текстовые кисти как привязки к свойству Foreground элемента управления.FadedTextBrush использует конвертер значений для исчезновения цвета переднего плана.Переопределенные ресурсы выглядят так:

<SolidColorBrush x:Key="NormalTextBrush" Color="{Binding Path=Foreground, RelativeSource={RelativeSource TemplatedParent}}" />
<SolidColorBrush x:Key="FadedTextBrush" Color="{Binding Path=Foreground, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource ColorConverter}, ConverterParameter='1.2'}" />

И вот тут у меня возникают проблемы.WPF не разрешает привязки анимаций внутри шаблонов управления.Выдает исключение с сообщением «Не удается заморозить это дерево шкалы времени раскадровки для использования в потоках».Проблема задокументирована здесь .

И это подводит меня к моему вопросу: как настроить ресурсы Brush так, чтобы они были связаны со свойством Foreground, но чтобы я могиспользовать их с анимацией в моем шаблоне управления?

Кто может ответить на этот вопрос, я куплю вам пиво в следующий раз, когда увижу вас!Спасибо за вашу помощь.

1 Ответ

0 голосов
/ 04 февраля 2011

Вы должны обойтись с доступными вам инструментами. Я хотел бы предложить два текстовых блока, которые занимают одно и то же пространство экрана, а затем управлять непрозрачностью каждого из них в раскадровке. Вот как можно наложить два текстовых блока, где верхний прозрачный в состоянии по умолчанию:

<Grid>
    <TextBlock x:Name="textBlock1" Foreground="Black"
        Margin="{TemplateBinding Padding}"
        VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
        HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
        SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
        Text="{TemplateBinding Content}"/>
    <TextBlock x:Name="textBlock2" Foreground="Gray"
        Margin="{TemplateBinding Padding}"
        VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
        HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
        SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
        Text="{TemplateBinding Content}" Opacity="0"/>
</Grid>

Затем настройте визуальную группу состояний с помощью менеджера визуальных состояний, чтобы поменять их непрозрачность:

<VisualStateGroup x:Name="CommonStates">
    <VisualStateGroup.Transitions>
        <VisualTransition GeneratedDuration="0:0:0.5"/>
    </VisualStateGroup.Transitions>
    <VisualState x:Name="Normal"/>
    <VisualState x:Name="MouseOver">
        <Storyboard>
            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="textBlock1">
                <EasingDoubleKeyFrame KeyTime="0" Value="0"/>
            </DoubleAnimationUsingKeyFrames>
            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="textBlock2">
                <EasingDoubleKeyFrame KeyTime="0" Value="1"/>
            </DoubleAnimationUsingKeyFrames>
        </Storyboard>
    </VisualState>
    <VisualState x:Name="Pressed"/>
    <VisualState x:Name="Disabled"/>
</VisualStateGroup>

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

...