Wot.Guo 发表于 2013-1-4 01:19:07

XAML附加属性-为Grid增加ItemsSource和ItemClick

<div id="cnblogs_post_body">首先先讲解下什么是附加属性:Attached Properties,中文称为附加属性,该属性是一种特殊的依赖属性,同时也是XAML中特有的属性之一。
其语法调用格式如下:<控件元素对象 附加元素对象.附加属性名 = 属性值 />
其实在自己做XAML的时候不经意间就用到了附加属性:
比如Canvas.Left=”25” Grid.Row="0" 类似的!
可以这样理解:附加属性主要目的是为了简化代码,增加XAML代码对元素对象的控制.通过已知属性的“继承”或者“附加”,在元素对象上实现特有的效果。
对了,这个被附加的对象必须继承DependencyObject!

首先我们通过为Grid增加一个ItemsSource附加属性!使得我们可以像ListBox之类使用ItemsSource!

[*]新建一个GridAttached类,用于专门定义Grid的附加属性
[*]定义声明一个附加属性,这里和依赖属性定义其实差不多,就一个Register和RegisterAttached的方法区别!
[*]“ItemsSource”就是我们附加属性名 那么这个属性一帮要定义成ItemsSourceProperty
[*]因为我们要定义的是ItemsSource所以使用IEnumerable类型
[*]定义附加属性的访问器 必须是Get/Set+PropertyName(注意:可以省略Get访问器,若省略则VS和Blend上看不到)
[*]处理OnItemsSourcePropertyChanged这个方法-这个方法主要是处理属性变更的时候所需要做的操作—基于IEnumerable相对比较麻烦一些!需要监听CollectionChanged事件处理
代码如下:
<div class="cnblogs_code"> public class GridAttached    {      #region ItemsSourceProperty      private static Grid _grid;      //声明附加属性      public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.RegisterAttached("ItemsSource", typeof(IEnumerable), typeof(GridAttached), new PropertyMetadata(OnItemsSourcePropertyChanged));      //申明Get访问器      public static IEnumerable GetItemsSource(DependencyObject target)      { return (IEnumerable)target.GetValue(ItemsSourceProperty); }      //申明Set访问器      public static void SetItemsSource(DependencyObject target, IEnumerable value)      { target.SetValue(ItemsSourceProperty, value); }      //附加属性变更操作方法      private static void OnItemsSourcePropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)      {            _grid = o as Grid;            if (null != _grid)            {                IEnumerable oldValue = e.OldValue as IEnumerable;                IEnumerable newValue = e.NewValue as IEnumerable;                #region 初次处理数据--这里为Grid添加色块                foreach (string item in newValue)                {                  AddColorChlidByString(item);                }                #endregion                #region ItemsSource变更时的操作                var oldValueInotifyCollectionChanged = oldValue as INotifyCollectionChanged;                if (null != oldValueInotifyCollectionChanged)                {                  oldValueInotifyCollectionChanged.CollectionChanged -= new NotifyCollectionChangedEventHandler(newValueInotifyCollectionChanged_CollectionChanged);                }                var newValueInotifyCollectionChanged = newValue as INotifyCollectionChanged;                if (null != newValueInotifyCollectionChanged)                {                  newValueInotifyCollectionChanged.CollectionChanged += new NotifyCollectionChangedEventHandler(newValueInotifyCollectionChanged_CollectionChanged);                }                #endregion                            }      }      //Items Collection内部变更时执行方法      static void newValueInotifyCollectionChanged_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)      {            if (null == e || null == e.NewItems)            {                return;            }            foreach (string item in e.NewItems)            {                //执行添加                AddColorChlidByString(item);            }      }      //Grid添加色块      private static void AddColorChlidByString(string colorName)      {            Rectangle rec = new Rectangle()            {                Margin = new Thickness(2),                Fill = new SolidColorBrush(ReturnColorFromString(colorName))            };            Grid.SetRow(rec, _grid.Children.Count / 4); //设置色块行            Grid.SetColumn(rec, _grid.Children.Count % 4);//设置色块列            //若是最后一项则新开一行            if (_grid.Children.Count == 0 || _grid.Children.Count / 4 == 1)            {                GridLength gl = new GridLength(115);                _grid.RowDefinitions.Add(new RowDefinition() { Height = gl });                _grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = gl });                _grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = gl });                _grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = gl });            }            _grid.Children.Add(rec);      }      /// 将字符串转换成Color类型      public static Color ReturnColorFromString(string color)      {            color = color.Substring(1, color.Length - 1);            string alpha = color.Substring(0, 2);            string red = color.Substring(2, 2);            string green = color.Substring(4, 2);            string blue = color.Substring(6, 2);            byte alphaByte = Convert.ToByte(alpha, 16);            byte redByte = Convert.ToByte(red, 16);            byte greenByte = Convert.ToByte(green, 16);            byte blueByte = Convert.ToByte(blue, 16);            return Color.FromArgb(alphaByte, redByte, greenByte, blueByte);      }      #endregion    }
页: [1]
查看完整版本: XAML附加属性-为Grid增加ItemsSource和ItemClick