如何將一個行為附加到某個元素上呢?我們可以通過自定義一個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被附加了以上行為。