• WPF xaml中列表依赖属性的定义


    列表内容属性

    如上图,是一个列表标题排序控件,我们需要定义一个标题列表,从而让调用方可以自由的设置标题信息。

    在自定义控件时,会遇到列表依赖属性,那么该如何定义呢?

    下面是错误的定义方式:

     1     /// <summary>
     2     /// 标识 <see cref="Headers"/> 的依赖项属性。
     3     /// </summary>
     4     public static readonly DependencyProperty HeadersProperty = DependencyProperty.Register(
     5         "Headers", typeof(List<HeaderContent>), typeof(ListViewHeader),
     6         new PropertyMetadata(new List<HeaderContent>(), (d, e) => ((ListViewHeader)d).InitHeaderList()));
     7 
     8     /// <summary>
     9     /// 获取或设置表头的信息集合。
    10     /// 由于这是依赖项属性,所以很难限制其不为 null,需要总是判空。
    11     /// </summary>
    12     public List<HeaderContent> Headers
    13     {
    14         get => (List<HeaderContent>)GetValue(HeadersProperty);
    15         set => SetValue(HeadersProperty, value);
    16     }

    按照如上依赖属性的定义,

    • 必须提供一个默认属性new List<HeaderContent>() 或者 在自定义控件初始化时设置默认列表值,不然界面调用此列表属性去添加项,界面初始化时肯定会报错~
    • 在Xaml中显示时,不会报出一些错误提示信息~(虽然不影响正常启动,但是错误列表中一直显示,对有强迫症的我来说。。不可忍受)

    正确的实现方案

    • 定义列表依赖属性:
     1     /// <summary>
     2     /// 标识 <see cref="Headers"/> 的依赖项属性。
     3     /// </summary>
     4     public static readonly DependencyProperty HeadersProperty = DependencyProperty.Register(
     5         "Headers", typeof(ListViewHeaderContentCollection), typeof(ListViewHeader),
     6         new PropertyMetadata(default(ListViewHeaderContentCollection), (d, e) => ((ListViewHeader)d).InitHeaderList()));
     7 
     8     /// <summary>
     9     /// 获取或设置表头的信息集合。
    10     /// 由于这是依赖项属性,所以很难限制其不为 null,需要总是判空。
    11     /// </summary>
    12     public ListViewHeaderContentCollection Headers
    13     {
    14         get => (ListViewHeaderContentCollection)GetValue(HeadersProperty);
    15         set => SetValue(HeadersProperty, value);
    16     }
    • 定义列表内容集合类:

      通过实现IList<T>和IList接口,可以让列表在界面调用时,可以以列表的形式添加内容。

      注:将实现的接口方法修改下内容即可

      1     public sealed class ListViewHeaderContentCollection : IList<HeaderContent>, IList
      2     {
      3         private readonly List<HeaderContent> _headContents = new List<HeaderContent>();
      4         public IEnumerator<HeaderContent> GetEnumerator()
      5         {
      6             return _headContents.GetEnumerator();
      7         }
      8 
      9         IEnumerator IEnumerable.GetEnumerator()
     10         {
     11             return GetEnumerator();
     12         }
     13 
     14         public void Add(HeaderContent item)
     15         {
     16             _headContents.Add(item);
     17         }
     18 
     19         public int Add(object value)
     20         {
     21             _headContents.Add((HeaderContent)value);
     22             return _headContents.Count;
     23         }
     24 
     25         public bool Contains(object value)
     26         {
     27             return _headContents.Contains((HeaderContent)value);
     28         }
     29 
     30         public void Clear()
     31         {
     32             _headContents.Clear();
     33         }
     34 
     35         public int IndexOf(object value)
     36         {
     37             return _headContents.IndexOf((HeaderContent)value);
     38         }
     39 
     40         public void Insert(int index, object value)
     41         {
     42             _headContents.Insert(index, (HeaderContent)value);
     43         }
     44 
     45         public void Remove(object value)
     46         {
     47             _headContents.Remove((HeaderContent)value);
     48         }
     49 
     50         void IList.RemoveAt(int index)
     51         {
     52             _headContents.RemoveAt(index);
     53         }
     54 
     55         object IList.this[int index]
     56         {
     57             get => _headContents[index];
     58             set => _headContents[index] = (HeaderContent)value;
     59         }
     60 
     61         public bool Contains(HeaderContent item)
     62         {
     63             return _headContents.Contains(item);
     64         }
     65 
     66         public void CopyTo(HeaderContent[] array, int arrayIndex)
     67         {
     68             _headContents.CopyTo(array, arrayIndex);
     69         }
     70 
     71         public bool Remove(HeaderContent item)
     72         {
     73             return _headContents.Remove(item);
     74         }
     75 
     76         public void CopyTo(Array array, int index)
     77         {
     78             _headContents.CopyTo((HeaderContent[])array, index);
     79         }
     80 
     81         public int Count => _headContents.Count;
     82 
     83         public object SyncRoot { get; }
     84 
     85         public bool IsSynchronized { get; }
     86 
     87         public bool IsReadOnly { get; }
     88 
     89         public bool IsFixedSize { get; }
     90 
     91         public int IndexOf(HeaderContent item)
     92         {
     93             return _headContents.IndexOf(item);
     94         }
     95 
     96         public void Insert(int index, HeaderContent item)
     97         {
     98             _headContents.Insert(index, item);
     99         }
    100 
    101         void IList<HeaderContent>.RemoveAt(int index)
    102         {
    103             _headContents.RemoveAt(index);
    104         }
    105 
    106         public HeaderContent this[int index]
    107         {
    108             get => _headContents[index];
    109             set => _headContents[index] = value;
    110         }
    111     }

     调用:

  • 相关阅读:
    VisualStudio 2012中的单元测试
    基于.Net 写我自己的Ajax后台框架AjaxFramework
    MongoDB的真正性能实战百万用户
    基于MMSeg算法的中文分词类库
    Visual Studio 2012的新插件Code Digger (类似Pex)
    Visual Studio 2010 单元测试之一普通单元测试
    Django系列教程:一、Django的安装和入门
    Cocos2dx 入门调研总结
    教程:建立自己的私有云
    如何让你的作业在Hadoop集群中真正实现分布式运行
  • 原文地址:https://www.cnblogs.com/kybs0/p/9293234.html
Copyright © 2020-2023  润新知