WPF: выбор цели анимации

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

От примеров статьи я видел, DataTrigger является самым легким способом выполнить это. Это появляется то Окно. Триггеры не поддерживают DataTriggers, который привел меня пытаться применить триггер в стиле. Проблема, которую я в настоящее время имею, состоит в том, что я, может казаться, не нацелен на TextBlock (или никакой другой дочерний элемент управления) - что происходит, который код ниже - то, что анимация применяется к фону целого окна.

Если я бросаю StoryBoard. Цель полностью, эффект является точно тем же.

Действительно ли это - правильный подход с неправильным синтаксисом или является там более легким способом выполнить это?

<Style x:Key="MyWindowStyle" TargetType="{x:Type Window}">
    <Setter Property="Template" Value="{StaticResource MyWindowTemplate}"/>
    <Style.Triggers>
        <DataTrigger Binding="{Binding ChangeOccurred}" Value="True">
            <DataTrigger.EnterActions>
                <BeginStoryboard>
                    <Storyboard BeginTime="00:00:00" Duration="0:0:2" Storyboard.Target="{Binding RelativeSource={RelativeSource AncestorType=TextBlock}}"
                                    Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)">
                        <ColorAnimation FillBehavior="Stop" From="Black" To="Red" Duration="0:0:0.5" AutoReverse="True"/>
                    </Storyboard>
                </BeginStoryboard>
            </DataTrigger.EnterActions>
        </DataTrigger>
    </Style.Triggers>
</Style>

Обновление

Должен был также упомянуть, что я пытался назвать TextBlock и сослаться на него через StoryBoard. TargetName (как предложенный Timores), и добрался, ошибка "свойство TargetName не может быть установлена на Методе set Стиля".

5
задан Phil Sandler 29 April 2010 в 20:40
поделиться

2 ответа

EDIT: Я проследил за тем, что TextBlock находится в ControlTemplate вашего пользовательского окна/контроля. Я не думаю, что можно нацелить элемент управления внутри шаблона ControlTemplate из Storyboard вне этого ControlTemplate. Однако вы можете определить свойство вашего пользовательского окна, которое затем привязать к свойству ChangeOccurred, а затем добавить триггер в ваш ControlTemplate, который теперь будет запускаться свойством пользовательского элемента управления, а не свойством ViewModel окна (конечно, косвенно он срабатывает от ViewModel, потому что ChangeOccurred привязан к свойству пользовательского окна, которое в свою очередь запускает анимацию - эээ, сложное предложение, надеюсь вы поняли). Это вариант? Не могли бы вы проследить? ;-)

Возможно, немного кода поможет:

public class MyCustomWindow : Window
{
    public static readonly DependencyProperty ChangeOccurred2 = DependencyProperty.Register(...);

    public bool ChangeOccurred2 { ... }

    // ...
}

И немного XAML:

<local:MyCustomWindow ChangeOccurred2="{Binding ChangeOccurred}" ... >
    <!-- Your content here... -->
</local:MyCustomWindow>

<!-- Somewhere else (whereever your ControlTemplate is defined) -->
<ControlTemplate TargetType="{x:Type local:MyCustomWindow}">

    <!-- your template here -->

    <ControlTemplate.Triggers>
        <Trigger Property="ChangeOccurred2" Value="True">
            <Trigger.EnterActions>
                <BeginStoryboard>
                    <Storyboard BeginTime="00:00:00" Duration="0:0:2"
                                Storyboard.TargetName="txtWhatever"
                                Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)">
                        <ColorAnimation FillBehavior="Stop"
                                        From="Black" To="Red"
                                        Duration="0:0:0.5"
                                        AutoReverse="True"/>
                    </Storyboard>
                </BeginStoryboard>
            </Trigger.EnterActions>
        </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>

Примечание: Я назвал свойство Window ChangeOccurred2, потому что хотел, чтобы его можно было отличить от свойства ViewModel ChangeOccurred. Конечно, вы должны выбрать более подходящее имя для этого свойства. Однако мне не хватает предпосылок для такого решения.


Мой старый ответ:

Итак, вы хотите анимировать TextBlock, который находится в содержимом (пользовательского) окна?!

Почему вы хотите установить стиль для окна, а не для самого TextBlock? Возможно, вам следует попробовать что-то вроде этого (не проверял!):

<local:MyCustomWindow ... >
    <!-- ... -->
    <TextBlock x:Name="textBlockAnimated" ... >
        <TextBlock.Style>
            <Style TargetType="{x:Type TextBlock}">
                <Style.Triggers>
                    <DataTrigger Binding="{Binding ChangeOccurred}" Value="True">
                        <DataTrigger.EnterActions>
                            <BeginStoryboard>
                                <Storyboard BeginTime="00:00:00" Duration="0:0:2"
                                            Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)">
                                    <ColorAnimation FillBehavior="Stop"
                                                    From="Black" To="Red"
                                                    Duration="0:0:0.5"
                                                    AutoReverse="True"/>
                                </Storyboard>
                            </BeginStoryboard>
                        </DataTrigger.EnterActions>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </TextBlock.Style>
    </TextBlock>
    <!-- ... -->
</local:MyCustomWindow>

Привязки {Binding ChangeOccurred} может быть недостаточно. Возможно, вам придется добавить DataContext к TextBlock, или добавить RelativeSource или что-то еще.

5
ответ дан 14 December 2019 в 19:06
поделиться

Присутствует ли TextBlock в MyWindowTemplate?

Если да, дайте TextBlock имя и используйте Storyboard.TargetName для ссылки на него.

См. другой вопрос в SO

0
ответ дан 14 December 2019 в 19:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: