我的组合框在我的应用程序中就像扩展器一样。当我需要折叠组合框时,我将其高度设置为0.当我需要展开它时,我将它的高度设置为auto(double.Nan)是否可以用故事板来完成。我怎么能提前知道自动高度。表达式混合不能使我动画为自动。
答案 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 个非阻塞问题:
<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>
直到现在,这个问题似乎还没有完美而简单的解决方案......