Expander展开收缩动画

这个问题困扰了我一天,最后下了个MaterialDesign的demo,看了下他的源码,才恍然大悟,原来很简单。

我原来的设想是在expander的ControlTemplate设置触发器,在IsExpanded属性变化时根据ContentPresenter控件的高度来做动画,但这就涉及到取属性,在xaml中只有绑定。

但一绑定就报错无法冻结此 Storyboard 时间线树供跨线程使用

说实话绑定高度是我们的自然想法,结果MaterialDesign居然使用LayoutTransform缩放来做的动画,这个就不需要属性值了呀,直接指定比例就行了,避开了绑定。

他的源代码时这样写的

......
<Border Name="ContentSite">
  <Border.LayoutTransform>
    <TransformGroup>
      <ScaleTransform x:Name="ContentSiteScaleTransform" />
      <RotateTransform Angle="{Binding Path=ExpandDirection, RelativeSource={RelativeSource AncestorType=Expander}, Converter={StaticResource ExpanderRotateAngleConverter}}" />
    </TransformGroup>
  </Border.LayoutTransform>

  <Grid Name="ContentPanel"
        Margin="{TemplateBinding Padding}"
        HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
        VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
    <Grid.LayoutTransform>
      <RotateTransform Angle="{Binding Path=ExpandDirection, RelativeSource={RelativeSource AncestorType=Expander}, Converter={StaticResource ExpanderRotateAngleConverter}, ConverterParameter=-1}" />
    </Grid.LayoutTransform>

    <ContentPresenter Name="PART_Content"
                      ContentStringFormat="{TemplateBinding ContentStringFormat}"
                      ContentTemplate="{TemplateBinding ContentTemplate}"
                      ContentTemplateSelector="{TemplateBinding ContentTemplateSelector}"
                      Focusable="False"
                      Visibility="Collapsed" />

  </Grid>
</Border>
......
<VisualTransition To="Expanded">
  <Storyboard>
    <DoubleAnimation Storyboard.TargetName="ContentPanel"
                     Storyboard.TargetProperty="Opacity"
                     From="0"
                     To="1"
                     Duration="{DynamicResource ExpandDuration}" />
    <DoubleAnimation Storyboard.TargetName="ContentSiteScaleTransform"
                     Storyboard.TargetProperty="(ScaleTransform.ScaleY)"
                     From="0"
                     To="1"
                     Duration="{DynamicResource ExpandDuration}">
      <DoubleAnimation.EasingFunction>
        <CubicEase EasingMode="EaseInOut" />
      </DoubleAnimation.EasingFunction>
    </DoubleAnimation>
    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_Content"
                                   Storyboard.TargetProperty="Visibility"
                                   Duration="0:0:0">
      <DiscreteObjectKeyFrame KeyTime="0%" Value="{x:Static Visibility.Visible}" />
    </ObjectAnimationUsingKeyFrames>
  </Storyboard>
</VisualTransition>

吐血三升!

posted @ 2024-04-14 10:47  ggtc  阅读(51)  评论(0)    收藏  举报
//右下角目录