【WPF】Behavior的使用

如何将一个行为附加到某个元素上呢?我们可以通过自定义一个Behavior!

我们首先看一下IAttachedObject接口,Behavior默认继承之这个接口

  // 摘要:
    //     供可以附加到另一个对象的对象使用的接口。
    public interface IAttachedObject
    {
        // 摘要:
        //     获得关联的对象。
        //
        // 备注:
        //     代表此实例附加到的对象。
        DependencyObject AssociatedObject { get; }

        // 摘要:
        //     附加到指定的对象。
        //
        // 参数:
        //   dependencyObject:
        //     要附加到的对象。
        void Attach(DependencyObject dependencyObject);
        //
        // 摘要:
        //     将此实例与其关联的对象分离。
        void Detach();
    }

下面我们自定义一个Behavior附加到ListBox元素上:

 public class SelectedItemFillBehavior : Behavior<ListBox>//把行为附加到ListBox上。ListBox被附加了下面的行为
    {
        // Using a DependencyProperty as the backing store for DefaultHeight.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty DefaultHeightProperty =
            DependencyProperty.Register("DefaultHeight", typeof(double), typeof(SelectedItemFillBehavior), new UIPropertyMetadata(30.0));

        // Using a DependencyProperty as the backing store for AnimationDuration.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty AnimationDurationProperty =
            DependencyProperty.Register("AnimationDuration", typeof(int), typeof(SelectedItemFillBehavior), new UIPropertyMetadata(300));

        public double DefaultHeight
        {
            get { return (double)GetValue(DefaultHeightProperty); }
            set { SetValue(DefaultHeightProperty, value); }
        }
        
        public int AnimationDuration
        {
            get { return (int)GetValue(AnimationDurationProperty); }
            set { SetValue(AnimationDurationProperty, value); }
        }
        
        protected override void OnAttached()
        {
            base.OnAttached();
            //附加行为后需要处理的事件
            AssociatedObject.SelectionChanged += new SelectionChangedEventHandler(OnAssociatedObjectSelectionChanged);
        }

        protected override void OnDetaching()
        {
            base.OnDetaching();
            //解除的事件
            AssociatedObject.SelectionChanged -= new SelectionChangedEventHandler(OnAssociatedObjectSelectionChanged);
        }

        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(0, 0, 0, 0, AnimationDuration))
                    };
                    Storyboard.SetTarget(heightAnimation, item);
                    Storyboard.SetTargetProperty(heightAnimation, new PropertyPath(FrameworkElement.HeightProperty));
                    storyBoard.Children.Add(heightAnimation);
                }
            }

            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(0, 0, 0, 0, AnimationDuration))
                };

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

            storyBoard.Begin(AssociatedObject);
        }
    }

这样ListBox被附加了以上行为。

posted @ 2013-12-31 11:33  YoMe  阅读(5540)  评论(0编辑  收藏  举报