ListCategory.xaml.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. 
  2. using System;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. using System.Collections.ObjectModel;
  6. using System.Windows;
  7. using System.Windows.Controls;
  8. using System.Windows.Input;
  9. namespace FWindSoft.Wpf.Controls
  10. {
  11. /// <summary>
  12. /// ListCategory.xaml 的交互逻辑
  13. /// </summary>
  14. public partial class ListCategory : UserControl
  15. {
  16. public ListCategory()
  17. {
  18. InitializeComponent();
  19. }
  20. }
  21. public partial class ListCategory
  22. {
  23. /*
  24. * 绑定数据源必须存在Name的属性
  25. * 直接和界面中属性关联的 使用绑定进行关联
  26. * 如果公开的属性和界面中用到的属性经过中间处理,则通过使用空间名字的方法进行赋值
  27. */
  28. #region 依赖属性定义
  29. public static readonly DependencyProperty ItemsProperty;
  30. public static readonly DependencyProperty DisplayPathProperty;
  31. #endregion
  32. #region 定义命令
  33. private static RoutedCommand m_SelectCommand;
  34. public static RoutedCommand SelectCommand
  35. {
  36. get { return m_SelectCommand; }
  37. }
  38. #endregion
  39. #region 定义事件
  40. public static readonly RoutedEvent SelectChangedEvent = EventManager.RegisterRoutedEvent("SelectChanged",
  41. RoutingStrategy.Direct, typeof(RoutedPropertyChangedEventHandler<object>), typeof(ListCategory));
  42. #endregion
  43. static ListCategory()
  44. {
  45. ItemsProperty = DependencyProperty.Register("Items", typeof(IEnumerable), typeof(ListCategory), new PropertyMetadata(default(IEnumerable), new PropertyChangedCallback(PropertyChangedCallback)));
  46. DisplayPathProperty = DependencyProperty.Register("DisplayPath", typeof(string), typeof(ListCategory), new PropertyMetadata(default(string), new PropertyChangedCallback(PropertyChangedCallback)));
  47. m_SelectCommand = new RoutedCommand("SelectCommand", typeof(ListCategory));
  48. System.Windows.Input.CommandManager.RegisterClassCommandBinding(typeof(ListCategory), new CommandBinding(m_SelectCommand, OnSelectCommand, CanExecuteRoutedEventHandler));
  49. HeightProperty.OverrideMetadata(typeof(ListCategory), new FrameworkPropertyMetadata(120d, FrameworkPropertyMetadataOptions.AffectsMeasure, new PropertyChangedCallback(HeightPropertyChangedCallback)));
  50. }
  51. #region 依赖属性封装
  52. /// <summary>
  53. /// 控件包好项目
  54. /// </summary>
  55. public IEnumerable Items
  56. {
  57. get { return (IEnumerable)GetValue(ItemsProperty); }
  58. set { SetValue(ItemsProperty, value); }
  59. }
  60. /// <summary>
  61. /// 类型显示字段
  62. /// </summary>
  63. public string DisplayPath
  64. {
  65. get { return (string)GetValue(DisplayPathProperty); }
  66. set { SetValue(DisplayPathProperty, value); }
  67. }
  68. /// <summary>
  69. /// 控件选中项目
  70. /// </summary>
  71. public IList SelectItems { get; private set; }
  72. #endregion
  73. #region 事件封装
  74. public event RoutedPropertyChangedEventHandler<object> SelectChanged
  75. {
  76. add { this.AddHandler(SelectChangedEvent,value); }
  77. remove { this.RemoveHandler(SelectChangedEvent,value);}
  78. }
  79. #endregion
  80. #region 相关静态方法
  81. #region 属性变化与界面关联
  82. private static void HeightPropertyChangedCallback(DependencyObject sender, DependencyPropertyChangedEventArgs args)
  83. {
  84. ListCategory section = sender as ListCategory;
  85. if (section != null)
  86. {
  87. section.list.Height = (double)args.NewValue;
  88. }
  89. }
  90. private static void PropertyChangedCallback(DependencyObject sender, DependencyPropertyChangedEventArgs args)
  91. {
  92. ListCategory list = sender as ListCategory;
  93. if (list != null)
  94. {
  95. string propeertyName = args.Property.Name;
  96. switch (propeertyName)
  97. {
  98. case "Items":
  99. {
  100. object tempObject = args.NewValue;
  101. if (tempObject == null)
  102. {
  103. list.DisplayItemsSource = null;
  104. list.SelectItems = null;
  105. list.list.ItemsSource = null;
  106. break;
  107. }
  108. var type=tempObject.GetType().GetInterface(typeof (IEnumerable).Name);
  109. if (type == null)
  110. {
  111. throw new Exception("数据源需要实现IEnumerable接口");
  112. }
  113. IEnumerator enumerator = ((IEnumerable)tempObject).GetEnumerator();
  114. try
  115. {
  116. var tempSource=new ObservableCollection<InnerCheckItem>();
  117. while (enumerator.MoveNext())
  118. {
  119. var tempCurrent = enumerator.Current;
  120. if (tempCurrent != null)
  121. {
  122. var tempItem = new InnerCheckItem(tempCurrent,list.DisplayPath);
  123. tempSource.Add(tempItem);
  124. }
  125. }
  126. list.DisplayItemsSource = tempSource;
  127. }
  128. finally
  129. {
  130. enumerator.Reset();
  131. }
  132. list.list.ItemsSource = list.DisplayItemsSource;
  133. list.SelectItems = null;
  134. break;
  135. }
  136. case "DisplayPath":
  137. {
  138. object tempObject = list.Items;
  139. if (tempObject == null)
  140. {
  141. break;
  142. }
  143. var type = tempObject.GetType().GetInterface(typeof(IEnumerable).Name);
  144. if (type == null)
  145. {
  146. break;
  147. }
  148. IEnumerator enumerator = ((IEnumerable)tempObject).GetEnumerator();
  149. string newPath = args.NewValue.ToString();
  150. try
  151. {
  152. var tempSource = new ObservableCollection<InnerCheckItem>();
  153. while (enumerator.MoveNext())
  154. {
  155. var tempCurrent = enumerator.Current;
  156. if (tempCurrent != null)
  157. {
  158. var tempItem = new InnerCheckItem(tempCurrent, newPath);
  159. tempSource.Add(tempItem);
  160. }
  161. }
  162. list.DisplayItemsSource = tempSource;
  163. }
  164. finally
  165. {
  166. enumerator.Reset();
  167. }
  168. list.list.ItemsSource = list.DisplayItemsSource;
  169. list.SelectItems = null;
  170. break;
  171. }
  172. }
  173. }
  174. }
  175. #endregion
  176. #endregion
  177. #region 命令处理
  178. private static void OnSelectCommand(object sender, ExecutedRoutedEventArgs e)
  179. {
  180. ListCategory list = sender as ListCategory;
  181. if (list != null)
  182. {
  183. list.ChangeSelectItems();
  184. }
  185. }
  186. private static void CanExecuteRoutedEventHandler(object sender, CanExecuteRoutedEventArgs e)
  187. {
  188. e.CanExecute = true;
  189. }
  190. #endregion
  191. #region 私有属性
  192. private ObservableCollection<InnerCheckItem> DisplayItemsSource { get; set; }
  193. #endregion
  194. #region 公开selectChange事件
  195. private void ChangeSelectItems()
  196. {
  197. List<object> tempObjects=new List<object>();
  198. if (this.DisplayItemsSource != null)
  199. {
  200. foreach (var innerCheckItem in DisplayItemsSource)
  201. {
  202. if (innerCheckItem.IsChecked)
  203. {
  204. tempObjects.Add(innerCheckItem.RefObject);
  205. }
  206. }
  207. }
  208. object oldValue = this.SelectItems;
  209. this.SelectItems = tempObjects;
  210. OnSelectChanged(oldValue, this.SelectItems);
  211. }
  212. protected virtual void OnSelectChanged(object oldValue,object newValue )
  213. {
  214. RoutedPropertyChangedEventArgs<object> arg = new RoutedPropertyChangedEventArgs<object>(oldValue, newValue, SelectChangedEvent);
  215. this.RaiseEvent(arg);
  216. }
  217. #endregion
  218. /// <summary>
  219. /// 设置选中项
  220. /// </summary>
  221. /// <param name="o"></param>
  222. public void SetSelected(object o)
  223. {
  224. if (this.DisplayItemsSource == null)
  225. return;
  226. foreach (var innerCheckItem in DisplayItemsSource)
  227. {
  228. if (innerCheckItem.RefObject.Equals(o))
  229. {
  230. innerCheckItem.IsChecked = true;
  231. }
  232. }
  233. }
  234. /// <summary>
  235. /// 设置选中集合
  236. /// </summary>
  237. /// <param name="selectList"></param>
  238. public void SetMultiSelected(IList selectList)
  239. {
  240. if (this.DisplayItemsSource == null)
  241. return;
  242. foreach (var innerCheckItem in DisplayItemsSource)
  243. {
  244. innerCheckItem.IsChecked = selectList.Contains(innerCheckItem.RefObject);
  245. }
  246. this.ChangeSelectItems();
  247. }
  248. }
  249. }