我有一个Stackpanel One,它有一些内容,一个Image和一个defualt隐藏的SubStackpanel。单击图像时,图像应旋转90度,然后向下滑动SubStackpanel。 再次单击图像时,图像应旋转回原始位置,SubStackpanel应向上滑动到默认隐藏位置。
我几乎让这个工作,问题是我不知道如何在两个不同的Storyboard动画上使用相同的Trigger事件。因此,每次单击图像时,只会出现按钮上的第一个动画和SubStackpanel。 我尝试了AutoReverse属性,但在动画完成后会立即触发。当然,这应该仅在用户第二次单击Image时发生。
我想实现这一点,只使用标记。
这是我目前的代码:
<Grid>
<StackPanel Grid.Row="0" Orientation="Vertical" Background="Beige" >
<StackPanel.Triggers>
<EventTrigger SourceName="ImageShowPanelTwo" RoutedEvent="Image.MouseDown">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="SubPanel" Storyboard.TargetProperty="(StackPanel.Height)" From="0" To="66" Duration="0:0:0.5" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger SourceName="ImageShowPanelTwo" RoutedEvent="Image.MouseDown">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="SubPanel" Storyboard.TargetProperty="(StackPanel.Height)" From="66" To="0" Duration="0:0:0.5" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</StackPanel.Triggers>
<TextBlock>Panel One</TextBlock>
<Image Name="ImageShowPanelTwo" Width="26" Height="26" Source="ImageRotate.png" RenderTransformOrigin=".5,.5" >
<Image.RenderTransform>
<RotateTransform x:Name="AnimatedRotateTransform" Angle="0" />
</Image.RenderTransform>
<Image.Triggers>
<EventTrigger RoutedEvent="Image.MouseDown">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="AnimatedRotateTransform"
Storyboard.TargetProperty="Angle"
By="0"
To="90"
Duration="0:0:0.5"
AutoReverse="True"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="Image.MouseDown">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="AnimatedRotateTransform"
Storyboard.TargetProperty="Angle"
By="90"
To="0"
Duration="0:0:0.5"
AutoReverse="True"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Image.Triggers>
</Image>
<StackPanel Name="SubPanel" Background="LightGreen" Height="66">
<TextBlock>SubPanel</TextBlock>
<TextBlock>SubPanel</TextBlock>
</StackPanel>
</StackPanel>
</Grid>
希望你能提供帮助:)
答案 0 :(得分:4)
Visual Studio的Blend可用于以更好,更简单的方式完成,而无需处理大量代码。
以下是执行此操作的步骤列表。
第1步:在Blend for Visual Studio和Visual Studio中同时打开项目。
第2步:在Blend中,围绕您希望使用它制作动画的所有元素创建一个新的故事板。 我们称之为&#34; Storyboard1&#34;。
第3步:现在,打开我们刚创建的故事板,然后点击&#34; +&#34;旁边的小箭头。然后点击&#34;复制&#34;在下拉菜单中。然后,一个名为&#34; Storyboard1_Copy&#34;的新故事板将被创建。
第4步:将此新故事板重命名为您喜欢的内容,例如&#34; Storyboard1_Rev&#34;。
第5步:你现在必须猜到了。选择重复的故事板,然后从下拉菜单中单击&#34;反向&#34;。
第6步:现在您已准备好两个故事板:一个用于动画一些元素,另一个用于反转动画序列。就像您从C#代码调用故事板一样,您可以根据某些条件调用可逆故事板,这些条件会检查元素是否已经设置了动画。为此,我使用bool变量,每次在一组元素上发生某些动画时,其值都会更改(即,如果元素尚未设置动画,则为false;如果是动画,则为true)。
插图示例:
我将使用简单的布局创建一个应用程序。它在屏幕上有一个按钮,一个图像和一个矩形区域。
这个想法是,无论何时单击按钮一次,图像应该最大化,并且当按下按钮两次时应该最小化回原始尺寸,依此类推。也就是说,每按一次按钮就会发生反向动画。以下是一些屏幕截图,展示了它是如何发生的:
您可以看到图像的当前状态显示在按钮中。它显示&#34;放大&#34;当图像处于其初始的小尺寸时,&#34;缩小&#34;当它最大化时。
最后,这是用于处理按钮点击的C#代码:
bool flag = false;
private void Button_Click(object sender, RoutedEventArgs e)
{
if (!flag)
{
Button.Content = "Zoom Out";
Storyboard1.Begin();
flag = true;
}
else
{
Button.Content = "Zoom In";
Storyboard1_Rev.Begin();
flag = false;
}
}
您所要做的就是拥有一个状态标志,该状态标志显示您希望设置的元素的当前状态,并根据标志的值在正向或反向时间轴中为它们(它们)设置动画。
答案 1 :(得分:0)
而不是尝试使用该事件设置Animation
,而是使用bool
属性来绑定:
<Image Name="ImageShowPanelTwo" Width="26" Height="26" Source="ImageRotate.png"
RenderTransformOrigin=".5,.5" >
<Image.RenderTransform>
<RotateTransform x:Name="AnimatedRotateTransform" Angle="0" />
</Image.RenderTransform>
<Image.Style>
<Style>
<Style.Triggers>
<DataTrigger Binding="{Binding IsRotated}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="AnimatedRotateTransform"
Storyboard.TargetProperty="Angle"
By="0"
To="90"
Duration="0:0:0.5"
AutoReverse="True"/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
<DataTrigger Binding="{Binding IsRotated}" Value="False">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="AnimatedRotateTransform"
Storyboard.TargetProperty="Angle"
By="90"
To="0"
Duration="0:0:0.5"
AutoReverse="True"/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
我相信您可以定义自己的bool
属性,并在每次MouseDown
事件发生时将其反转以完成此功能。设置为true
时,第一个Animation
将开始,当设置为false
时,第二个将开始。
答案 2 :(得分:0)
这就是我解决问题的方法:
为Stackpanel和箭头创建了四个故事板:
<Storyboard x:Key="RotateIconUp">
<DoubleAnimation Storyboard.TargetName="IconExpand" Storyboard.TargetProperty="(TextBlock.RenderTransform).(RotateTransform.Angle)" From="0" To="90" Duration="0:0:0.4" />
</Storyboard>
<Storyboard x:Key="RotateIconDown">
<DoubleAnimation Storyboard.TargetName="IconExpand" Storyboard.TargetProperty="(TextBlock.RenderTransform).(RotateTransform.Angle)" From="90" To="0" Duration="0:0:0.4" />
</Storyboard>
<Storyboard x:Key="SlideGridDown">
<DoubleAnimation Storyboard.TargetName="GridDetails" Storyboard.TargetProperty="(Grid.Height)" From="0" To="180" Duration="0:0:0.4" />
</Storyboard>
<Storyboard x:Key="SlideGridUp">
<DoubleAnimation Storyboard.TargetName="GridDetails" Storyboard.TargetProperty="(Grid.Height)" From="180" To="0" Duration="0:0:0.4" />
</Storyboard>
然后,当点击箭头时,我会从代码隐藏中触发故事板:
private void ExpandDetails() {
try {
if (!pm_IsExanded) {
Storyboard Storyboard = (Storyboard)FindResource("RotateIconUp");
Storyboard.Begin(this);
Storyboard = (Storyboard)FindResource("SlideGridDown");
Storyboard.Begin(this);
pm_IsExanded = true;
BorderMain.BorderBrush = pm_BrushConverter.ConvertFromString("#000000") as Brush;
} else {
Storyboard Storyboard = (Storyboard)FindResource("RotateIconDown");
Storyboard.Begin(this);
Storyboard = (Storyboard)FindResource("SlideGridUp");
Storyboard.Begin(this);
pm_IsExanded = false;
BorderMain.BorderBrush = pm_BrushConverter.ConvertFromString("#d0d0d0") as Brush;
}
} catch (Exception ee) {
GlobalResource.WriteToLog("Error in ExpandDetails", ee);
}
}