组框的动画高度从0到auto

时间:2011-07-02 00:46:45

标签: c# wpf xaml animation storyboard

我的组合框在我的应用程序中就像扩展器一样。当我需要折叠组合框时,我将其高度设置为0.当我需要展开它时,我将它的高度设置为auto(double.Nan)是否可以用故事板来完成。我怎么能提前知道自动高度。表达式混合不能使我动画为自动。

enter image description here

3 个答案:

答案 0 :(得分:20)

由于我讨厌规模转换,因为我发现它很丑,我寻找另一种解决方案。

嗯,我知道这是一个很老的帖子,并且存在很多变通方法,但是我很简单,即使有人确实找到它,我也没有在其他地方读过它。
您可以将高度设置为Auto并为Auto属性设置动画,而不是将高度从X设置为MaxHeight(这是不可能的):

<MyControl x:Name="ctrlAutoHeight" Height="Auto">
    <MyControl.Triggers>
        <EventTrigger RoutedEvent="myRoutedEvent">
            <BeginStoryboard>
                <Storyboard>
                    <DoubleAnimation 
                        Storyboard.TargetName="ctrlAutoHeight" 
                        Storyboard.TargetProperty="MaxHeight"
                        From="0.0" 
                        To="{Binding ElementName=ParentControl, Path=ActualHeight}"
                        Duration="0:0:1" 
                        AutoReverse="False"
                        />
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </MyControl.Triggers>
</MyControl>

答案 1 :(得分:7)

您可以将ScaleTransform用于此

<GroupBox Header="GroupBox">
    <GroupBox.RenderTransform>
        <ScaleTransform ScaleY="1"/>
    </GroupBox.RenderTransform>
</GroupBox>

折叠时,groupbox将ScaleTransform.ScaleX设置为0.当展开设置为1时。

答案 2 :(得分:0)

这是一个基于 StackPanel 的现成示例(您可以随意将其替换为 GroupBox)。

对于那些具有 «InvalidOperationException:无法冻结此 Storyboard 时间轴树以供跨线程使用。» 的情况,当在 Storyboard 中定义绑定时会发生此异常,而 Storyboard 本身在 ControlTemplate 或 Style 中定义。 在某种程度上,冻结动画是所有值都是静态的(假设是预先计算的)。

只是感觉问题,想象一下在动画过程中 StackPanel 正在添加或删除一些控件,理论上要成功实现这个动画,动画引擎应该考虑这些变化(通过绑定), 但不幸的是,WPF 实际上并不支持这种情况。

回到下面的解决方案,请注意我使用的是任何 ControlTemplate 或 Style 之外的绑定。 在这种情况下,动画参数在事件触发时计算,但一旦播放,当绑定属性改变时它们不会更新。

因此,此解决方案(除非其他解决方案)存在 2 个非阻塞问题:

  1. 在动画结束时,如果 StackPanel 内容在动画期间发生变化,则 StackPanel 的大小可能会出错
  2. 在 CheckBox 上快速单击几次时,无论剩余空间如何折叠或展开,动画持续时间将始终相同
<StackPanel>

    <!-- CheckBox used for triggering the StackPanel animation -->
    <CheckBox Content="Expand/Collapse">
        <CheckBox.Triggers>
            <EventTrigger RoutedEvent="CheckBox.Checked">
                <!-- Expand animation -->
                <BeginStoryboard>
                    <Storyboard>
                        <DoubleAnimation Storyboard.TargetName="StackPanel" 
                                         Storyboard.TargetProperty="Height"
                                         From="{Binding ElementName=StackPanel, Path=Height}" 
                                         To="{Binding ElementName=ContentSize, Path=DesiredSize.Height}"
                                         Duration="0:0:1" />
                    </Storyboard>
                </BeginStoryboard>
            </EventTrigger>
            <EventTrigger RoutedEvent="CheckBox.Unchecked">
                <!-- Collapse animation -->
                <BeginStoryboard>
                    <Storyboard>
                        <DoubleAnimation Storyboard.TargetName="StackPanel" 
                                         Storyboard.TargetProperty="Height"
                                         From="{Binding ElementName=StackPanel, Path=Height}" 
                                         To="0"
                                         Duration="0:0:1" />
                    </Storyboard>
                </BeginStoryboard>
            </EventTrigger>
        </CheckBox.Triggers>
    </CheckBox>

    <!-- The animated StackPanel -->
    <StackPanel x:Name="StackPanel" Height="0">
        <!-- The border below acts as a probe to get the expected StackPanel container size -->
        <Border x:Name="ContentSize">
            <TextBlock>Some Content</TextBlock>
        </Border>
    </StackPanel>
</StackPanel>

直到现在,这个问题似乎还没有完美而简单的解决方案......

相关问题