我正在寻找代码隐藏在ControlTemplate
中包含的控件上启动动画的方法。
在我的应用程序中,我有一个由ObservableCollection
:
MainMenuViewModel:
/// <summary>
/// Menu items list
/// </summary>
private ObservableCollection<MenuItem> _items;
....
/// <summary>
/// Menu items list property
/// </summary>
public ObservableCollection<MenuItem> Items
{
get { return _items; }
set { _items = value; }
}
MainMenuView:
<UserControl x:Class="OfficeTourismeBrantome.Views.MainMenuView"
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="800" d:DesignWidth="300">
<UserControl.Resources>
<Style x:Key="MenuItemButtonStyle" TargetType="Button">
<Setter Property="FontSize" Value="60" />
<Setter Property="FontFamily" Value="Segoe" />
<Setter Property="FontWeight" Value="UltraLight" />
<Setter Property="Foreground" Value="#FFEBEDEA" />
<!--<Setter Property="Height" Value="{Binding MenuLayout.MenuItemSize.Height}" />-->
<Setter Property="HorizontalContentAlignment" Value="Right" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<ControlTemplate.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard Name="themeSelectionAnimation">
<DoubleAnimation
Storyboard.TargetName="coloredRectangle"
Storyboard.TargetProperty="Width"
From="30.0"
To="250.0"
Duration="0:0:0.3" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</ControlTemplate.Triggers>
<Canvas HorizontalAlignment="Stretch" ClipToBounds="False" >
<ContentPresenter Canvas.Left="{Binding MenuLayout.MenuItemLeftMargin}" HorizontalAlignment="Center"
VerticalAlignment="Center" Canvas.ZIndex="1"/>
<TextBlock
Text="{Binding SecondaryText}"
Canvas.Top="50"
Canvas.Left="10"
FontSize="30"
FontWeight="ExtraLight"
FontStyle="Italic"
Canvas.ZIndex="1"
/>
<Rectangle
Canvas.Top="30"
Canvas.Left="10"
Name="coloredRectangle"
Width="30"
Height="10"
Canvas.ZIndex="0"
Fill="{Binding Color}"/>
</Canvas>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Storyboard x:Key="themeUnselectionAnimation">
<DoubleAnimation
Storyboard.TargetProperty="Width"
From="250.0"
To="30.0"
Duration="0:0:0.15" />
</Storyboard>
</UserControl.Resources>
<ItemsControl Name="menuButtonContainer" ItemsSource="{Binding Items}" Margin="{Binding MenuLayout.MenuMargin}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button
Style="{StaticResource ResourceKey=MenuItemButtonStyle}"
Margin="{Binding ElementName=menuButtonContainer,
Path=DataContext.MenuLayout.MenuItemMargin}"
Height="{Binding ElementName=menuButtonContainer,
Path=DataContext.MenuLayout.MenuItemSize.Height}"
Content="{Binding Text}"
Command="{Binding ElementName=menuButtonContainer,
Path=DataContext.ChangeThemeCommand}"
CommandParameter="{Binding Id}"
/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</UserControl>
正如您在上面的代码中看到的,我在按钮点击时自动触发动画。我想在单击集合中的另一个按钮时反向播放(选择另一个菜单项)。要播放的动画是名为themeUnselectionAnimation的动画。
第一个问题:有没有办法只在XAML中做到这一点?我不确定是否需要按下另一个按钮来触发它。
以下是我的想法:
Button
(这是我的菜单项)命令操作中,发送一条消息,让订阅者更改菜单项。MainMenuView
代码隐藏中注册。到目前为止,我的问题是为动画设置目标控件。为此,我需要在Rectangle
中找到名为coloredRectangle
的{{1}}。怎么做?
以下是我对应上述步骤的代码:
第1步:发送消息(我正在使用MVVM Light框架)
ControlTemplate
第2步:注册消息
/// <summary>
/// Delegates that handles theme change process and tasks
/// </summary>
/// <param name="themeId">the new active theme</param>
private void ChangeTheme(int themeId)
{
// Set current active theme as inactive, if one is selected.
// Exception use because of Single implementation that throw an InvalidOperationException if not item is found
try
{
MenuItem currentTheme = Items.Single(x => x.IsActive == true);
// Check if this is current theme. If it is, we do nothing.
if(currentTheme.Id == themeId)
return;
// If current theme is set and new theme id is not the same, disable the old one
currentTheme.IsActive = false;
// Set new theme as active
Items.Single(x => x.Id == themeId).IsActive = true;
// Finally, launch unselection animation
// Send message and register to it in view code behind
// Create inner message
ThemeChangeNotification innerMessage = new ThemeChangeNotification();
innerMessage.NewThemeId = themeId;
innerMessage.OldThemeId = currentTheme.Id;
NotificationMessage<ThemeChangeNotification> message =
new NotificationMessage<ThemeChangeNotification>(innerMessage, "");
// Send message
Messenger.Default.Send(message);
}
catch (InvalidOperationException exception)
{
// Set first theme selection as active
Items.Single(x => x.Id == themeId).IsActive = true;
}
}
第3步:从index / id到达Button并启动动画(不工作)
Messenger.Default.Register<NotificationMessage<ThemeChangeNotification>>(this, ChangeThemeAnimation);
非常感谢您的回答!
答案 0 :(得分:1)
当然,您可以根据使用另一个Style
的第一个来创建另一个Storyboard
...然后您可以在{{1}上应用反向Style
()你想要开始Button
:
Storyboard
我必须完全诚实......我并不完全理解你的问题,所以如果没有回答,似乎你也想知道如何开始<Style x:Key="ReverseMenuItemButtonStyle" TargetType="Button">
<Setter Property="FontSize" Value="60" />
<Setter Property="FontFamily" Value="Segoe" />
<Setter Property="FontWeight" Value="UltraLight" />
<Setter Property="Foreground" Value="#FFEBEDEA" />
<Setter Property="HorizontalContentAlignment" Value="Right" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<ControlTemplate.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard Name="themeUnselectionAnimation">
<DoubleAnimation
Storyboard.TargetName="coloredRectangle"
Storyboard.TargetProperty="Width"
From="30.0"
To="250.0"
Duration="0:0:0.3" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</ControlTemplate.Triggers>
...
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
从视图模型。在这种情况下,您只需要一个Storyboard
属性,该属性将在视图模型中设置为bool
时启动动画。您可以使用true
执行此操作:
DataTrigger.EnterActions
更新&gt;&gt;&gt;
再次......我仍然不知道你在追求什么...我建议在发布另一个问题之前先处理你的问题。但是,我能解决这个问题:
您的 TargetName无法用于Style Setter 错误,并且您希望定位
<Style> <Style.Triggers> <DataTrigger Binding="{Binding SomeBooleanPropertyInViewModel}" Value="True"> <DataTrigger.EnterActions> <BeginStoryboard> <Storyboard ... /> </BeginStoryboard> </DataTrigger.EnterActions> </DataTrigger> </Style.Triggers> </Style>
元素。
此错误的常见修复方法是将coloredRectangle
移动到您尝试定位的元素。所以试试这个:
Trigger