列表內容屬性 如上圖,是一個列表標題排序控制項,我們需要定義一個標題列表,從而讓調用方可以自由的設置標題信息。 在自定義控制項時,會遇到列表依賴屬性,那麼該如何定義呢? 下麵是錯誤的定義方式: 按照如上依賴屬性的定義, 必須提供一個預設屬性new List<HeaderContent>() 或者 在自定 ...
列表內容屬性
如上圖,是一個列表標題排序控制項,我們需要定義一個標題列表,從而讓調用方可以自由的設置標題信息。
在自定義控制項時,會遇到列表依賴屬性,那麼該如何定義呢?
下麵是錯誤的定義方式:
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 }
調用: