Я пытаюсь создать простое (я думаю), эффект анимации на основе изменения свойства в моем 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 Стиля".
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
или что-то еще.
Присутствует ли TextBlock в MyWindowTemplate?
Если да, дайте TextBlock имя и используйте Storyboard.TargetName для ссылки на него.