1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 // Copyright (c) 2004-2006 Novell, Inc.
23 // Jordi Mas i Hernandez, jordi@ximian.com
24 // Mike Kestner <mkestner@novell.com>
31 using System.Collections;
32 using System.ComponentModel;
33 using System.ComponentModel.Design;
34 using System.ComponentModel.Design.Serialization;
35 using System.Reflection;
36 using System.Runtime.InteropServices;
38 namespace System.Windows.Forms
40 [DefaultProperty("Items")]
41 [DefaultEvent("SelectedIndexChanged")]
42 [Designer ("System.Windows.Forms.Design.ListBoxDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
44 [DefaultBindingProperty ("SelectedValue")]
45 [ClassInterface (ClassInterfaceType.AutoDispatch)]
48 public class ListBox : ListControl
50 public const int DefaultItemHeight = 13;
51 public const int NoMatches = -1;
53 internal enum ItemNavigation
65 Hashtable item_heights;
66 private int item_height = -1;
67 private int column_width = 0;
68 private int requested_height = -1;
69 private DrawMode draw_mode = DrawMode.Normal;
70 private int horizontal_extent = 0;
71 private bool horizontal_scrollbar = false;
72 private bool integral_height = true;
73 private bool multicolumn = false;
74 private bool scroll_always_visible = false;
75 private int selected_index = -1;
76 private SelectedIndexCollection selected_indices;
77 private SelectedObjectCollection selected_items;
78 private ArrayList selection = new ArrayList ();
79 private SelectionMode selection_mode = SelectionMode.One;
80 private bool sorted = false;
81 private bool use_tabstops = true;
82 private int column_width_internal = 120;
83 private ImplicitVScrollBar vscrollbar;
84 private ImplicitHScrollBar hscrollbar;
85 private int hbar_offset;
86 private bool suspend_layout;
87 private bool ctrl_pressed = false;
88 private bool shift_pressed = false;
89 private bool explicit_item_height = false;
90 private int top_index = 0;
91 private int last_visible_index = 0;
92 private Rectangle items_area;
93 private int focused_item = -1;
94 private ObjectCollection items;
98 border_style = BorderStyle.Fixed3D;
99 BackColor = ThemeEngine.Current.ColorWindow;
101 items = CreateItemCollection ();
102 selected_indices = new SelectedIndexCollection (this);
103 selected_items = new SelectedObjectCollection (this);
105 /* Vertical scrollbar */
106 vscrollbar = new ImplicitVScrollBar ();
107 vscrollbar.Minimum = 0;
108 vscrollbar.SmallChange = 1;
109 vscrollbar.LargeChange = 1;
110 vscrollbar.Maximum = 0;
111 vscrollbar.ValueChanged += new EventHandler (VerticalScrollEvent);
112 vscrollbar.Visible = false;
114 /* Horizontal scrollbar */
115 hscrollbar = new ImplicitHScrollBar ();
116 hscrollbar.Minimum = 0;
117 hscrollbar.SmallChange = 1;
118 hscrollbar.LargeChange = 1;
119 hscrollbar.Maximum = 0;
120 hscrollbar.Visible = false;
121 hscrollbar.ValueChanged += new EventHandler (HorizontalScrollEvent);
124 MouseDown += new MouseEventHandler (OnMouseDownLB);
125 MouseMove += new MouseEventHandler (OnMouseMoveLB);
126 MouseUp += new MouseEventHandler (OnMouseUpLB);
127 MouseWheel += new MouseEventHandler (OnMouseWheelLB);
128 KeyDown += new KeyEventHandler (OnKeyDownLB);
129 KeyUp += new KeyEventHandler (OnKeyUpLB);
130 GotFocus += new EventHandler (OnGotFocus);
131 LostFocus += new EventHandler (OnLostFocus);
133 SetStyle (ControlStyles.UserPaint, false);
137 static object DrawItemEvent = new object ();
138 static object MeasureItemEvent = new object ();
139 static object SelectedIndexChangedEvent = new object ();
142 [EditorBrowsable (EditorBrowsableState.Never)]
143 public new event EventHandler BackgroundImageChanged {
144 add { base.BackgroundImageChanged += value; }
145 remove { base.BackgroundImageChanged -= value; }
150 [EditorBrowsable (EditorBrowsableState.Always)]
153 [EditorBrowsable (EditorBrowsableState.Advanced)]
155 public new event EventHandler Click {
156 add { base.Click += value; }
157 remove { base.Click -= value; }
160 public event DrawItemEventHandler DrawItem {
161 add { Events.AddHandler (DrawItemEvent, value); }
162 remove { Events.RemoveHandler (DrawItemEvent, value); }
165 public event MeasureItemEventHandler MeasureItem {
166 add { Events.AddHandler (MeasureItemEvent, value); }
167 remove { Events.RemoveHandler (MeasureItemEvent, value); }
171 [EditorBrowsable (EditorBrowsableState.Never)]
172 public new event PaintEventHandler Paint {
173 add { base.Paint += value; }
174 remove { base.Paint -= value; }
177 public event EventHandler SelectedIndexChanged {
178 add { Events.AddHandler (SelectedIndexChangedEvent, value); }
179 remove { Events.RemoveHandler (SelectedIndexChangedEvent, value); }
183 [EditorBrowsable (EditorBrowsableState.Advanced)]
184 public new event EventHandler TextChanged {
185 add { base.TextChanged += value; }
186 remove { base.TextChanged -= value; }
190 #region Public Properties
191 public override Color BackColor {
192 get { return base.BackColor; }
194 if (base.BackColor == value)
197 base.BackColor = value;
198 base.Refresh (); // Careful. Calling the base method is not the same that calling
199 } // the overriden one that refresh also all the items
203 [EditorBrowsable (EditorBrowsableState.Never)]
204 public override Image BackgroundImage {
205 get { return base.BackgroundImage; }
207 base.BackgroundImage = value;
212 [DefaultValue (BorderStyle.Fixed3D)]
214 public BorderStyle BorderStyle {
215 get { return InternalBorderStyle; }
217 InternalBorderStyle = value;
218 UpdateListBoxBounds ();
224 public int ColumnWidth {
225 get { return column_width; }
228 throw new ArgumentException ("A value less than zero is assigned to the property.");
230 column_width = value;
233 ColumnWidthInternal = 120;
235 ColumnWidthInternal = value;
241 protected override CreateParams CreateParams {
242 get { return base.CreateParams;}
245 protected override Size DefaultSize {
246 get { return new Size (120, 96); }
249 [RefreshProperties(RefreshProperties.Repaint)]
250 [DefaultValue (DrawMode.Normal)]
251 public virtual DrawMode DrawMode {
252 get { return draw_mode; }
255 if (!Enum.IsDefined (typeof (DrawMode), value))
256 throw new InvalidEnumArgumentException (string.Format("Enum argument value '{0}' is not valid for DrawMode", value));
258 if (value == DrawMode.OwnerDrawVariable && multicolumn == true)
259 throw new ArgumentException ("Cannot have variable height and multicolumn");
261 if (draw_mode == value)
266 if (draw_mode == DrawMode.OwnerDrawVariable)
267 item_heights = new Hashtable ();
275 public override Color ForeColor {
276 get { return base.ForeColor; }
279 if (base.ForeColor == value)
282 base.ForeColor = value;
289 public int HorizontalExtent {
290 get { return horizontal_extent; }
292 if (horizontal_extent == value)
295 horizontal_extent = value;
300 [DefaultValue (false)]
302 public bool HorizontalScrollbar {
303 get { return horizontal_scrollbar; }
305 if (horizontal_scrollbar == value)
308 horizontal_scrollbar = value;
314 [DefaultValue (true)]
316 [RefreshProperties(RefreshProperties.Repaint)]
317 public bool IntegralHeight {
318 get { return integral_height; }
320 if (integral_height == value)
323 integral_height = value;
324 UpdateListBoxBounds ();
330 [RefreshProperties(RefreshProperties.Repaint)]
331 public virtual int ItemHeight {
333 if (item_height == -1) {
334 SizeF sz = DeviceContext.MeasureString ("The quick brown Fox", Font);
335 item_height = (int) sz.Height;
341 throw new ArgumentOutOfRangeException ("The ItemHeight property was set beyond 255 pixels");
343 explicit_item_height = true;
344 if (item_height == value)
349 UpdateListBoxBounds ();
354 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
356 [Editor ("System.Windows.Forms.Design.ListControlStringCollectionEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
358 [MergableProperty (false)]
360 public ObjectCollection Items {
361 get { return items; }
364 [DefaultValue (false)]
365 public bool MultiColumn {
366 get { return multicolumn; }
368 if (multicolumn == value)
371 if (value == true && DrawMode == DrawMode.OwnerDrawVariable)
372 throw new ArgumentException ("A multicolumn ListBox cannot have a variable-sized height.");
380 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
381 [EditorBrowsable (EditorBrowsableState.Advanced)]
382 public int PreferredHeight {
385 if (draw_mode == DrawMode.Normal)
386 itemsHeight = FontHeight * items.Count;
387 else if (draw_mode == DrawMode.OwnerDrawFixed)
388 itemsHeight = ItemHeight * items.Count;
389 else if (draw_mode == DrawMode.OwnerDrawVariable) {
390 for (int i = 0; i < items.Count; i++)
391 itemsHeight += (int) item_heights [Items [i]];
398 public override RightToLeft RightToLeft {
399 get { return base.RightToLeft; }
401 base.RightToLeft = value;
402 if (base.RightToLeft == RightToLeft.Yes)
403 StringFormat.Alignment = StringAlignment.Far;
405 StringFormat.Alignment = StringAlignment.Near;
410 // Only affects the Vertical ScrollBar
411 [DefaultValue (false)]
413 public bool ScrollAlwaysVisible {
414 get { return scroll_always_visible; }
416 if (scroll_always_visible == value)
419 scroll_always_visible = value;
426 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
427 public override int SelectedIndex {
428 get { return selected_index;}
430 if (value < -1 || value >= Items.Count)
431 throw new ArgumentOutOfRangeException ("Index of out range");
433 if (SelectionMode == SelectionMode.None)
434 throw new ArgumentException ("cannot call this method if SelectionMode is SelectionMode.None");
436 if (selected_index == value)
441 else if (SelectionMode == SelectionMode.One)
442 UnSelectItem (selected_index, true);
444 if (value < top_index)
449 int rows = items_area.Height / ItemHeight;
450 if (value >= (top_index + rows))
452 top_index = value - rows + 1;
457 selected_index = value;
459 OnSelectedIndexChanged (new EventArgs ());
460 OnSelectedValueChanged (new EventArgs ());
465 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
466 public SelectedIndexCollection SelectedIndices {
467 get { return selected_indices; }
472 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
473 public object SelectedItem {
475 if (SelectedItems.Count > 0)
476 return SelectedItems[0];
481 if (value != null && !Items.Contains (value))
482 return; // FIXME: this is probably an exception
484 SelectedIndex = value == null ? - 1 : Items.IndexOf (value);
489 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
490 public SelectedObjectCollection SelectedItems {
491 get {return selected_items;}
494 [DefaultValue (SelectionMode.One)]
495 public virtual SelectionMode SelectionMode {
496 get { return selection_mode; }
498 if (!Enum.IsDefined (typeof (SelectionMode), value))
499 throw new InvalidEnumArgumentException (string.Format("Enum argument value '{0}' is not valid for SelectionMode", value));
501 if (selection_mode == value)
504 selection_mode = value;
506 switch (selection_mode) {
507 case SelectionMode.None:
511 case SelectionMode.One:
512 while (SelectedIndices.Count > 1)
513 UnSelectItem (SelectedIndices [SelectedIndices.Count - 1], true);
522 [DefaultValue (false)]
524 get { return sorted; }
538 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
539 [EditorBrowsable (EditorBrowsableState.Advanced)]
540 public override string Text {
542 if (SelectionMode != SelectionMode.None && SelectedIndex != -1)
543 return GetItemText (SelectedItem);
551 if (SelectionMode == SelectionMode.None)
556 index = FindStringExact (value);
561 SelectedIndex = index;
566 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
567 public int TopIndex {
568 get { return top_index; }
570 if (value == top_index)
573 if (value < 0 || value >= Items.Count)
582 [DefaultValue (true)]
583 public bool UseTabStops {
584 get { return use_tabstops; }
587 if (use_tabstops == value)
590 use_tabstops = value;
592 StringFormat.SetTabStops (0, new float [] {(float)(Font.Height * 3.7)});
594 StringFormat.SetTabStops (0, new float [0]);
600 protected override bool AllowSelection {
602 return SelectionMode != SelectionMode.None;
607 #endregion Public Properties
609 #region Private Properties
611 private int ColumnWidthInternal {
612 get { return column_width_internal; }
613 set { column_width_internal = value; }
616 private int row_count = 1;
617 private int RowCount {
619 return MultiColumn ? row_count : Items.Count;
623 #endregion Private Properties
625 #region Public Methods
627 [Obsolete ("this method has been deprecated")]
629 protected virtual void AddItemsCore (object[] value)
631 Items.AddRange (value);
634 public void BeginUpdate ()
636 suspend_layout = true;
639 public void ClearSelected ()
641 foreach (int i in selected_indices) {
642 UnSelectItem (i, false);
648 protected virtual ObjectCollection CreateItemCollection ()
650 return new ObjectCollection (this);
653 public void EndUpdate ()
655 suspend_layout = false;
660 public int FindString (String s)
662 return FindString (s, -1);
665 public int FindString (string s, int startIndex)
667 if (Items.Count == 0)
668 return -1; // No exception throwing if empty
670 if (startIndex < -1 || startIndex >= Items.Count - 1)
671 throw new ArgumentOutOfRangeException ("Index of out range");
674 for (int i = startIndex; i < Items.Count; i++) {
675 if ((GetItemText (Items[i])).StartsWith (s))
682 public int FindStringExact (string s)
684 return FindStringExact (s, -1);
687 public int FindStringExact (string s, int startIndex)
689 if (Items.Count == 0)
690 return -1; // No exception throwing if empty
692 if (startIndex < -1 || startIndex >= Items.Count - 1)
693 throw new ArgumentOutOfRangeException ("Index of out range");
696 for (int i = startIndex; i < Items.Count; i++) {
697 if ((GetItemText (Items[i])).Equals (s))
704 public int GetItemHeight (int index)
706 if (index < 0 || index >= Items.Count)
707 throw new ArgumentOutOfRangeException ("Index of out range");
709 if (DrawMode == DrawMode.OwnerDrawVariable && IsHandleCreated == true) {
711 object o = Items [index];
712 if (item_heights.Contains (o))
713 return (int) item_heights [o];
715 MeasureItemEventArgs args = new MeasureItemEventArgs (DeviceContext, index, ItemHeight);
716 OnMeasureItem (args);
717 item_heights [o] = args.ItemHeight;
718 return args.ItemHeight;
724 public Rectangle GetItemRectangle (int index)
726 if (index < 0 || index >= Items.Count)
727 throw new ArgumentOutOfRangeException ("GetItemRectangle index out of range.");
729 Rectangle rect = new Rectangle ();
732 int col = index / RowCount;
733 rect.Y = ((index - top_index) % RowCount) * ItemHeight;
734 rect.X = col * ColumnWidthInternal;
735 rect.Height = ItemHeight;
736 rect.Width = ColumnWidthInternal;
739 rect.Height = GetItemHeight (index);
740 rect.Width = items_area.Width;
742 if (DrawMode == DrawMode.OwnerDrawVariable) {
744 if (index >= top_index) {
745 for (int i = top_index; i < index; i++) {
746 rect.Y += GetItemHeight (i);
749 for (int i = index; i < top_index; i++) {
750 rect.Y -= GetItemHeight (i);
754 rect.Y = ItemHeight * (index - top_index);
761 public bool GetSelected (int index)
763 if (index < 0 || index >= Items.Count)
764 throw new ArgumentOutOfRangeException ("Index of out range");
766 return SelectedIndices.Contains (index);
769 public int IndexFromPoint (Point p)
771 return IndexFromPoint (p.X, p.Y);
774 // Only returns visible points
775 public int IndexFromPoint (int x, int y)
778 if (Items.Count == 0) {
782 for (int i = top_index; i <= last_visible_index; i++) {
783 if (GetItemRectangle (i).Contains (x,y) == true)
790 protected override void OnChangeUICues (UICuesEventArgs e)
792 base.OnChangeUICues (e);
795 protected override void OnDataSourceChanged (EventArgs e)
797 base.OnDataSourceChanged (e);
800 if (DataSource == null || DataManager == null) {
804 SelectedIndex = DataManager.Position;
808 protected override void OnDisplayMemberChanged (EventArgs e)
810 base.OnDisplayMemberChanged (e);
812 if (DataManager == null || !IsHandleCreated)
819 protected virtual void OnDrawItem (DrawItemEventArgs e)
822 case DrawMode.OwnerDrawFixed:
823 case DrawMode.OwnerDrawVariable:
824 DrawItemEventHandler eh = (DrawItemEventHandler)(Events [DrawItemEvent]);
831 ThemeEngine.Current.DrawListBoxItem (this, e);
836 protected override void OnFontChanged (EventArgs e)
838 base.OnFontChanged (e);
841 StringFormat.SetTabStops (0, new float [] {(float)(Font.Height * 3.7)});
843 if (explicit_item_height) {
846 SizeF sz = DeviceContext.MeasureString ("The quick brown Fox", Font);
847 item_height = (int) sz.Height;
849 UpdateListBoxBounds ();
854 protected override void OnHandleCreated (EventArgs e)
856 base.OnHandleCreated (e);
859 Controls.AddImplicit (vscrollbar);
860 Controls.AddImplicit (hscrollbar);
865 protected override void OnHandleDestroyed (EventArgs e)
867 base.OnHandleDestroyed (e);
870 protected virtual void OnMeasureItem (MeasureItemEventArgs e)
872 if (draw_mode != DrawMode.OwnerDrawVariable)
875 MeasureItemEventHandler eh = (MeasureItemEventHandler)(Events [MeasureItemEvent]);
880 protected override void OnParentChanged (EventArgs e)
882 base.OnParentChanged (e);
885 protected override void OnResize (EventArgs e)
888 if (canvas_size.IsEmpty || MultiColumn)
892 protected override void OnSelectedIndexChanged (EventArgs e)
894 base.OnSelectedIndexChanged (e);
896 EventHandler eh = (EventHandler)(Events [SelectedIndexChangedEvent]);
901 protected override void OnSelectedValueChanged (EventArgs e)
903 base.OnSelectedValueChanged (e);
906 public override void Refresh ()
908 if (draw_mode == DrawMode.OwnerDrawVariable)
909 item_heights.Clear ();
914 protected override void RefreshItem (int index)
916 if (index < 0 || index >= Items.Count)
917 throw new ArgumentOutOfRangeException ("Index of out range");
919 if (draw_mode == DrawMode.OwnerDrawVariable)
920 item_heights.Remove (Items [index]);
923 protected override void SetBoundsCore (int x, int y, int width, int height, BoundsSpecified specified)
925 if ((specified & BoundsSpecified.Height) == BoundsSpecified.Height)
926 requested_height = height;
928 if (IntegralHeight) {
930 switch (border_style) {
931 case BorderStyle.Fixed3D:
932 border = ThemeEngine.Current.Border3DSize.Height;
934 case BorderStyle.FixedSingle:
935 border = ThemeEngine.Current.BorderSize.Height;
937 case BorderStyle.None:
942 height -= (2 * border);
943 height -= height % ItemHeight;
944 height += (2 * border);
947 base.SetBoundsCore (x, y, width, height, specified);
951 protected override void SetItemCore (int index, object value)
953 if (index < 0 || index >= Items.Count)
956 Items[index] = value;
959 protected override void SetItemsCore (IList value)
964 Items.AddRange (value);
970 public void SetSelected (int index, bool value)
972 if (index < 0 || index >= Items.Count)
973 throw new ArgumentOutOfRangeException ("Index of out range");
975 if (SelectionMode == SelectionMode.None)
976 throw new InvalidOperationException ();
981 UnSelectItem (index, true);
984 protected virtual void Sort ()
986 if (Items.Count == 0)
993 public override string ToString ()
995 return base.ToString ();
998 protected virtual void WmReflectCommand (ref Message m)
1002 protected override void WndProc (ref Message m)
1004 base.WndProc (ref m);
1007 #endregion Public Methods
1009 #region Private Methods
1011 private Size canvas_size;
1013 private void LayoutListBox ()
1015 if (!IsHandleCreated || suspend_layout)
1019 LayoutMultiColumn ();
1021 LayoutSingleColumn ();
1023 UpdateScrollBars ();
1024 last_visible_index = LastVisibleItem ();
1027 private void LayoutSingleColumn ()
1032 case DrawMode.OwnerDrawVariable:
1034 width = HorizontalExtent;
1035 for (int i = 0; i < Items.Count; i++) {
1036 height += GetItemHeight (i);
1040 case DrawMode.OwnerDrawFixed:
1041 height = Items.Count * ItemHeight;
1042 width = HorizontalExtent;
1045 case DrawMode.Normal:
1047 height = Items.Count * ItemHeight;
1049 for (int i = 0; i < Items.Count; i++) {
1050 SizeF sz = DeviceContext.MeasureString (GetItemText (Items[i]), Font);
1051 if ((int) sz.Width > width)
1052 width = (int) sz.Width;
1057 canvas_size = new Size (width, height);
1060 private void LayoutMultiColumn ()
1062 int usable_height = ClientRectangle.Height - (ScrollAlwaysVisible ? hscrollbar.Height : 0);
1063 row_count = usable_height / ItemHeight;
1066 int cols = (int) Math.Ceiling ((float)Items.Count / (float) row_count);
1067 Size sz = new Size (cols * ColumnWidthInternal, row_count * ItemHeight);
1068 if (!ScrollAlwaysVisible && sz.Width > ClientRectangle.Width && row_count > 1) {
1069 usable_height = ClientRectangle.Height - hscrollbar.Height;
1070 row_count = usable_height / ItemHeight;
1071 cols = (int) Math.Ceiling ((float)Items.Count / (float) row_count);
1072 sz = new Size (cols * ColumnWidthInternal, row_count * ItemHeight);
1077 internal void Draw (Rectangle clip, Graphics dc)
1079 Theme theme = ThemeEngine.Current;
1081 if (hscrollbar.Visible && vscrollbar.Visible) {
1082 // Paint the dead space in the bottom right corner
1083 Rectangle rect = new Rectangle (hscrollbar.Right, vscrollbar.Bottom, vscrollbar.Width, hscrollbar.Height);
1084 if (rect.IntersectsWith (clip))
1085 dc.FillRectangle (theme.ResPool.GetSolidBrush (theme.ColorControl), rect);
1088 dc.FillRectangle (theme.ResPool.GetSolidBrush (BackColor), items_area);
1090 if (Items.Count == 0)
1093 for (int i = top_index; i <= last_visible_index; i++) {
1094 Rectangle rect = GetItemDisplayRectangle (i, top_index);
1096 if (!clip.IntersectsWith (rect))
1099 DrawItemState state = DrawItemState.None;
1101 if (SelectedIndices.Contains (i))
1102 state |= DrawItemState.Selected;
1104 if (has_focus && FocusedItem == i)
1105 state |= DrawItemState.Focus;
1107 if (MultiColumn == false && hscrollbar != null && hscrollbar.Visible) {
1108 rect.X -= hscrollbar.Value;
1109 rect.Width += hscrollbar.Value;
1112 OnDrawItem (new DrawItemEventArgs (dc, Font, rect, i, state, ForeColor, BackColor));
1116 // Converts a GetItemRectangle to a one that we can display
1117 internal Rectangle GetItemDisplayRectangle (int index, int first_displayble)
1119 Rectangle item_rect;
1120 Rectangle first_item_rect = GetItemRectangle (first_displayble);
1121 item_rect = GetItemRectangle (index);
1122 item_rect.X -= first_item_rect.X;
1123 item_rect.Y -= first_item_rect.Y;
1129 private void HorizontalScrollEvent (object sender, EventArgs e)
1132 int top_item = top_index;
1133 int last_item = last_visible_index;
1135 top_index = RowCount * hscrollbar.Value;
1136 last_visible_index = LastVisibleItem ();
1138 if (top_item != top_index || last_item != last_visible_index)
1139 Invalidate (items_area);
1142 int old_offset = hbar_offset;
1143 hbar_offset = hscrollbar.Value;
1145 if (hbar_offset < 0)
1148 XplatUI.ScrollWindow (Handle, items_area, old_offset - hbar_offset, 0, false);
1152 // Only returns visible points. The diference of with IndexFromPoint is that the rectangle
1153 // has screen coordinates
1154 private int IndexAtClientPoint (int x, int y)
1156 if (Items.Count == 0)
1161 else if (x > ClientRectangle.Right)
1162 x = ClientRectangle.Right;
1166 else if (y > ClientRectangle.Bottom)
1167 y = ClientRectangle.Bottom;
1169 for (int i = top_index; i <= last_visible_index; i++)
1170 if (GetItemDisplayRectangle (i, top_index).Contains (x, y))
1176 private int LastVisibleItem ()
1178 Rectangle item_rect;
1179 int top_y = items_area.Y + items_area.Height;
1182 if (top_index >= Items.Count)
1185 for (i = top_index; i < Items.Count; i++) {
1187 item_rect = GetItemDisplayRectangle (i, top_index);
1190 if (item_rect.X > items_area.Width)
1194 if (item_rect.Y + item_rect.Height > top_y) {
1202 private void UpdateTopItem ()
1205 int col = top_index / RowCount;
1207 if (col > hscrollbar.Maximum)
1208 hscrollbar.Value = hscrollbar.Maximum;
1210 hscrollbar.Value = col;
1212 int val = vscrollbar.Value;
1213 if (top_index > vscrollbar.Maximum)
1214 vscrollbar.Value = vscrollbar.Maximum;
1216 vscrollbar.Value = top_index;
1217 Scroll (vscrollbar, vscrollbar.Value - top_index);
1218 XplatUI.ScrollWindow (Handle, items_area, 0, ItemHeight * (val - vscrollbar.Value), false);
1222 // Navigates to the indicated item and returns the new item
1223 private int NavigateItemVisually (ItemNavigation navigation)
1225 int page_size, columns, selected_index = -1;
1228 columns = items_area.Width / ColumnWidthInternal;
1229 page_size = columns * RowCount;
1230 if (page_size == 0) {
1231 page_size = RowCount;
1234 page_size = items_area.Height / ItemHeight;
1237 switch (navigation) {
1239 case ItemNavigation.PreviousColumn: {
1240 if (FocusedItem - RowCount < 0) {
1244 if (FocusedItem - RowCount < top_index) {
1245 top_index = FocusedItem - RowCount;
1249 selected_index = FocusedItem - RowCount;
1253 case ItemNavigation.NextColumn: {
1254 if (FocusedItem + RowCount >= Items.Count) {
1258 if (FocusedItem + RowCount > last_visible_index) {
1259 top_index = FocusedItem;
1263 selected_index = FocusedItem + RowCount;
1267 case ItemNavigation.First: {
1274 case ItemNavigation.Last: {
1276 int rows = items_area.Height / ItemHeight;
1277 if (Items.Count < rows) {
1279 selected_index = Items.Count - 1;
1282 top_index = Items.Count - rows;
1283 selected_index = Items.Count - 1;
1289 case ItemNavigation.Next: {
1290 if (FocusedItem == Items.Count - 1)
1294 ArrayList heights = new ArrayList ();
1295 if (draw_mode == DrawMode.OwnerDrawVariable) {
1296 for (int i = top_index; i <= FocusedItem + 1; i++) {
1297 int h = GetItemHeight (i);
1302 bottom = ((FocusedItem + 1) - top_index + 1) * ItemHeight;
1305 if (bottom >= items_area.Height) {
1306 int overhang = bottom - items_area.Height;
1309 if (draw_mode == DrawMode.OwnerDrawVariable)
1310 while (overhang > 0)
1311 overhang -= (int) heights [offset];
1313 offset = (int) Math.Ceiling ((float)overhang / (float) ItemHeight);
1314 top_index += offset;
1317 selected_index = FocusedItem + 1;
1321 case ItemNavigation.Previous: {
1322 if (FocusedItem > 0) {
1323 if (FocusedItem - 1 < top_index) {
1327 selected_index = FocusedItem - 1;
1332 case ItemNavigation.NextPage: {
1333 if (Items.Count < page_size) {
1334 NavigateItemVisually (ItemNavigation.Last);
1338 if (FocusedItem + page_size - 1 >= Items.Count) {
1339 top_index = Items.Count - page_size;
1341 selected_index = Items.Count - 1;
1344 if (FocusedItem + page_size - 1 > last_visible_index) {
1345 top_index = FocusedItem;
1349 selected_index = FocusedItem + page_size - 1;
1355 case ItemNavigation.PreviousPage: {
1357 int rows = items_area.Height / ItemHeight;
1358 if (FocusedItem - (rows - 1) <= 0) {
1365 if (FocusedItem - (rows - 1) < top_index) {
1366 top_index = FocusedItem - (rows - 1);
1370 selected_index = FocusedItem - (rows - 1);
1379 return selected_index;
1383 private void OnGotFocus (object sender, EventArgs e)
1385 if (FocusedItem != -1)
1386 InvalidateItem (FocusedItem);
1389 private void OnLostFocus (object sender, EventArgs e)
1391 if (FocusedItem != -1)
1392 InvalidateItem (FocusedItem);
1395 private void OnKeyDownLB (object sender, KeyEventArgs e)
1399 if (Items.Count == 0)
1402 switch (e.KeyCode) {
1404 case Keys.ControlKey:
1405 ctrl_pressed = true;
1409 shift_pressed = true;
1413 new_item = NavigateItemVisually (ItemNavigation.First);
1417 new_item = NavigateItemVisually (ItemNavigation.Last);
1421 new_item = NavigateItemVisually (ItemNavigation.Previous);
1425 new_item = NavigateItemVisually (ItemNavigation.Next);
1429 new_item = NavigateItemVisually (ItemNavigation.PreviousPage);
1433 new_item = NavigateItemVisually (ItemNavigation.NextPage);
1437 if (multicolumn == true) {
1438 new_item = NavigateItemVisually (ItemNavigation.NextColumn);
1443 if (multicolumn == true) {
1444 new_item = NavigateItemVisually (ItemNavigation.PreviousColumn);
1449 if (selection_mode == SelectionMode.MultiSimple) {
1450 SelectedItemFromNavigation (FocusedItem);
1459 if (new_item != -1) {
1460 FocusedItem = new_item;
1461 if (selection_mode != SelectionMode.MultiSimple && selection_mode != SelectionMode.None) {
1462 SelectedItemFromNavigation (new_item);
1467 private void OnKeyUpLB (object sender, KeyEventArgs e)
1469 switch (e.KeyCode) {
1470 case Keys.ControlKey:
1471 ctrl_pressed = false;
1474 shift_pressed = false;
1481 internal void InvalidateItem (int index)
1483 Rectangle bounds = GetItemDisplayRectangle (index, top_index);
1484 if (ClientRectangle.IntersectsWith (bounds))
1485 Invalidate (bounds);
1488 internal virtual void OnItemClick (int index)
1490 OnSelectedIndexChanged (EventArgs.Empty);
1491 OnSelectedValueChanged (EventArgs.Empty);
1495 int[] prev_selection;
1496 bool button_pressed = false;
1498 private void SelectExtended (int index)
1502 ArrayList new_selection = new ArrayList ();
1503 int start = anchor < index ? anchor : index;
1504 int end = anchor > index ? anchor : index;
1505 for (int i = start; i <= end; i++)
1506 new_selection.Add (i);
1509 foreach (int i in prev_selection)
1510 if (!selection.Contains (i))
1511 new_selection.Add (i);
1513 foreach (int i in SelectedIndices)
1514 if (!new_selection.Contains (i))
1515 UnSelectItem (i, true);
1517 foreach (int i in new_selection)
1518 if (!SelectedIndices.Contains (i))
1523 private void OnMouseDownLB (object sender, MouseEventArgs e)
1525 int index = IndexAtClientPoint (e.X, e.Y);
1530 switch (SelectionMode) {
1531 case SelectionMode.One:
1532 if (SelectedIndex != index) {
1533 UnSelectItem (SelectedIndex, true);
1536 selected_index = index;
1539 case SelectionMode.MultiSimple:
1540 if (SelectedIndices.Contains (index))
1541 UnSelectItem (index, true);
1546 case SelectionMode.MultiExtended:
1547 shift_pressed = (XplatUI.State.ModifierKeys & Keys.Shift) != 0;
1548 ctrl_pressed = (XplatUI.State.ModifierKeys & Keys.Control) != 0;
1551 prev_selection = new int [selection.Count];
1552 SelectedIndices.CopyTo (prev_selection, 0);
1559 SelectExtended (index);
1562 case SelectionMode.None:
1567 button_pressed = true;
1568 FocusedItem = index;
1571 private void OnMouseMoveLB (object sender, MouseEventArgs e)
1573 if (!button_pressed)
1576 int index = IndexAtClientPoint (e.X, e.Y);
1578 switch (SelectionMode) {
1579 case SelectionMode.One:
1580 if (index == selected_index)
1583 UnSelectItem (SelectedIndex, true);
1585 selected_index = index;
1588 case SelectionMode.MultiSimple:
1591 case SelectionMode.MultiExtended:
1592 SelectExtended (index);
1595 case SelectionMode.None:
1600 FocusedItem = index;
1603 private void OnMouseUpLB (object sender, MouseEventArgs e)
1606 OnDoubleClick (EventArgs.Empty);
1607 else if (e.Clicks == 1)
1608 OnClick (EventArgs.Empty);
1610 if (!button_pressed)
1613 int index = IndexAtClientPoint (e.X, e.Y);
1614 OnItemClick (index);
1615 button_pressed = ctrl_pressed = shift_pressed = false;
1618 private void Scroll (ScrollBar scrollbar, int delta)
1620 if (delta == 0 || !scrollbar.Visible || !scrollbar.Enabled)
1624 if (scrollbar == hscrollbar)
1625 max = hscrollbar.Maximum - (items_area.Width / ColumnWidthInternal) + 1;
1627 max = vscrollbar.Maximum - (items_area.Height / ItemHeight) + 1;
1629 int val = scrollbar.Value + delta;
1632 else if (val < scrollbar.Minimum)
1633 val = scrollbar.Minimum;
1634 scrollbar.Value = val;
1637 private void OnMouseWheelLB (object sender, MouseEventArgs me)
1639 if (Items.Count == 0)
1642 int lines = me.Delta / 120;
1645 Scroll (hscrollbar, -SystemInformation.MouseWheelScrollLines * lines);
1647 Scroll (vscrollbar, -lines);
1650 internal override void OnPaintInternal (PaintEventArgs pevent)
1655 Draw (pevent.ClipRectangle, pevent.Graphics);
1658 internal void RepositionScrollBars ()
1660 if (vscrollbar.is_visible) {
1661 vscrollbar.Size = new Size (vscrollbar.Width, items_area.Height);
1662 vscrollbar.Location = new Point (items_area.Width, 0);
1665 if (hscrollbar.is_visible) {
1666 hscrollbar.Size = new Size (items_area.Width, hscrollbar.Height);
1667 hscrollbar.Location = new Point (0, items_area.Height);
1671 // Add an item in the Selection array and marks it visually as selected
1672 private void SelectItem (int index)
1674 if (index == -1 || SelectedIndices.Contains (index))
1677 selection.Add (Items[index]);
1678 InvalidateItem (index);
1681 // An item navigation operation (mouse or keyboard) has caused to select a new item
1682 internal void SelectedItemFromNavigation (int index)
1684 switch (SelectionMode) {
1685 case SelectionMode.None: // Do nothing
1687 case SelectionMode.One: {
1688 SelectedIndex = index;
1691 case SelectionMode.MultiSimple: {
1692 if (SelectedIndex == -1) {
1693 SelectedIndex = index;
1696 if (SelectedIndices.Contains (index))
1697 UnSelectItem (index, true);
1700 OnSelectedIndexChanged (new EventArgs ());
1701 OnSelectedValueChanged (new EventArgs ());
1707 case SelectionMode.MultiExtended: {
1708 if (SelectedIndex == -1) {
1709 SelectedIndex = index;
1712 if (ctrl_pressed == false && shift_pressed == false) {
1716 if (shift_pressed == true) {
1717 ShiftSelection (index);
1718 } else { // ctrl_pressed or single item
1722 OnSelectedIndexChanged (new EventArgs ());
1723 OnSelectedValueChanged (new EventArgs ());
1733 private void ShiftSelection (int index)
1735 int shorter_item = -1, dist = Items.Count + 1, cur_dist;
1737 foreach (int idx in selected_indices) {
1739 cur_dist = idx - index;
1742 cur_dist = index - idx;
1745 if (cur_dist < dist) {
1751 if (shorter_item != -1) {
1754 if (shorter_item > index) {
1758 start = shorter_item;
1763 for (int idx = start; idx <= end; idx++) {
1769 internal int FocusedItem {
1770 get { return focused_item; }
1772 if (focused_item == value)
1775 int prev = focused_item;
1777 focused_item = value;
1779 if (has_focus == false)
1783 InvalidateItem (prev);
1786 InvalidateItem (value);
1790 // Removes an item in the Selection array and marks it visually as unselected
1791 private void UnSelectItem (int index, bool remove)
1797 selection.Remove (Items[index]);
1799 InvalidateItem (index);
1802 StringFormat string_format;
1803 internal StringFormat StringFormat {
1805 if (string_format == null) {
1806 string_format = new StringFormat ();
1807 if (RightToLeft == RightToLeft.Yes)
1808 string_format.Alignment = StringAlignment.Far;
1810 string_format.Alignment = StringAlignment.Near;
1812 string_format.SetTabStops (0, new float [] {(float)(Font.Height * 3.7)});
1814 return string_format;
1819 internal virtual void CollectionChanged ()
1824 if (Items.Count == 0) {
1825 selected_index = -1;
1830 if (!IsHandleCreated || suspend_layout)
1838 private void UpdateListBoxBounds ()
1840 if (requested_height == -1)
1843 SetBounds(0, 0, 0, requested_height, BoundsSpecified.Height);
1846 private void UpdateScrollBars ()
1848 items_area = ClientRectangle;
1849 if (UpdateHorizontalScrollBar ()) {
1850 items_area.Height -= hscrollbar.Height;
1851 if (UpdateVerticalScrollBar ()) {
1852 items_area.Width -= vscrollbar.Width;
1853 UpdateHorizontalScrollBar ();
1855 } else if (UpdateVerticalScrollBar ()) {
1856 items_area.Width -= vscrollbar.Width;
1857 if (UpdateHorizontalScrollBar ()) {
1858 items_area.Height -= hscrollbar.Height;
1859 UpdateVerticalScrollBar ();
1863 RepositionScrollBars ();
1866 /* Determines if the horizontal scrollbar has to be displyed */
1867 private bool UpdateHorizontalScrollBar ()
1870 bool enabled = true;
1873 if (canvas_size.Width > items_area.Width) {
1875 hscrollbar.Maximum = canvas_size.Width / ColumnWidthInternal - 1;
1876 } else if (ScrollAlwaysVisible == true) {
1879 hscrollbar.Maximum = 0;
1881 } else if (canvas_size.Width > ClientRectangle.Width && HorizontalScrollbar) {
1883 hscrollbar.Maximum = canvas_size.Width;
1884 hscrollbar.LargeChange = items_area.Width;
1887 hbar_offset = hscrollbar.Value;
1888 hscrollbar.Enabled = enabled;
1889 hscrollbar.Visible = show;
1894 /* Determines if the vertical scrollbar has to be displyed */
1895 private bool UpdateVerticalScrollBar ()
1897 if (MultiColumn || Items.Count == 0) {
1898 vscrollbar.Visible = false;
1903 bool enabled = true;
1904 if (canvas_size.Height > items_area.Height) {
1906 vscrollbar.Maximum = Items.Count - 1;
1907 vscrollbar.LargeChange = items_area.Height / ItemHeight;
1908 } else if (ScrollAlwaysVisible) {
1911 vscrollbar.Maximum = 0;
1914 vscrollbar.Enabled = enabled;
1915 vscrollbar.Visible = show;
1921 private void VerticalScrollEvent (object sender, EventArgs e)
1923 int top_item = top_index;
1925 top_index = /*row_count + */ vscrollbar.Value;
1926 last_visible_index = LastVisibleItem ();
1928 int diff = top_item - top_index;
1930 XplatUI.ScrollWindow (Handle, items_area, 0, ItemHeight * diff, false);
1933 #endregion Private Methods
1935 [ListBindable (false)]
1936 public class ObjectCollection : IList, ICollection, IEnumerable
1938 internal class ListObjectComparer : IComparer
1940 public int Compare (object a, object b)
1942 string str1 = a.ToString ();
1943 string str2 = b.ToString ();
1944 return str1.CompareTo (str2);
1948 private ListBox owner;
1949 internal ArrayList object_items = new ArrayList ();
1951 public ObjectCollection (ListBox owner)
1956 public ObjectCollection (ListBox owner, object[] obj)
1962 public ObjectCollection (ListBox owner, ObjectCollection obj)
1968 #region Public Properties
1970 get { return object_items.Count; }
1973 public bool IsReadOnly {
1974 get { return false; }
1978 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
1979 public virtual object this [int index] {
1981 if (index < 0 || index >= Count)
1982 throw new ArgumentOutOfRangeException ("Index of out range");
1984 return object_items[index];
1987 if (index < 0 || index >= Count)
1988 throw new ArgumentOutOfRangeException ("Index of out range");
1990 throw new ArgumentNullException ("value");
1992 object_items[index] = value;
1993 owner.CollectionChanged ();
1997 bool ICollection.IsSynchronized {
1998 get { return false; }
2001 object ICollection.SyncRoot {
2002 get { return this; }
2005 bool IList.IsFixedSize {
2006 get { return false; }
2009 #endregion Public Properties
2011 #region Public Methods
2012 public int Add (object item)
2016 idx = AddItem (item);
2017 owner.CollectionChanged ();
2021 public void AddRange (object[] items)
2023 foreach (object mi in items)
2026 owner.CollectionChanged ();
2029 public void AddRange (ObjectCollection col)
2031 foreach (object mi in col)
2034 owner.CollectionChanged ();
2037 internal void AddRange (IList list)
2039 foreach (object mi in list)
2042 owner.CollectionChanged ();
2045 public virtual void Clear ()
2047 owner.selection.Clear ();
2048 object_items.Clear ();
2049 owner.CollectionChanged ();
2051 public bool Contains (object obj)
2053 return object_items.Contains (obj);
2056 public void CopyTo (object[] dest, int arrayIndex)
2058 object_items.CopyTo (dest, arrayIndex);
2061 void ICollection.CopyTo (Array dest, int index)
2063 object_items.CopyTo (dest, index);
2066 public IEnumerator GetEnumerator ()
2068 return object_items.GetEnumerator ();
2071 int IList.Add (object item)
2076 public int IndexOf (object value)
2078 return object_items.IndexOf (value);
2081 public void Insert (int index, object item)
2083 if (index < 0 || index > Count)
2084 throw new ArgumentOutOfRangeException ("Index of out range");
2086 owner.BeginUpdate ();
2087 object_items.Insert (index, item);
2088 owner.CollectionChanged ();
2092 public void Remove (object value)
2094 RemoveAt (IndexOf (value));
2097 public void RemoveAt (int index)
2099 if (index < 0 || index >= Count)
2100 throw new ArgumentOutOfRangeException ("Index of out range");
2102 owner.selection.Remove (object_items [index]);
2103 object_items.RemoveAt (index);
2104 owner.CollectionChanged ();
2106 #endregion Public Methods
2108 #region Private Methods
2109 internal int AddItem (object item)
2112 throw new ArgumentNullException ("item");
2114 int cnt = object_items.Count;
2115 object_items.Add (item);
2119 internal void Sort ()
2121 object_items.Sort (new ListObjectComparer ());
2124 #endregion Private Methods
2127 public class SelectedIndexCollection : IList, ICollection, IEnumerable
2129 private ListBox owner;
2131 public SelectedIndexCollection (ListBox owner)
2136 #region Public Properties
2139 get { return owner.selection.Count; }
2142 public bool IsReadOnly {
2143 get { return true; }
2146 public int this [int index] {
2148 if (index < 0 || index >= Count)
2149 throw new ArgumentOutOfRangeException ("Index of out range");
2151 return owner.Items.IndexOf (owner.selection [index]);
2155 bool ICollection.IsSynchronized {
2156 get { return true; }
2159 bool IList.IsFixedSize{
2160 get { return true; }
2163 object ICollection.SyncRoot {
2164 get { return this; }
2167 #endregion Public Properties
2169 #region Public Methods
2170 public bool Contains (int selectedIndex)
2172 foreach (object o in owner.selection)
2173 if (owner.Items.IndexOf (o) == selectedIndex)
2178 public void CopyTo (Array dest, int index)
2180 foreach (object o in owner.selection)
2181 dest.SetValue(owner.Items.IndexOf (o), index++);
2184 public IEnumerator GetEnumerator ()
2186 //FIXME: write an enumerator that uses owner.selection.GetEnumerator
2187 // so that invalidation is write on selection changes
2188 ArrayList indices = new ArrayList ();
2189 foreach (object o in owner.selection)
2190 indices.Add (owner.Items.IndexOf (o));
2191 return indices.GetEnumerator ();
2194 int IList.Add (object obj)
2196 throw new NotSupportedException ();
2201 throw new NotSupportedException ();
2204 bool IList.Contains (object selectedIndex)
2206 return Contains ((int)selectedIndex);
2209 int IList.IndexOf (object selectedIndex)
2211 return IndexOf ((int) selectedIndex);
2214 void IList.Insert (int index, object value)
2216 throw new NotSupportedException ();
2219 void IList.Remove (object value)
2221 throw new NotSupportedException ();
2224 void IList.RemoveAt (int index)
2226 throw new NotSupportedException ();
2229 object IList.this[int index]{
2230 get {return owner.Items.IndexOf (owner.selection [index]); }
2231 set {throw new NotImplementedException (); }
2234 public int IndexOf (int selectedIndex)
2236 for (int i = 0; i < owner.selection.Count; i++)
2237 if (owner.Items.IndexOf (owner.selection [i]) == selectedIndex)
2241 #endregion Public Methods
2244 public class SelectedObjectCollection : IList, ICollection, IEnumerable
2246 private ListBox owner;
2248 public SelectedObjectCollection (ListBox owner)
2253 #region Public Properties
2255 get { return owner.selection.Count; }
2258 public bool IsReadOnly {
2259 get { return true; }
2263 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
2264 public object this [int index] {
2266 if (index < 0 || index >= Count)
2267 throw new ArgumentOutOfRangeException ("Index of out range");
2269 return owner.selection [index];
2271 set {throw new NotSupportedException ();}
2274 bool ICollection.IsSynchronized {
2275 get { return true; }
2278 object ICollection.SyncRoot {
2279 get { return this; }
2282 bool IList.IsFixedSize {
2283 get { return true; }
2286 #endregion Public Properties
2288 #region Public Methods
2289 public bool Contains (object selectedObject)
2291 return owner.selection.Contains (selectedObject);
2294 public void CopyTo (Array dest, int index)
2296 owner.selection.CopyTo (dest, index);
2299 int IList.Add (object value)
2301 throw new NotSupportedException ();
2306 throw new NotSupportedException ();
2309 void IList.Insert (int index, object value)
2311 throw new NotSupportedException ();
2314 void IList.Remove (object value)
2316 throw new NotSupportedException ();
2319 void IList.RemoveAt (int index)
2321 throw new NotSupportedException ();
2324 public int IndexOf (object item)
2326 return owner.selection.IndexOf (item);
2329 public IEnumerator GetEnumerator ()
2331 return owner.selection.GetEnumerator ();
2334 #endregion Public Methods