ListBox.SelectedIndexCollection.cs 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. // Licensed to the .NET Foundation under one or more agreements.
  2. // The .NET Foundation licenses this file to you under the MIT license.
  3. // See the LICENSE file in the project root for more information.
  4. using System.Collections;
  5. using System.ComponentModel;
  6. namespace System.Windows.Forms
  7. {
  8. public partial class ListBox
  9. {
  10. public class SelectedIndexCollection : IList
  11. {
  12. private readonly ListBox _owner;
  13. public SelectedIndexCollection(ListBox owner)
  14. {
  15. _owner = owner ?? throw new ArgumentNullException(nameof(owner));
  16. }
  17. /// <summary>
  18. /// Number of current selected items.
  19. /// </summary>
  20. [Browsable(false)]
  21. public int Count
  22. {
  23. get
  24. {
  25. return _owner.SelectedItems.Count;
  26. }
  27. }
  28. object ICollection.SyncRoot
  29. {
  30. get
  31. {
  32. return this;
  33. }
  34. }
  35. bool ICollection.IsSynchronized
  36. {
  37. get
  38. {
  39. return true;
  40. }
  41. }
  42. bool IList.IsFixedSize
  43. {
  44. get
  45. {
  46. return true;
  47. }
  48. }
  49. public bool IsReadOnly
  50. {
  51. get
  52. {
  53. return true;
  54. }
  55. }
  56. public bool Contains(int selectedIndex)
  57. {
  58. return IndexOf(selectedIndex) != -1;
  59. }
  60. bool IList.Contains(object selectedIndex)
  61. {
  62. if (selectedIndex is int)
  63. {
  64. return Contains((int)selectedIndex);
  65. }
  66. else
  67. {
  68. return false;
  69. }
  70. }
  71. public int IndexOf(int selectedIndex)
  72. {
  73. // Just what does this do? The selectedIndex parameter above is the index into the
  74. // main object collection. We look at the state of that item, and if the state indicates
  75. // that it is selected, we get back the virtualized index into this collection. Indexes on
  76. // this collection match those on the SelectedObjectCollection.
  77. if (selectedIndex >= 0 &&
  78. selectedIndex < InnerArray.GetCount(0) &&
  79. InnerArray.GetState(selectedIndex, SelectedObjectCollection.SelectedObjectMask))
  80. {
  81. return InnerArray.IndexOf(InnerArray.GetItem(selectedIndex, 0), SelectedObjectCollection.SelectedObjectMask);
  82. }
  83. return -1;
  84. }
  85. int IList.IndexOf(object selectedIndex)
  86. {
  87. if (selectedIndex is int)
  88. {
  89. return IndexOf((int)selectedIndex);
  90. }
  91. else
  92. {
  93. return -1;
  94. }
  95. }
  96. int IList.Add(object value)
  97. {
  98. throw new NotSupportedException();
  99. }
  100. void IList.Clear()
  101. {
  102. throw new NotSupportedException();
  103. }
  104. void IList.Insert(int index, object value)
  105. {
  106. throw new NotSupportedException();
  107. }
  108. void IList.Remove(object value)
  109. {
  110. throw new NotSupportedException();
  111. }
  112. void IList.RemoveAt(int index)
  113. {
  114. throw new NotSupportedException();
  115. }
  116. /// <summary>
  117. /// Retrieves the specified selected item.
  118. /// </summary>
  119. public int this[int index]
  120. {
  121. get
  122. {
  123. object identifier = InnerArray.GetEntryObject(index, SelectedObjectCollection.SelectedObjectMask);
  124. return InnerArray.IndexOfIdentifier(identifier, 0);
  125. }
  126. }
  127. object IList.this[int index]
  128. {
  129. get
  130. {
  131. return this[index];
  132. }
  133. set
  134. {
  135. throw new NotSupportedException();
  136. }
  137. }
  138. /// <summary>
  139. /// This is the item array that stores our data. We share this backing store
  140. /// with the main object collection.
  141. /// </summary>
  142. private ItemArray InnerArray
  143. {
  144. get
  145. {
  146. _owner.SelectedItems.EnsureUpToDate();
  147. return ((ObjectCollection)_owner.Items).InnerArray;
  148. }
  149. }
  150. public void CopyTo(Array destination, int index)
  151. {
  152. int cnt = Count;
  153. for (int i = 0; i < cnt; i++)
  154. {
  155. destination.SetValue(this[i], i + index);
  156. }
  157. }
  158. public void Clear()
  159. {
  160. if (_owner != null)
  161. {
  162. _owner.ClearSelected();
  163. }
  164. }
  165. public void Add(int index)
  166. {
  167. if (_owner != null)
  168. {
  169. ObjectCollection items = _owner.Items;
  170. if (items != null)
  171. {
  172. if (index != -1 && !Contains(index))
  173. {
  174. _owner.SetSelected(index, true);
  175. }
  176. }
  177. }
  178. }
  179. public void Remove(int index)
  180. {
  181. if (_owner != null)
  182. {
  183. ObjectCollection items = _owner.Items;
  184. if (items != null)
  185. {
  186. if (index != -1 && Contains(index))
  187. {
  188. _owner.SetSelected(index, false);
  189. }
  190. }
  191. }
  192. }
  193. public IEnumerator GetEnumerator()
  194. {
  195. return new SelectedIndexEnumerator(this);
  196. }
  197. /// <summary>
  198. /// EntryEnumerator is an enumerator that will enumerate over
  199. /// a given state mask.
  200. /// </summary>
  201. private class SelectedIndexEnumerator : IEnumerator
  202. {
  203. private readonly SelectedIndexCollection items;
  204. private int current;
  205. /// <summary>
  206. /// Creates a new enumerator that will enumerate over the given state.
  207. /// </summary>
  208. public SelectedIndexEnumerator(SelectedIndexCollection items)
  209. {
  210. this.items = items;
  211. current = -1;
  212. }
  213. /// <summary>
  214. /// Moves to the next element, or returns false if at the end.
  215. /// </summary>
  216. bool IEnumerator.MoveNext()
  217. {
  218. if (current < items.Count - 1)
  219. {
  220. current++;
  221. return true;
  222. }
  223. else
  224. {
  225. current = items.Count;
  226. return false;
  227. }
  228. }
  229. /// <summary>
  230. /// Resets the enumeration back to the beginning.
  231. /// </summary>
  232. void IEnumerator.Reset()
  233. {
  234. current = -1;
  235. }
  236. /// <summary>
  237. /// Retrieves the current value in the enumerator.
  238. /// </summary>
  239. object IEnumerator.Current
  240. {
  241. get
  242. {
  243. if (current == -1 || current == items.Count)
  244. {
  245. throw new InvalidOperationException();
  246. }
  247. return items[current];
  248. }
  249. }
  250. }
  251. }
  252. }
  253. }