/YetAnotherRegexTester/YetAnotherRegexTester/Controls/Selection Wrappers/ListSelectionWrapper.cs

http://yetanotheregextester.codeplex.com · C# · 236 lines · 114 code · 17 blank · 105 comment · 8 complexity · fea65856544b7dd65806808e59ef1c73 MD5 · raw file

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