实现"滑下"动画在WPF [英] Achieve "slide down" animation in WPF

查看:468
本文介绍了实现"滑下"动画在WPF的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图创建自己的一个扩展控件模板。当控制展开,我想要的内容慢慢滑下。

内容的理想高度是不是在编译时已知。

我想我们可以定义上下滑动作为一个动画:

 <情节提要X:键=ExpandContent>    < D​​oubleAnimation是
        Storyboard.TargetName =_ expanderContent
        Storyboard.TargetProperty =高度
        从=0.0
        为了={绑定的ElementName = _expanderContent,路径= DesiredHeight}
        持续时间=0:0:1.0/>
< /故事板>

但遗憾的是没有。我们得到一个错误


  

不能冻结这个故事板时间表树跨线程使用。


看来,定义动画参数时,我们不能用绑定。 (还讨论了<一个href=\"http://stackoverflow.com/questions/1669750/wpf-animation-cannot-freeze-this-storyboard-timeline-tree-for-use-across-thread\">this问题。)

有谁会对我怎么能处理这个任何想法?我警惕使用 LayoutTransform.ScaleY 的,因为这会造成图像失​​真。

这是类似于<一个href=\"http://stackoverflow.com/questions/5035174/how-to-get-desired-height-of-wpf-ui-element-with-current-height-of-0\">this问题,但这个问题已经涉及到写作code-背后的答案,我不认为是可能的控件模板。
我想知道如果一个基于XAML的解决方案是可以实现的。



对于它的价值,这是我的控件模板的当前状态。

 &LT;控件模板X:键=ExpanderControlTemplate的TargetType ={X:类型扩展}&GT;
    &LT; ControlTemplate.Resources&GT;
            &LT;! - 这里是不工作的故事板 - &GT;
            &LT;情节提要X:键=ExpandContent&GT;                &LT; D​​oubleAnimation是
                    Storyboard.TargetName =_ expanderContent
                    Storyboard.TargetProperty =高度
                    从=0.0
                    为了={绑定的ElementName = _expanderContent,路径= DesiredHeight}
                    持续时间=0:0:1.0/&GT;
            &LT; /故事板&GT;
            &LT;情节提要X:键=ContractContent&GT;                &LT; D​​oubleAnimation是
                    Storyboard.TargetName =_ expanderContent
                    Storyboard.TargetProperty =高度
                    从={绑定的ElementName = _expanderContent,路径= DesiredHeight}
                    为了=0.0
                    持续时间=0:0:1.0/&GT;            &LT; /故事板&GT;
        &LT; /ControlTemplate.Resources>
    &LT;电网NAME =MainGrid背景=白&GT;
        &LT; Grid.RowDefinitions&GT;
            &LT; RowDefinition高度=自动/&GT;
            &LT; RowDefinition NAME =ContentRowHEIGHT =自动/&GT;
        &LT; /Grid.RowDefinitions>
        &LT; Grid.ColumnDefinitions&GT;
            &所述; ColumnDefinition宽度=*/&GT;
        &LT; /Grid.ColumnDefinitions>
        &LT; BORDER&GT;
            &LT;网格和GT;
                &LT; Grid.ColumnDefinitions&GT;
                    &所述; ColumnDefinition宽度=*/&GT;
                    &LT; ColumnDefinition WIDTH =自动/&GT;
                &LT; /Grid.ColumnDefinitions>
                &lt;内容presenter ContentSource =头文件/&GT;
                &LT;切换按钮模板={StaticResource的ProductButtonExpand}
                              Grid.Column =1
                              器isChecked ={绑定路径= IsExpanded,模式=双向,的RelativeSource = {的RelativeSource TemplatedParent}}
                              /&GT;
                &LT;矩形Grid.ColumnSpan =2填写=#FFDADADAHEIGHT =1保证金=8,0,8,2VerticalAlignment =底/&GT;            &LT; /网格和GT;
        &LT; /边框&GT;            &lt;内容presenter Grid.Row =1的Horizo​​ntalAlignment =弹力名称=_ expanderContent&GT;            &LT; /内容presenter&GT;    &LT; /网格和GT;
    &LT; ControlTemplate.Triggers&GT;
        &LT;触发属性=IsExpandedVALUE =真&GT;
            &LT;二传手的TargetName =_ expanderContent属性=高度值={绑定的ElementName = _expanderContent,路径= DesiredHeight}/&GT;                &LT;! - 这里是哪里,如果他们做了工作,我会激活故事板 - &GT;
                &LT; Trigger.EnterActions&GT;
                &LT;! - &LT; BeginStoryboard故事板={StaticResource的ExpandContent}/&GT; - &GT;
            &LT; /Trigger.EnterActions>
                &LT; Trigger.ExitActions&GT;
                    !&LT; - &LT; BeginStoryboard X:NAME =ContractContent_BeginStoryboard故事板={StaticResource的ContractContent}/&GT; - &GT;
                &LT; /Trigger.ExitActions>
        &LT; /触发&GT;
            &LT;触发属性=IsExpandedVALUE =FALSE&GT;                &LT;二传手的TargetName =_ expanderContent属性=高度值=0/&GT;
            &LT; /触发&GT;
        &LT; /ControlTemplate.Triggers>&LT; /控件模板&GT;


解决方案

如果的你可以使用交互 FluidLayout 混合4 SDK )你很幸运,这对那些花哨的东西动画真正有用的。

首先设置内容CP的高度为0:

 &lt;内容presenter Grid.Row =1
    的Horizo​​ntalAlignment =弹力
    X:名称=_ expanderContent
    高度=0/&GT;

要动画这一点,身高只需将动画到 NaN的的VisualState 的再presents展开状态(非离散的动画不会让你使用 NaN的

 的xmlns:是=htt​​p://schemas.microsoft.com/ex$p$pssion/2010/interactions

 &LT;电网X:NAME =MainGrid背景=白&GT;
    &LT; VisualStateManager.CustomVisualStateManager&GT;
        &LT是:ExtendedVisualStateManager /&GT;
    &LT; /VisualStateManager.CustomVisualStateManager>
    &LT; VisualStateManager.VisualStateGroups&GT;
        &LT; VisualStateGroup X:NAME =ExpansionStates是:ExtendedVisualStateManager.UseFluidLayout =真&GT;
            &LT; VisualStateGroup.Transitions&GT;
                &所述; VisualTransition GeneratedDuration =0:0:1/&GT;
            &LT; /VisualStateGroup.Transitions>
            &LT;的VisualState X:名称=膨胀&GT;
                &LT;情节提要&GT;
                    &LT; D​​oubleAnimationUsingKeyFrames Storyboard.TargetProperty =(FrameworkElement.Height)
                                                   Storyboard.TargetName =_ expanderContent&GT;
                        &LT; D​​iscreteDoubleKeyFrame KeyTime =0值=南/&GT;
                    &LT; / DoubleAnimationUsingKeyFrames&GT;
                &LT; /故事板&GT;
            &LT; /&的VisualState GT;
            &LT;的VisualState X:NAME =折叠/&GT;
        &LT; / VisualStateGroup&GT;
    &LT; /VisualStateManager.VisualStateGroups>
    &LT;! - ... - &GT;

这应该是一切必要,流体布局将在那里为你创造的转变。<​​/ P>


如果你有一个code-背后的解决方案,将被罚款,你甚至可以用code-背后词典是这样的:

 &LT;! -  TestDictionary.xaml  - &GT;
&LT; ResourceDictionary的X:类=Test.TestDictionary
                    ...&GT;

  // TestDictionary.xaml.cs
使用系统;
使用System.Collections.Generic;
使用System.Linq的;
使用System.Text;
使用System.Windows;命名空间测试
{
    部分类TestDictionary:ResourceDictionary中
    {
        //处理程序和在这里等
    }
}

I am attempting to create my own template for an Expander control. When the control is expanded, I want the content to slide down slowly.

The desired height of the content is not known at compile time.

I thought we could define the slide down as an animation:

<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>

But Unfortunately not. We get an error

Cannot freeze this Storyboard timeline tree for use across threads.

It appears that we cannot use binding when defining animation parameters. (Discussed also in this question.)

Does anyone have any ideas on how I can approach this? I'm wary of using LayoutTransform.ScaleY, because that would create a distorted image.

This is similar to this question, but this question has an answer involved writing code-behind, which I don't think is possible in a control template. I'm wondering if a XAML-based solution is achievable.


For what it's worth, here is the current state of my control template.

<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>

解决方案

If you can use Interactions with FluidLayout (Blend 4 SDK) you are in luck, it's really useful for those fancy animation things.

First set the content CP's Height to 0:

<ContentPresenter Grid.Row="1"
    HorizontalAlignment="Stretch"
    x:Name="_expanderContent"
    Height="0"/>

To animate this, the Height just needs to be animated to NaN in the VisualState that represents the expanded state (non-discrete animations would not let you use NaN):

xmlns:is="http://schemas.microsoft.com/expression/2010/interactions"

<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>
    <!-- ... --->

That should be all that is necessary, the fluid layout will create the transition for you from there.


If you have a code-behind solution that would be fine, you can even use code-behind in dictionaries like this:

<!-- TestDictionary.xaml -->
<ResourceDictionary x:Class="Test.TestDictionary"
                    ...>

//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
    }
}

这篇关于实现&QUOT;滑下&QUOT;动画在WPF的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆