简体   繁体   English

在SizeChanged事件上调整动画大小无法正常工作

[英]Resizing animation on SizeChanged event doesn't work as it should

I want a resizing animation when stackpanel visibility is set to visible state, but instead of that, I'm getting neverending flickering of border containing stackpanel.I don't think I'm doing it wrong. 我希望在将StackPanel的可见性设置为可见状态时调整动画大小,但与此相反,我变得无休止地闪烁了包含StackPanel的边框。我认为我做错了。 Stack panel contains an instance of TextBlock. 堆栈面板包含TextBlock的实例。

private void MyBorder_SizeChanged_1(object sender, SizeChangedEventArgs e)
{
    if (!first)
    {
        DoubleAnimation anim = new DoubleAnimation();
        anim.From = e.PreviousSize.Height;
        anim.To = e.NewSize.Height;
        anim.Duration = new Duration(TimeSpan.FromSeconds(1));
        Storyboard.SetTarget(anim, MyBorder);
        Storyboard.SetTargetProperty(anim, new PropertyPath(Border.HeightProperty));
        Storyboard st = new Storyboard();
        st.Children.Add(anim);
        st.Begin();
    }
    first = false;
}

private void MyBorder_Tap_1(object sender, GestureEventArgs e)
{
    if (MyPanel.Visibility == Visibility.Collapsed)
        MyPanel.Visibility = Visibility.Visible;
    else
        MyPanel.Visibility = Visibility.Collapsed;
}

The problem is that when you animate the height of the border it will trigger the SizeChanged event so you have a loop: size changed event>animate height>size changed event> .. 问题在于,当对边框的高度进行动画处理时,它将触发SizeChanged事件,因此会产生一个循环:大小更改事件>动画高度>大小更改事件>。
Also when the sized changed event is fired, the size change has already taken placed so even if that was working you will get a little flicking when it go back to do the animation. 同样,在触发了大小更改事件时,大小更改已被放置,因此即使该大小可行,当您返回动画时,您也会有一些轻弹。
Finally using HEight in an animation force a rendering update so that is not hardware accelerated. 最后,在动画中使用HEight会强制进行渲染更新,因此不会硬件加速。 Probably the best would be to either do a Translate Transform or a Scale Transform. 最好的办法是执行“转换”变换或“缩放”变换。
For exemple you could do a scale transform between 0 and 1 directly on MyPanel in the tap event. 例如,您可以在tap事件中直接在MyPanel上进行0到1之间的比例转换。

This might help you to. 这可能会帮助您。 It is a work around 这是一个变通

private void MyBorder_SizeChanged_1(object sender, SizeChangedEventArgs e)
    {
        if (!first)
        {
            DoubleAnimation anim = new DoubleAnimation();
            anim.From = e.PreviousSize.Height;
            anim.To = e.NewSize.Height;
            anim.Duration = new Duration(TimeSpan.FromSeconds(1));
            Storyboard.SetTarget(anim, MyBorder);
            Storyboard.SetTargetProperty(anim, new PropertyPath(Border.HeightProperty));
            Storyboard st = new Storyboard();
            st.Children.Add(anim);
            st.Completed += st_Completed;
            MyBorder.SizeChanged -= MyBorder_SizeChanged_1;
            st.Begin();

        }
        first = false;
    }

    void st_Completed(object sender, EventArgs e)
    {
        MyBorder.SizeChanged += MyBorder_SizeChanged_1;
    }

    private void MyBorder_Tap_1(object sender, GestureEventArgs e)
    {
        if (MyPanel.Visibility == Visibility.Collapsed)
            MyPanel.Visibility = Visibility.Visible;
        else
            MyPanel.Visibility = Visibility.Collapsed;


    }

With reference to the fact that border is getting resized even in the storyboard its better to remove the event of size changed. 考虑到即使在情节提要中,边框的大小都已调整,因此最好删除大小更改的事件。 Try animating the parent container on chld size changed some thing kind of this 尝试对chld大小的父容器进行动画处理,从而改变了这种情况

I've solved this problem. 我已经解决了这个问题。 Silly my, I thought that Measure method of StackPanel is private, and didn't bother to make sure about it, here's solution code for expanding StackPanel on Click. 愚蠢的我,我认为StackPanel的Measure方法是私有的,并且不必费心去确保它,这是在Click上扩展StackPanel的解决方案代码。

 private void MyBorder_Tap_1(object sender, GestureEventArgs e) { if (MyPanel.Visibility == Visibility.Collapsed) { MyPanel.Visibility = Visibility.Visible; MyPanel.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity)); DoubleAnimation anim = new DoubleAnimation(); anim.From = MyBorder.ActualHeight; anim.To = MyBorder.ActualHeight + MyPanel.DesiredSize.Height; anim.Duration = new Duration(TimeSpan.FromSeconds(0.25)); Storyboard.SetTarget(anim, MyBorder); Storyboard.SetTargetProperty(anim, new PropertyPath(Border.HeightProperty)); Storyboard st = new Storyboard(); st.Children.Add(anim); st.Begin(); } else { MyPanel.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity)); DoubleAnimation anim = new DoubleAnimation(); anim.From = MyBorder.ActualHeight; anim.To = MyBorder.ActualHeight - MyPanel.DesiredSize.Height; anim.Duration = new Duration(TimeSpan.FromSeconds(0.25)); Storyboard.SetTarget(anim, MyBorder); Storyboard.SetTargetProperty(anim, new PropertyPath(Border.HeightProperty)); Storyboard st = new Storyboard(); st.Children.Add(anim); st.Completed += (a,b) => { MyPanel.Visibility = Visibility.Collapsed; }; st.Begin(); } } 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM