ListSelectionWrapper.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. /*******************************************************************************
  2. * Copyright(c) 2014 DongkeSoft All rights reserved. / Confidential
  3. * 类的信息:
  4. * 1.程序名称:ListSelectionWrapper.cs
  5. * 2.功能描述:类文件
  6. * 编辑履历:
  7. * 作者 日期 版本 修改内容
  8. * 陈晓野 2014/09/29 1.00 新建
  9. *******************************************************************************/
  10. using System;
  11. using System.Collections;
  12. using System.Collections.Generic;
  13. using System.Reflection;
  14. using System.ComponentModel;
  15. namespace Dongke.IBOSS.PRD.Basics.BaseControls
  16. {
  17. /// <summary>
  18. /// Maintains an additional "Selected" & "Count" value for each item in a List.
  19. /// Useful in the CheckBoxComboBox. It holds a reference to the List[Index] Item and
  20. /// whether it is selected or not.
  21. /// It also caters for a Count, if needed.
  22. /// </summary>
  23. /// <typeparam name="TSelectionWrapper"></typeparam>
  24. public class ListSelectionWrapper<TItem, TValue> : List<ObjectSelectionWrapper<TItem, TValue>>
  25. {
  26. #region CONSTRUCTOR
  27. ///// <summary>
  28. ///// No property on the object is specified for display purposes, so simple ToString() operation
  29. ///// will be performed. And no Counts will be displayed
  30. ///// </summary>
  31. //public ListSelectionWrapper(IEnumerable source) : this(source, false) { }
  32. ///// <summary>
  33. ///// No property on the object is specified for display purposes, so simple ToString() operation
  34. ///// will be performed.
  35. ///// </summary>
  36. //private ListSelectionWrapper(IEnumerable source, bool showCounts)
  37. // : base()
  38. //{
  39. // _Source = source;
  40. // _ShowCounts = showCounts;
  41. // if (_Source is IBindingList)
  42. // ((IBindingList)_Source).ListChanged += new ListChangedEventHandler(ListSelectionWrapper_ListChanged);
  43. // Populate();
  44. //}
  45. ///// <summary>
  46. ///// A Display "Name" property is specified. ToString() will not be performed on items.
  47. ///// This is specifically useful on DataTable implementations, or where PropertyDescriptors are used to read the values.
  48. ///// If a PropertyDescriptor is not found, a Property will be used.
  49. ///// </summary>
  50. //public ListSelectionWrapper(IEnumerable source, string usePropertyAsDisplayName) : this(source, false, usePropertyAsDisplayName) { }
  51. ///// <summary>
  52. ///// A Display "Name" property is specified. ToString() will not be performed on items.
  53. ///// This is specifically useful on DataTable implementations, or where PropertyDescriptors are used to read the values.
  54. ///// If a PropertyDescriptor is not found, a Property will be used.
  55. ///// </summary>
  56. //public ListSelectionWrapper(IEnumerable source, bool showCounts, string usePropertyAsDisplayName)
  57. // : this(source, showCounts)
  58. //{
  59. // _DisplayNameProperty = usePropertyAsDisplayName;
  60. //}
  61. public ListSelectionWrapper(IEnumerable source, string usePropertyAsDisplayName, string valueProperty)
  62. : base()
  63. {
  64. _Source = source;
  65. _ShowCounts = false;
  66. _DisplayNameProperty = usePropertyAsDisplayName;
  67. _ValueProperty = valueProperty;
  68. if (_Source is IBindingList)
  69. ((IBindingList)_Source).ListChanged += new ListChangedEventHandler(ListSelectionWrapper_ListChanged);
  70. Populate();
  71. }
  72. #endregion
  73. #region PRIVATE PROPERTIES
  74. /// <summary>
  75. /// Is a Count indicator used.
  76. /// </summary>
  77. private bool _ShowCounts;
  78. /// <summary>
  79. /// The original List of values wrapped. A "Selected" and possibly "Count" functionality is added.
  80. /// </summary>
  81. private IEnumerable _Source;
  82. /// <summary>
  83. /// Used to indicate NOT to use ToString(), but read this property instead as a display value.
  84. /// </summary>
  85. private string _DisplayNameProperty = null;
  86. private string _ValueProperty = null;
  87. #endregion
  88. #region PUBLIC PROPERTIES
  89. /// <summary>
  90. /// When specified, indicates that ToString() should not be performed on the items.
  91. /// This property will be read instead.
  92. /// This is specifically useful on DataTable implementations, where PropertyDescriptors are used to read the values.
  93. /// </summary>
  94. public string DisplayNameProperty
  95. {
  96. get { return _DisplayNameProperty; }
  97. set { _DisplayNameProperty = value; }
  98. }
  99. public string ValueProperty
  100. {
  101. get
  102. {
  103. return _ValueProperty;
  104. }
  105. set
  106. {
  107. _ValueProperty = value;
  108. }
  109. }
  110. /// <summary>
  111. /// Builds a concatenation list of selected items in the list.
  112. /// </summary>
  113. public string SelectedNames
  114. {
  115. get
  116. {
  117. string Text = "";
  118. foreach (ObjectSelectionWrapper<TItem, TValue> Item in this)
  119. if (Item.Selected)
  120. Text += (
  121. string.IsNullOrEmpty(Text)
  122. ? String.Format("\"{0}\"", Item.Name)
  123. : String.Format(" & \"{0}\"", Item.Name));
  124. return Text;
  125. }
  126. }
  127. public TValue[] SelectedValues
  128. {
  129. get
  130. {
  131. List<TValue> Values = new List<TValue>();
  132. foreach (ObjectSelectionWrapper<TItem, TValue> Item in this)
  133. if (Item.Selected)
  134. Values.Add(Item.Value);
  135. return Values.ToArray();
  136. }
  137. }
  138. /// <summary>
  139. /// Indicates whether the Item display value (Name) should include a count.
  140. /// </summary>
  141. public bool ShowCounts
  142. {
  143. get { return _ShowCounts; }
  144. set { _ShowCounts = value; }
  145. }
  146. #endregion
  147. #region HELPER MEMBERS
  148. /// <summary>
  149. /// Reset all counts to zero.
  150. /// </summary>
  151. public void ClearCounts()
  152. {
  153. foreach (ObjectSelectionWrapper<TItem, TValue> Item in this)
  154. Item.Count = 0;
  155. }
  156. /// <summary>
  157. /// Creates a ObjectSelectionWrapper item.
  158. /// Note that the constructor signature of sub classes classes are important.
  159. /// </summary>
  160. /// <param name="Object"></param>
  161. /// <returns></returns>
  162. private ObjectSelectionWrapper<TItem, TValue> CreateSelectionWrapper(IEnumerator Object)
  163. {
  164. Type[] Types = new Type[] { typeof(TItem), this.GetType() };
  165. ConstructorInfo CI = typeof(ObjectSelectionWrapper<TItem, TValue>).GetConstructor(Types);
  166. if (CI == null)
  167. throw new Exception(String.Format(
  168. "The selection wrapper class {0} must have a constructor with ({1} Item, {2} Container) parameters.",
  169. typeof(ObjectSelectionWrapper<TItem, TValue>),
  170. typeof(TItem),
  171. this.GetType()));
  172. object[] parameters = new object[] { Object.Current, this };
  173. object result = CI.Invoke(parameters);
  174. return (ObjectSelectionWrapper<TItem, TValue>)result;
  175. }
  176. public ObjectSelectionWrapper<TItem, TValue> FindObjectWithItem(TItem Object)
  177. {
  178. return Find(new Predicate<ObjectSelectionWrapper<TItem, TValue>>(
  179. delegate(ObjectSelectionWrapper<TItem, TValue> target)
  180. {
  181. return target.Item.Equals(Object);
  182. }));
  183. }
  184. public ObjectSelectionWrapper<TItem, TValue> FindObjectWithValue(TValue Object)
  185. {
  186. return Find(new Predicate<ObjectSelectionWrapper<TItem, TValue>>(
  187. delegate(ObjectSelectionWrapper<TItem, TValue> target)
  188. {
  189. return target.Value.Equals(Object);
  190. }));
  191. }
  192. /*
  193. public TSelectionWrapper FindObjectWithKey(object key)
  194. {
  195. return FindObjectWithKey(new object[] { key });
  196. }
  197. public TSelectionWrapper FindObjectWithKey(object[] keys)
  198. {
  199. return Find(new Predicate<TSelectionWrapper>(
  200. delegate(TSelectionWrapper target)
  201. {
  202. return
  203. ReflectionHelper.CompareKeyValues(
  204. ReflectionHelper.GetKeyValuesFromObject(target.Item, target.Item.TableInfo),
  205. keys);
  206. }));
  207. }
  208. public object[] GetArrayOfSelectedKeys()
  209. {
  210. List<object> List = new List<object>();
  211. foreach (TSelectionWrapper Item in this)
  212. if (Item.Selected)
  213. {
  214. if (Item.Item.TableInfo.KeyProperties.Length == 1)
  215. List.Add(ReflectionHelper.GetKeyValueFromObject(Item.Item, Item.Item.TableInfo));
  216. else
  217. List.Add(ReflectionHelper.GetKeyValuesFromObject(Item.Item, Item.Item.TableInfo));
  218. }
  219. return List.ToArray();
  220. }
  221. public T[] GetArrayOfSelectedKeys<T>()
  222. {
  223. List<T> List = new List<T>();
  224. foreach (TSelectionWrapper Item in this)
  225. if (Item.Selected)
  226. {
  227. if (Item.Item.TableInfo.KeyProperties.Length == 1)
  228. List.Add((T)ReflectionHelper.GetKeyValueFromObject(Item.Item, Item.Item.TableInfo));
  229. else
  230. throw new LibraryException("This generator only supports single value keys.");
  231. // List.Add((T)ReflectionHelper.GetKeyValuesFromObject(Item.Item, Item.Item.TableInfo));
  232. }
  233. return List.ToArray();
  234. }
  235. */
  236. private void Populate()
  237. {
  238. Clear();
  239. /*
  240. for(int Index = 0; Index <= _Source.Count -1; Index++)
  241. Add(CreateSelectionWrapper(_Source[Index]));
  242. */
  243. IEnumerator Enumerator = _Source.GetEnumerator();
  244. if (Enumerator != null)
  245. while (Enumerator.MoveNext())
  246. Add(CreateSelectionWrapper(Enumerator));
  247. }
  248. #endregion
  249. #region EVENT HANDLERS
  250. private void ListSelectionWrapper_ListChanged(object sender, ListChangedEventArgs e)
  251. {
  252. switch (e.ListChangedType)
  253. {
  254. case ListChangedType.ItemAdded:
  255. Add(CreateSelectionWrapper((IEnumerator)((IBindingList)_Source)[e.NewIndex]));
  256. break;
  257. case ListChangedType.ItemDeleted:
  258. Remove(FindObjectWithItem((TItem)((IBindingList)_Source)[e.OldIndex]));
  259. break;
  260. case ListChangedType.Reset:
  261. Populate();
  262. break;
  263. }
  264. }
  265. #endregion
  266. }
  267. }