And*_*erd 12 wpf animation controltemplate
我正在尝试为Expander控件创建自己的模板.当控件展开时,我希望内容缓慢滑下.
在编译时不知道内容的期望高度.
我以为我们可以将幻灯片定义为动画:
<Storyboard x:Key="ExpandContent">
<DoubleAnimation
Storyboard.TargetName="_expanderContent"
Storyboard.TargetProperty="Height"
From="0.0"
To="{Binding ElementName=_expanderContent,Path=DesiredHeight}"
Duration="0:0:1.0" />
</Storyboard>
Run Code Online (Sandbox Code Playgroud)
但不幸的是没有.我们收到错误
无法冻结此Storyboard时间轴树以跨线程使用.
看来我们在定义动画参数时不能使用绑定.(也在这个问题中讨论过.)
有没有人对我如何处理这个有任何想法?我担心使用LayoutTransform.ScaleY,因为这会产生扭曲的图像.
这与此问题类似,但这个问题的答案涉及编写代码隐藏,我认为在控件模板中是不可能的.我想知道基于XAML的解决方案是否可以实现.
<ControlTemplate x:Key="ExpanderControlTemplate" TargetType="{x:Type Expander}">
<ControlTemplate.Resources>
<!-- Here are the storyboards which don't work -->
<Storyboard x:Key="ExpandContent">
<DoubleAnimation
Storyboard.TargetName="_expanderContent"
Storyboard.TargetProperty="Height"
From="0.0"
To="{Binding ElementName=_expanderContent,Path=DesiredHeight}"
Duration="0:0:1.0" />
</Storyboard>
<Storyboard x:Key="ContractContent">
<DoubleAnimation
Storyboard.TargetName="_expanderContent"
Storyboard.TargetProperty="Height"
From="{Binding ElementName=_expanderContent,Path=DesiredHeight}"
To="0.0"
Duration="0:0:1.0" />
</Storyboard>
</ControlTemplate.Resources>
<Grid Name="MainGrid" Background="White">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Name="ContentRow" Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Border>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<ContentPresenter ContentSource="Header" />
<ToggleButton Template="{StaticResource ProductButtonExpand}"
Grid.Column="1"
IsChecked="{Binding Path=IsExpanded,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}"
/>
<Rectangle Grid.ColumnSpan="2" Fill="#FFDADADA" Height="1" Margin="8,0,8,2" VerticalAlignment="Bottom"/>
</Grid>
</Border>
<ContentPresenter Grid.Row="1" HorizontalAlignment="Stretch" Name="_expanderContent">
</ContentPresenter>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsExpanded" Value="True">
<Setter TargetName="_expanderContent" Property="Height" Value="{Binding ElementName=_expanderContent,Path=DesiredHeight}" />
<!-- Here is where I would activate the storyboard if they did work -->
<Trigger.EnterActions>
<!--<BeginStoryboard Storyboard="{StaticResource ExpandContent}"/>-->
</Trigger.EnterActions>
<Trigger.ExitActions>
<!--<BeginStoryboard x:Name="ContractContent_BeginStoryboard" Storyboard="{StaticResource ContractContent}"/>-->
</Trigger.ExitActions>
</Trigger>
<Trigger Property="IsExpanded" Value="False">
<Setter TargetName="_expanderContent" Property="Height" Value="0" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
Run Code Online (Sandbox Code Playgroud)
如果你可以用Interactions与FluidLayout(混合4 SDK),你是幸运的,它是为那些花哨的东西动画真正有用的.
首先将内容CP的高度设置为0:
<ContentPresenter Grid.Row="1"
HorizontalAlignment="Stretch"
x:Name="_expanderContent"
Height="0"/>
Run Code Online (Sandbox Code Playgroud)
动画这一点,Height只需要被动画化,以NaN在VisualState代表展开状态(非离散动画不会让你使用NaN):
xmlns:is="http://schemas.microsoft.com/expression/2010/interactions"
Run Code Online (Sandbox Code Playgroud)
<Grid x:Name="MainGrid" Background="White">
<VisualStateManager.CustomVisualStateManager>
<is:ExtendedVisualStateManager/>
</VisualStateManager.CustomVisualStateManager>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="ExpansionStates" is:ExtendedVisualStateManager.UseFluidLayout="True">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0:0:1"/>
</VisualStateGroup.Transitions>
<VisualState x:Name="Expanded">
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Height)"
Storyboard.TargetName="_expanderContent">
<DiscreteDoubleKeyFrame KeyTime="0" Value="NaN"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Collapsed"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<!-- ... --->
Run Code Online (Sandbox Code Playgroud)
这应该是所有必要的,流体布局将为您创造过渡.
如果你有一个很好的代码隐藏解决方案,你甚至可以在这样的字典中使用代码隐藏:
<!-- TestDictionary.xaml -->
<ResourceDictionary x:Class="Test.TestDictionary"
...>
Run Code Online (Sandbox Code Playgroud)
//TestDictionary.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
namespace Test
{
partial class TestDictionary : ResourceDictionary
{
//Handlers and such here
}
}
Run Code Online (Sandbox Code Playgroud)
这是一个古老的问题,但是我今天对此有疑问,所以我认为发布我的解决方案是值得的:
我必须为网格行的Height属性设置动画(上下滑动),但需要动态绑定,以便该行可以再次滑动到与以前相同的位置。
我发现此答案非常有帮助(在毫无成效地与XAML对抗之后):http : //go4answers.webhost4life.com/Question/found-solution-work-protected-override-190845.aspx
有时,在后台代码中执行操作会更简单:
Storyboard sb = new Storyboard();
var animation = new GridLengthAnimation
{
Duration = new Duration(500.Milliseconds()),
From = this.myGridRow.Height,
To = new GridLength(IsGridRowVisible ? GridRowPreviousHeight : 0, GridUnitType.Pixel)
};
// Set the target of the animation
Storyboard.SetTarget(animation, this.myGridRow);
Storyboard.SetTargetProperty(animation, new PropertyPath("Height"));
// Kick the animation off
sb.Children.Add(animation);
sb.Begin();
Run Code Online (Sandbox Code Playgroud)
可以在这里找到GridLengthAnimation类:http : //social.msdn.microsoft.com/forums/en-US/wpf/thread/da47a4b8-4d39-4d6e-a570-7dbe51a842e4/