• 【WPF】实现QQ中的分组面板(2)——添加动画


    在上一篇中,介绍了如何实现类似QQ中分组面板的功能。这一次将介绍如何用另一种方式实现这个功能,并添加动画效果。

    在上一篇所介绍的方式中,主要的技术点其实就是那个作为ItemsPanel的自定义Panel。然而这种实现方式有两个主要缺点。

    1.       没有了Virtualizing的效果。虽然没有不可见项。

    2.       不便于添加动画效果。

    这里将向大家介绍另一种实现方式。就是用Blend 3中非常火爆的Behavior来实现,并且可以很容易地添加上动画效果。

    这个Behavior原理很简单,就是动态地计算ListBoxItem的高度。这就要求:

    1.       不能为ListBoxItem指定各不相同的高度。

    2.       要为每个Item指定一个默认的收缩时的高度。

    Rooijakkers的博客上介绍了类似的用高度的方法。不过上面的方法没有充分利用WPF的特性,写了一些不必要的逻辑,比如控件ExpanderIsExpanded属性。而且没有动画的支持。

    这里使用Behavior简单步骤就是,添加一个用于ListBox的自定义Behavior,然后在ListBoxSelectionChanged事件中去设置每个Item的高度。用Storyboard就可以很容易地实现动画效果。

    这个Behavior有两个自定义属性。一个是DefaultHeight,一个是AnimationDuration。顾名思义,不解释了。核心代码如下所示。

    Core Logic
    private void OnAssociatedObjectSelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        
    double selectedItemFinalHeight = AssociatedObject.ActualHeight;

        Storyboard storyBoard 
    = new Storyboard();

        
    for (int i = 0; i < AssociatedObject.Items.Count; i++)
        {
            ListBoxItem item 
    = AssociatedObject.ItemContainerGenerator.ContainerFromIndex(i) as ListBoxItem;
            
    if (!item.IsSelected)
            {
                selectedItemFinalHeight 
    -= DefaultHeight;

                DoubleAnimation heightAnimation 
    = new DoubleAnimation()
                {
                    To 
    = DefaultHeight,
                    Duration 
    = new Duration(new TimeSpan(0000, AnimationDuration))
                };
                Storyboard.SetTarget(heightAnimation, item);
                Storyboard.SetTargetProperty(heightAnimation, 
    new PropertyPath(FrameworkElement.HeightProperty));
                storyBoard.Children.Add(heightAnimation);
            }
        }

        
    // The Padding of the ListBox.
        selectedItemFinalHeight -= 4;

        
    if (AssociatedObject.SelectedIndex >= 0)
        {
            ListBoxItem selectedItem 
    = AssociatedObject.ItemContainerGenerator.ContainerFromIndex(AssociatedObject.SelectedIndex) as ListBoxItem;

            DoubleAnimation fillheightAnimation 
    = new DoubleAnimation()
            {
                To 
    = selectedItemFinalHeight,
                Duration 
    = new Duration(new TimeSpan(0000, AnimationDuration))
            };

            Storyboard.SetTarget(fillheightAnimation, selectedItem);
            Storyboard.SetTargetProperty(fillheightAnimation, 
    new PropertyPath(FrameworkElement.HeightProperty));
            storyBoard.Children.Add(fillheightAnimation);
        }

        storyBoard.Begin(AssociatedObject);
    }

    这个示例看截图是和上一篇中介绍的是一样。要看动画效果还是要自己试一下的。在这个代码里,也包含了上次的示例。

  • 相关阅读:
    numpy函数:[6]arange()详解
    python中的list和array的不同之处
    python 矩阵转置transpose
    PowerDesigner(一)-PowerDesigner概述(系统分析与建模)
    MDX中Filter 与Exist的区别
    SQL Server 2016 —— 聚集列存储索引的功能增强
    SQL Server 2016:内存列存储索引
    PXE
    setjmp
    skb head/data/tail/end/介绍
  • 原文地址:https://www.cnblogs.com/nankezhishi/p/ExpandablePanelWithAnimation.html
Copyright © 2020-2023  润新知