gpt4 book ai didi

wpf - 在WPF中实现 "slide down"动画

转载 作者:行者123 更新时间:2023-12-04 00:58:59 25 4
gpt4 key购买 nike

我正在尝试为 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>

但不幸的是没有。我们得到一个错误

Cannot freeze this Storyboard timeline tree for use across threads.



看来我们在定义动画参数时不能使用绑定(bind)。 (也在 this question 中讨论过。)

有人对我如何解决这个问题有任何想法吗?我对使用 LayoutTransform.ScaleY 持谨慎态度,因为这会产生扭曲的图像。

这类似于 this question ,但是这个问题的答案涉及编写代码隐藏,我认为这在控制模板中是不可能的。
我想知道是否可以实现基于 XAML 的解决方案。

对于它的值(value),这是我的控制模板的当前状态。
<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>

最佳答案

有一个即用型且仅限 XAML 的解决方案 on CodeProject :

风格:

    <local:MultiplyConverter x:Key="MultiplyConverter" />
<Style TargetType="Expander" x:Key="VerticalSlidingEmptyExpander">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Expander}">
<ScrollViewer x:Name="ExpanderContentScrollView"
HorizontalScrollBarVisibility="Hidden"
VerticalScrollBarVisibility="Hidden"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Top"
>
<ScrollViewer.Tag>
<system:Double>0.0</system:Double>
</ScrollViewer.Tag>
<ScrollViewer.Height>
<MultiBinding Converter="{StaticResource MultiplyConverter}">
<Binding Path="ActualHeight" ElementName="ExpanderContent"/>
<Binding Path="Tag" RelativeSource="{RelativeSource Self}" />
</MultiBinding>
</ScrollViewer.Height>
<ContentPresenter x:Name="ExpanderContent" ContentSource="Content"/>
</ScrollViewer>
<ControlTemplate.Triggers>
<Trigger Property="IsExpanded" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="ExpanderContentScrollView"
Storyboard.TargetProperty="Tag"
To="1"
Duration="0:0:0.2"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="ExpanderContentScrollView"
Storyboard.TargetProperty="Tag"
To="0"
Duration="0:0:0.2"/>
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="Expander" x:Key="HorizontalSlidingEmptyExpander">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Expander}">
<ScrollViewer x:Name="ExpanderContentScrollView"
HorizontalScrollBarVisibility="Hidden"
VerticalScrollBarVisibility="Hidden"
HorizontalContentAlignment="Left"
VerticalContentAlignment="Stretch"
>
<ScrollViewer.Tag>
<system:Double>0.0</system:Double>
</ScrollViewer.Tag>
<ScrollViewer.Width>
<MultiBinding Converter="{StaticResource MultiplyConverter}">
<Binding Path="ActualWidth" ElementName="ExpanderContent"/>
<Binding Path="Tag" RelativeSource="{RelativeSource Self}" />
</MultiBinding>
</ScrollViewer.Width>
<ContentPresenter x:Name="ExpanderContent" ContentSource="Content"/>
</ScrollViewer>
<ControlTemplate.Triggers>
<Trigger Property="IsExpanded" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="ExpanderContentScrollView"
Storyboard.TargetProperty="Tag"
To="1"
Duration="0:0:0.2"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="ExpanderContentScrollView"
Storyboard.TargetProperty="Tag"
To="0"
Duration="0:0:0.2"/>
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

乘法转换器:
public class MultiplyConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType,
object parameter, CultureInfo culture)
{
double result = 1.0;
for (int i = 0; i < values.Length; i++)
{
if (values[i] is double)
result *= (double)values[i];
}

return result;
}

public object[] ConvertBack(object value, Type[] targetTypes,
object parameter, CultureInfo culture)
{
throw new Exception("Not implemented");
}
}

我复制了样式以具有水平和垂直版本并省略了切换按钮,但您可以从原始帖子中轻松获得。

关于wpf - 在WPF中实现 "slide down"动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8221230/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com