如何将一个行为附加到某个元素上呢?我们可以通过自定义一个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被附加了以上行为。