在该行的内容上运行动画时如何更新外部控件高度?

发布于 2025-01-02 00:47:01 字数 1484 浏览 2 评论 0原文

目前我有一个 ControlTemplate,我正在尝试添加滑动动画。当我运行动画时,它运行得很好,除了当我缩小内容时,我希望它的父容器也缩小。

目前我要缩小的控件位于堆栈面板内部,我还尝试将其放入网格中并将其 RowDefinition 设置为自动,但是当内容缩小时,外部控件在两种情况下都保持相同的大小。

这就是我目前正在做的事情。动画工作正常,它的外部堆栈面板没有调整大小。值得注意的是,这只是问题的细节,堆栈面板实际上包含其他内容,所以我不能只在根上运行动画。

<StackPanel x:Name="_root">

<StackPanel.Resources>
    <Storyboard x:Key="_expand">
        <DoubleAnimation
            Duration="0:0:0.25"
            From="0"
            To="1" 
            Storyboard.TargetName="_borderContent"
            Storyboard.TargetProperty="(FrameworkElement.RenderTransform).(ScaleTransform.ScaleY)"
            />
    </Storyboard>
    <Storyboard x:Key="_collapse" >
        <DoubleAnimation
            Duration="0:0:0.25" 
            From="1"
            To="0" 
            Storyboard.TargetName="_borderContent"
            Storyboard.TargetProperty="(FrameworkElement.RenderTransform).(ScaleTransform.ScaleY)"
            />
    </Storyboard>
</StackPanel.Resources>



<Border 
    x:Name="_borderContent"
    Grid.Row="1" BorderBrush="{TemplateBinding ExpandStroke}" BorderThickness="1" >

    <Border.RenderTransform>
        <ScaleTransform ScaleX="1" ScaleY="1"/>
    </Border.RenderTransform>
    <!-- Contains the Content to be presented in the card-->
    <ContentPresenter x:Name="_content">
    </ContentPresenter>



</Border>
</StackPanel>

Currently I have a ControlTemplate I am trying to add a sliding animation to. When I run the animation it runs fine other than when I scale the content down I would like its parent container to scale down as well.

currently the control I am scaling down is inside of a stackpanel, I have also tried putting it in a Grid and Setting its RowDefinition to Auto, but when the content gets scaled down I am left with the outer control staying the same size in both cases.

Here is what I am curretly doing. the animations work fine, its the outer stackpanel thats not resizing. Its worth noting this is just the details of the problem, the stack panel actually contains other content so I can't just run the animation on the root.

<StackPanel x:Name="_root">

<StackPanel.Resources>
    <Storyboard x:Key="_expand">
        <DoubleAnimation
            Duration="0:0:0.25"
            From="0"
            To="1" 
            Storyboard.TargetName="_borderContent"
            Storyboard.TargetProperty="(FrameworkElement.RenderTransform).(ScaleTransform.ScaleY)"
            />
    </Storyboard>
    <Storyboard x:Key="_collapse" >
        <DoubleAnimation
            Duration="0:0:0.25" 
            From="1"
            To="0" 
            Storyboard.TargetName="_borderContent"
            Storyboard.TargetProperty="(FrameworkElement.RenderTransform).(ScaleTransform.ScaleY)"
            />
    </Storyboard>
</StackPanel.Resources>



<Border 
    x:Name="_borderContent"
    Grid.Row="1" BorderBrush="{TemplateBinding ExpandStroke}" BorderThickness="1" >

    <Border.RenderTransform>
        <ScaleTransform ScaleX="1" ScaleY="1"/>
    </Border.RenderTransform>
    <!-- Contains the Content to be presented in the card-->
    <ContentPresenter x:Name="_content">
    </ContentPresenter>



</Border>
</StackPanel>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

秋风の叶未落 2025-01-09 00:47:01

我在您发布的 XAML 中没有看到任何与您的堆栈面板有关的内容..

这是我拥有的一些内容,也许您可​​以将其用作模板..或尝试指南
我知道它不会与您的相同,但我确信您可能会在我的模板中看到您缺少的某些内容。

<ControlTemplate TargetType="ListBoxItem">
    <Border x:Name="LayoutRoot" Margin="0,10,0,10" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}">
        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="CommonStates">
                <VisualState x:Name="Normal"/>
                <VisualState x:Name="MouseOver"/>
                <VisualState x:Name="Disabled">
                    <Storyboard>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="LayoutRoot">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource TransparentBrush}"/>
                        </ObjectAnimationUsingKeyFrames>
                        <DoubleAnimation Duration="0" To=".5" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="ContentContainer"/>
                    </Storyboard>
                </VisualState>
            </VisualStateGroup>
            <VisualStateGroup x:Name="SelectionStates">
                <VisualState x:Name="Unselected"/>
                <VisualState x:Name="Selected">
                    <Storyboard>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentContainer">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneAccentBrush}"/>
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="Panel">
                            <DiscreteObjectKeyFrame KeyTime="0">
                                <DiscreteObjectKeyFrame.Value>
                                    <SolidColorBrush Color="Azure"/>
                                </DiscreteObjectKeyFrame.Value>
                            </DiscreteObjectKeyFrame>
                        </ObjectAnimationUsingKeyFrames>
                        <DoubleAnimation Storyboard.TargetProperty="Opacity" Storyboard.TargetName="Top" To="0"/>
                        <DoubleAnimation Storyboard.TargetProperty="Opacity" Storyboard.TargetName="Bottom" To="0"/>
                    </Storyboard>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>
        <StackPanel>
          <Rectangle x:Name="Top" Fill="Aquamarine" Height="20"/>
             <StackPanel x:Name="Panel" Orientation="Horizontal" Background="CadetBlue">
                <Image Source="logo.png" Stretch="None"/>
                <ContentControl Margin="10" x:Name="ContentContainer" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"  VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
          </StackPanel>
          <Rectangle x:Name="Bottom" Fill="Aquamarine" Height="20"/>
        </StackPanel>
    </Border>
</ControlTemplate>

I don't see anything in regards to your stackpanel in the XAML that you have posted..

here is something of what I have that perhaps you could use as a Template.. or guide to try
I know that it will not be the same as yours but I am sure that there is something here that you are missing that you may see in my template.

<ControlTemplate TargetType="ListBoxItem">
    <Border x:Name="LayoutRoot" Margin="0,10,0,10" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}">
        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="CommonStates">
                <VisualState x:Name="Normal"/>
                <VisualState x:Name="MouseOver"/>
                <VisualState x:Name="Disabled">
                    <Storyboard>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="LayoutRoot">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource TransparentBrush}"/>
                        </ObjectAnimationUsingKeyFrames>
                        <DoubleAnimation Duration="0" To=".5" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="ContentContainer"/>
                    </Storyboard>
                </VisualState>
            </VisualStateGroup>
            <VisualStateGroup x:Name="SelectionStates">
                <VisualState x:Name="Unselected"/>
                <VisualState x:Name="Selected">
                    <Storyboard>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentContainer">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneAccentBrush}"/>
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="Panel">
                            <DiscreteObjectKeyFrame KeyTime="0">
                                <DiscreteObjectKeyFrame.Value>
                                    <SolidColorBrush Color="Azure"/>
                                </DiscreteObjectKeyFrame.Value>
                            </DiscreteObjectKeyFrame>
                        </ObjectAnimationUsingKeyFrames>
                        <DoubleAnimation Storyboard.TargetProperty="Opacity" Storyboard.TargetName="Top" To="0"/>
                        <DoubleAnimation Storyboard.TargetProperty="Opacity" Storyboard.TargetName="Bottom" To="0"/>
                    </Storyboard>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>
        <StackPanel>
          <Rectangle x:Name="Top" Fill="Aquamarine" Height="20"/>
             <StackPanel x:Name="Panel" Orientation="Horizontal" Background="CadetBlue">
                <Image Source="logo.png" Stretch="None"/>
                <ContentControl Margin="10" x:Name="ContentContainer" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"  VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
          </StackPanel>
          <Rectangle x:Name="Bottom" Fill="Aquamarine" Height="20"/>
        </StackPanel>
    </Border>
</ControlTemplate>
娇妻 2025-01-09 00:47:01

这花了一点时间,但我必须回到之前的工作方式。我更改了动画以处理高度而不是缩放变换。 ScaleTransform 的问题在于它保留了控件空间,因此其父控件实际上不会更新。

更新高度时,如果高度设置为 Double.NaN 动画将不起作用,因为它不知道如何将动画设置为 Double.NaN

要解决这个问题,我实际上从模板中提取了动画,并分配其值到后面代码中的控件实际高度。

public override OnApplyTemplate()
{
    //in the onapplytemplate overried
    _collapseHeightAnimation = (DoubleAnimation) GetTemplateChild("_collapseHeightAnimation");
    _expandHeightAnimation = (DoubleAnimation) GetTemplateChild("_expandHeightAnimation");

    //get controls for updating heights and angles once we know what that information will be
    var contentBorder = (Border) GetTemplateChild("_borderContent");

}

public void ContentBorderSizeChanged(object sender, SizeChangedEventHandler e)
{
    //once the size of my control has been determined
    // can set to and from values that weren't available before
    // in this case this happens in the size change event
    _collapseHeightAnimation.From = contentBorder.ActualHeight;
    _expandHeightAnimation.To = contentBorder.ActualHeight;
}

It took a little bit but I had to go back to how I was working with it before. I changed the animation to work on the Height instead of a ScaleTransform. The problem with the ScaleTransform is that it reserves the controls space so its parent control wont actually update.

when updating the height, if the height was set to Double.NaN the animation wouldn't work because it doesn't know how to animate to Double.NaN

To fix that I actually pull out the animations from the template, and assign its values to the controls actualheight in the code behind.

public override OnApplyTemplate()
{
    //in the onapplytemplate overried
    _collapseHeightAnimation = (DoubleAnimation) GetTemplateChild("_collapseHeightAnimation");
    _expandHeightAnimation = (DoubleAnimation) GetTemplateChild("_expandHeightAnimation");

    //get controls for updating heights and angles once we know what that information will be
    var contentBorder = (Border) GetTemplateChild("_borderContent");

}

public void ContentBorderSizeChanged(object sender, SizeChangedEventHandler e)
{
    //once the size of my control has been determined
    // can set to and from values that weren't available before
    // in this case this happens in the size change event
    _collapseHeightAnimation.From = contentBorder.ActualHeight;
    _expandHeightAnimation.To = contentBorder.ActualHeight;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文