zoukankan      html  css  js  c++  java
  • 【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);
    }

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

  • 相关阅读:
    javascript 显示类型转换
    javascript 隐式类型转换
    inline/inline-block/block 的区别
    javascript 类型检测
    title与h1的区别、b与strong的区别、i与em的区别?
    CSS定位方式有哪些?position属性的值有哪些?他们之间的区别是什么?
    列出display的值,说明他们的作用。position的值, relative和 absolute定位原点是?
    语义化的理解
    src与href的区别
    img的alt和title的异同?
  • 原文地址:https://www.cnblogs.com/nankezhishi/p/ExpandablePanelWithAnimation.html
Copyright © 2011-2022 走看看