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);
123 Controls.AddImplicit (vscrollbar);
124 Controls.AddImplicit (hscrollbar);
127 MouseDown += new MouseEventHandler (OnMouseDownLB);
128 MouseMove += new MouseEventHandler (OnMouseMoveLB);
129 MouseUp += new MouseEventHandler (OnMouseUpLB);
130 MouseWheel += new MouseEventHandler (OnMouseWheelLB);
131 KeyDown += new KeyEventHandler (OnKeyDownLB);
132 KeyUp += new KeyEventHandler (OnKeyUpLB);
133 GotFocus += new EventHandler (OnGotFocus);
134 LostFocus += new EventHandler (OnLostFocus);
136 SetStyle (ControlStyles.UserPaint, false);
140 static object DrawItemEvent = new object ();
141 static object MeasureItemEvent = new object ();
142 static object SelectedIndexChangedEvent = new object ();
145 [EditorBrowsable (EditorBrowsableState.Never)]
146 public new event EventHandler BackgroundImageChanged {
147 add { base.BackgroundImageChanged += value; }
148 remove { base.BackgroundImageChanged -= value; }
153 [EditorBrowsable (EditorBrowsableState.Always)]
156 [EditorBrowsable (EditorBrowsableState.Advanced)]
158 public new event EventHandler Click {
159 add { base.Click += value; }
160 remove { base.Click -= value; }
163 public event DrawItemEventHandler DrawItem {
164 add { Events.AddHandler (DrawItemEvent, value); }
165 remove { Events.RemoveHandler (DrawItemEvent, value); }
168 public event MeasureItemEventHandler MeasureItem {
169 add { Events.AddHandler (MeasureItemEvent, value); }
170 remove { Events.RemoveHandler (MeasureItemEvent, value); }
174 [EditorBrowsable (EditorBrowsableState.Never)]
175 public new event PaintEventHandler Paint {
176 add { base.Paint += value; }
177 remove { base.Paint -= value; }
180 public event EventHandler SelectedIndexChanged {
181 add { Events.AddHandler (SelectedIndexChangedEvent, value); }
182 remove { Events.RemoveHandler (SelectedIndexChangedEvent, value); }
186 [EditorBrowsable (EditorBrowsableState.Advanced)]
187 public new event EventHandler TextChanged {
188 add { base.TextChanged += value; }
189 remove { base.TextChanged -= value; }
193 #region Public Properties
194 public override Color BackColor {
195 get { return base.BackColor; }
197 if (base.BackColor == value)
200 base.BackColor = value;
201 base.Refresh (); // Careful. Calling the base method is not the same that calling
202 } // the overriden one that refresh also all the items
206 [EditorBrowsable (EditorBrowsableState.Never)]
207 public override Image BackgroundImage {
208 get { return base.BackgroundImage; }
210 base.BackgroundImage = value;
215 [DefaultValue (BorderStyle.Fixed3D)]
217 public BorderStyle BorderStyle {
218 get { return InternalBorderStyle; }
220 InternalBorderStyle = value;
221 UpdateListBoxBounds ();
227 public int ColumnWidth {
228 get { return column_width; }
231 throw new ArgumentException ("A value less than zero is assigned to the property.");
233 column_width = value;
236 ColumnWidthInternal = 120;
238 ColumnWidthInternal = value;
244 protected override CreateParams CreateParams {
245 get { return base.CreateParams;}
248 protected override Size DefaultSize {
249 get { return new Size (120, 96); }
252 [RefreshProperties(RefreshProperties.Repaint)]
253 [DefaultValue (DrawMode.Normal)]
254 public virtual DrawMode DrawMode {
255 get { return draw_mode; }
258 if (!Enum.IsDefined (typeof (DrawMode), value))
259 throw new InvalidEnumArgumentException (string.Format("Enum argument value '{0}' is not valid for DrawMode", value));
261 if (value == DrawMode.OwnerDrawVariable && multicolumn == true)
262 throw new ArgumentException ("Cannot have variable height and multicolumn");
264 if (draw_mode == value)
269 if (draw_mode == DrawMode.OwnerDrawVariable)
270 item_heights = new Hashtable ();
278 public override Color ForeColor {
279 get { return base.ForeColor; }
282 if (base.ForeColor == value)
285 base.ForeColor = value;
292 public int HorizontalExtent {
293 get { return horizontal_extent; }
295 if (horizontal_extent == value)
298 horizontal_extent = value;
303 [DefaultValue (false)]
305 public bool HorizontalScrollbar {
306 get { return horizontal_scrollbar; }
308 if (horizontal_scrollbar == value)
311 horizontal_scrollbar = value;
317 [DefaultValue (true)]
319 [RefreshProperties(RefreshProperties.Repaint)]
320 public bool IntegralHeight {
321 get { return integral_height; }
323 if (integral_height == value)
326 integral_height = value;
327 UpdateListBoxBounds ();
333 [RefreshProperties(RefreshProperties.Repaint)]
334 public virtual int ItemHeight {
336 if (item_height == -1) {
337 SizeF sz = DeviceContext.MeasureString ("The quick brown Fox", Font);
338 item_height = (int) sz.Height;
344 throw new ArgumentOutOfRangeException ("The ItemHeight property was set beyond 255 pixels");
346 explicit_item_height = true;
347 if (item_height == value)
352 UpdateListBoxBounds ();
357 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
359 [Editor ("System.Windows.Forms.Design.ListControlStringCollectionEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
361 [MergableProperty (false)]
363 public ObjectCollection Items {
364 get { return items; }
367 [DefaultValue (false)]
368 public bool MultiColumn {
369 get { return multicolumn; }
371 if (multicolumn == value)
374 if (value == true && DrawMode == DrawMode.OwnerDrawVariable)
375 throw new ArgumentException ("A multicolumn ListBox cannot have a variable-sized height.");
383 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
384 [EditorBrowsable (EditorBrowsableState.Advanced)]
385 public int PreferredHeight {
388 if (draw_mode == DrawMode.Normal)
389 itemsHeight = FontHeight * items.Count;
390 else if (draw_mode == DrawMode.OwnerDrawFixed)
391 itemsHeight = ItemHeight * items.Count;
392 else if (draw_mode == DrawMode.OwnerDrawVariable) {
393 for (int i = 0; i < items.Count; i++)
394 itemsHeight += (int) item_heights [Items [i]];
401 public override RightToLeft RightToLeft {
402 get { return base.RightToLeft; }
404 base.RightToLeft = value;
405 if (base.RightToLeft == RightToLeft.Yes)
406 StringFormat.Alignment = StringAlignment.Far;
408 StringFormat.Alignment = StringAlignment.Near;
413 // Only affects the Vertical ScrollBar
414 [DefaultValue (false)]
416 public bool ScrollAlwaysVisible {
417 get { return scroll_always_visible; }
419 if (scroll_always_visible == value)
422 scroll_always_visible = value;
429 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
430 public override int SelectedIndex {
431 get { return selected_index;}
433 if (value < -1 || value >= Items.Count)
434 throw new ArgumentOutOfRangeException ("Index of out range");
436 if (SelectionMode == SelectionMode.None)
437 throw new ArgumentException ("cannot call this method if SelectionMode is SelectionMode.None");
439 if (selected_index == value)
444 else if (SelectionMode == SelectionMode.One)
445 UnSelectItem (selected_index, true);
447 if (value < top_index)
452 int rows = items_area.Height / ItemHeight;
453 if (value >= (top_index + rows))
455 top_index = value - rows + 1;
460 selected_index = value;
462 OnSelectedIndexChanged (new EventArgs ());
463 OnSelectedValueChanged (new EventArgs ());
468 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
469 public SelectedIndexCollection SelectedIndices {
470 get { return selected_indices; }
475 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
476 public object SelectedItem {
478 if (SelectedItems.Count > 0)
479 return SelectedItems[0];
484 if (value != null && !Items.Contains (value))
485 return; // FIXME: this is probably an exception
487 SelectedIndex = value == null ? - 1 : Items.IndexOf (value);
492 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
493 public SelectedObjectCollection SelectedItems {
494 get {return selected_items;}
497 [DefaultValue (SelectionMode.One)]
498 public virtual SelectionMode SelectionMode {
499 get { return selection_mode; }
501 if (!Enum.IsDefined (typeof (SelectionMode), value))
502 throw new InvalidEnumArgumentException (string.Format("Enum argument value '{0}' is not valid for SelectionMode", value));
504 if (selection_mode == value)
507 selection_mode = value;
509 switch (selection_mode) {
510 case SelectionMode.None:
514 case SelectionMode.One:
515 while (SelectedIndices.Count > 1)
516 UnSelectItem (SelectedIndices [SelectedIndices.Count - 1], true);
525 [DefaultValue (false)]
527 get { return sorted; }
541 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
542 [EditorBrowsable (EditorBrowsableState.Advanced)]
543 public override string Text {
545 if (SelectionMode != SelectionMode.None && SelectedIndex != -1)
546 return GetItemText (SelectedItem);
554 if (SelectionMode == SelectionMode.None)
559 index = FindStringExact (value);
564 SelectedIndex = index;
569 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
570 public int TopIndex {
571 get { return top_index; }
573 if (value == top_index)
576 if (value < 0 || value >= Items.Count)
585 [DefaultValue (true)]
586 public bool UseTabStops {
587 get { return use_tabstops; }
590 if (use_tabstops == value)
593 use_tabstops = value;
595 StringFormat.SetTabStops (0, new float [] {(float)(Font.Height * 3.7)});
597 StringFormat.SetTabStops (0, new float [0]);
603 protected override bool AllowSelection {
605 return SelectionMode != SelectionMode.None;
610 #endregion Public Properties
612 #region Private Properties
614 private int ColumnWidthInternal {
615 get { return column_width_internal; }
616 set { column_width_internal = value; }
619 private int row_count = 1;
620 private int RowCount {
622 return MultiColumn ? row_count : Items.Count;
626 #endregion Private Properties
628 #region Public Methods
630 [Obsolete ("this method has been deprecated")]
632 protected virtual void AddItemsCore (object[] value)
634 Items.AddRange (value);
637 public void BeginUpdate ()
639 suspend_layout = true;
642 public void ClearSelected ()
644 foreach (int i in selected_indices) {
645 UnSelectItem (i, false);
651 protected virtual ObjectCollection CreateItemCollection ()
653 return new ObjectCollection (this);
656 public void EndUpdate ()
658 suspend_layout = false;
663 public int FindString (String s)
665 return FindString (s, -1);
668 public int FindString (string s, int startIndex)
670 if (Items.Count == 0)
671 return -1; // No exception throwing if empty
673 if (startIndex < -1 || startIndex >= Items.Count - 1)
674 throw new ArgumentOutOfRangeException ("Index of out range");
677 for (int i = startIndex; i < Items.Count; i++) {
678 if ((GetItemText (Items[i])).StartsWith (s))
685 public int FindStringExact (string s)
687 return FindStringExact (s, -1);
690 public int FindStringExact (string s, int startIndex)
692 if (Items.Count == 0)
693 return -1; // No exception throwing if empty
695 if (startIndex < -1 || startIndex >= Items.Count - 1)
696 throw new ArgumentOutOfRangeException ("Index of out range");
699 for (int i = startIndex; i < Items.Count; i++) {
700 if ((GetItemText (Items[i])).Equals (s))
707 public int GetItemHeight (int index)
709 if (index < 0 || index >= Items.Count)
710 throw new ArgumentOutOfRangeException ("Index of out range");
712 if (DrawMode == DrawMode.OwnerDrawVariable && IsHandleCreated == true) {
714 object o = Items [index];
715 if (item_heights.Contains (o))
716 return (int) item_heights [o];
718 MeasureItemEventArgs args = new MeasureItemEventArgs (DeviceContext, index, ItemHeight);
719 OnMeasureItem (args);
720 item_heights [o] = args.ItemHeight;
721 return args.ItemHeight;
727 public Rectangle GetItemRectangle (int index)
729 if (index < 0 || index >= Items.Count)
730 throw new ArgumentOutOfRangeException ("GetItemRectangle index out of range.");
732 Rectangle rect = new Rectangle ();
735 int col = index / RowCount;
736 rect.Y = ((index - top_index) % RowCount) * ItemHeight;
737 rect.X = col * ColumnWidthInternal;
738 rect.Height = ItemHeight;
739 rect.Width = ColumnWidthInternal;
742 rect.Height = GetItemHeight (index);
743 rect.Width = items_area.Width;
745 if (DrawMode == DrawMode.OwnerDrawVariable) {
747 if (index >= top_index) {
748 for (int i = top_index; i < index; i++) {
749 rect.Y += GetItemHeight (i);
752 for (int i = index; i < top_index; i++) {
753 rect.Y -= GetItemHeight (i);
757 rect.Y = ItemHeight * (index - top_index);
764 public bool GetSelected (int index)
766 if (index < 0 || index >= Items.Count)
767 throw new ArgumentOutOfRangeException ("Index of out range");
769 return SelectedIndices.Contains (index);
772 public int IndexFromPoint (Point p)
774 return IndexFromPoint (p.X, p.Y);
777 // Only returns visible points
778 public int IndexFromPoint (int x, int y)
781 if (Items.Count == 0) {
785 for (int i = top_index; i <= last_visible_index; i++) {
786 if (GetItemRectangle (i).Contains (x,y) == true)
793 protected override void OnChangeUICues (UICuesEventArgs e)
795 base.OnChangeUICues (e);
798 protected override void OnDataSourceChanged (EventArgs e)
800 base.OnDataSourceChanged (e);
803 if (DataSource == null || DataManager == null) {
807 SelectedIndex = DataManager.Position;
811 protected override void OnDisplayMemberChanged (EventArgs e)
813 base.OnDisplayMemberChanged (e);
815 if (DataManager == null || !IsHandleCreated)
822 protected virtual void OnDrawItem (DrawItemEventArgs e)
825 case DrawMode.OwnerDrawFixed:
826 case DrawMode.OwnerDrawVariable:
827 DrawItemEventHandler eh = (DrawItemEventHandler)(Events [DrawItemEvent]);
834 ThemeEngine.Current.DrawListBoxItem (this, e);
839 protected override void OnFontChanged (EventArgs e)
841 base.OnFontChanged (e);
844 StringFormat.SetTabStops (0, new float [] {(float)(Font.Height * 3.7)});
846 if (explicit_item_height) {
849 SizeF sz = DeviceContext.MeasureString ("The quick brown Fox", Font);
850 item_height = (int) sz.Height;
852 UpdateListBoxBounds ();
857 protected override void OnHandleCreated (EventArgs e)
859 base.OnHandleCreated (e);
863 protected override void OnHandleDestroyed (EventArgs e)
865 base.OnHandleDestroyed (e);
868 protected virtual void OnMeasureItem (MeasureItemEventArgs e)
870 if (draw_mode != DrawMode.OwnerDrawVariable)
873 MeasureItemEventHandler eh = (MeasureItemEventHandler)(Events [MeasureItemEvent]);
878 protected override void OnParentChanged (EventArgs e)
880 base.OnParentChanged (e);
883 protected override void OnResize (EventArgs e)
886 if (canvas_size.IsEmpty || MultiColumn)
890 protected override void OnSelectedIndexChanged (EventArgs e)
892 base.OnSelectedIndexChanged (e);
894 EventHandler eh = (EventHandler)(Events [SelectedIndexChangedEvent]);
899 protected override void OnSelectedValueChanged (EventArgs e)
901 base.OnSelectedValueChanged (e);
904 public override void Refresh ()
906 if (draw_mode == DrawMode.OwnerDrawVariable)
907 item_heights.Clear ();
912 protected override void RefreshItem (int index)
914 if (index < 0 || index >= Items.Count)
915 throw new ArgumentOutOfRangeException ("Index of out range");
917 if (draw_mode == DrawMode.OwnerDrawVariable)
918 item_heights.Remove (Items [index]);
921 protected override void SetBoundsCore (int x, int y, int width, int height, BoundsSpecified specified)
923 if ((specified & BoundsSpecified.Height) == BoundsSpecified.Height)
924 requested_height = height;
926 if (IntegralHeight) {
928 switch (border_style) {
929 case BorderStyle.Fixed3D:
930 border = ThemeEngine.Current.Border3DSize.Height;
932 case BorderStyle.FixedSingle:
933 border = ThemeEngine.Current.BorderSize.Height;
935 case BorderStyle.None:
940 height -= (2 * border);
941 height -= height % ItemHeight;
942 height += (2 * border);
945 base.SetBoundsCore (x, y, width, height, specified);
949 protected override void SetItemCore (int index, object value)
951 if (index < 0 || index >= Items.Count)
954 Items[index] = value;
957 protected override void SetItemsCore (IList value)
962 Items.AddRange (value);
968 public void SetSelected (int index, bool value)
970 if (index < 0 || index >= Items.Count)
971 throw new ArgumentOutOfRangeException ("Index of out range");
973 if (SelectionMode == SelectionMode.None)
974 throw new InvalidOperationException ();
979 UnSelectItem (index, true);
982 protected virtual void Sort ()
984 if (Items.Count == 0)
991 public override string ToString ()
993 return base.ToString ();
996 protected virtual void WmReflectCommand (ref Message m)
1000 protected override void WndProc (ref Message m)
1002 base.WndProc (ref m);
1005 #endregion Public Methods
1007 #region Private Methods
1009 private Size canvas_size;
1011 private void LayoutListBox ()
1013 if (!IsHandleCreated || suspend_layout)
1017 LayoutMultiColumn ();
1019 LayoutSingleColumn ();
1021 UpdateScrollBars ();
1022 last_visible_index = LastVisibleItem ();
1025 private void LayoutSingleColumn ()
1030 case DrawMode.OwnerDrawVariable:
1032 width = HorizontalExtent;
1033 for (int i = 0; i < Items.Count; i++) {
1034 height += GetItemHeight (i);
1038 case DrawMode.OwnerDrawFixed:
1039 height = Items.Count * ItemHeight;
1040 width = HorizontalExtent;
1043 case DrawMode.Normal:
1045 height = Items.Count * ItemHeight;
1047 for (int i = 0; i < Items.Count; i++) {
1048 SizeF sz = DeviceContext.MeasureString (GetItemText (Items[i]), Font);
1049 if ((int) sz.Width > width)
1050 width = (int) sz.Width;
1055 canvas_size = new Size (width, height);
1058 private void LayoutMultiColumn ()
1060 int usable_height = ClientRectangle.Height - (ScrollAlwaysVisible ? hscrollbar.Height : 0);
1061 row_count = usable_height / ItemHeight;
1064 int cols = (int) Math.Ceiling ((float)Items.Count / (float) row_count);
1065 Size sz = new Size (cols * ColumnWidthInternal, row_count * ItemHeight);
1066 if (!ScrollAlwaysVisible && sz.Width > ClientRectangle.Width && row_count > 1) {
1067 usable_height = ClientRectangle.Height - hscrollbar.Height;
1068 row_count = usable_height / ItemHeight;
1069 cols = (int) Math.Ceiling ((float)Items.Count / (float) row_count);
1070 sz = new Size (cols * ColumnWidthInternal, row_count * ItemHeight);
1075 internal void Draw (Rectangle clip, Graphics dc)
1077 Theme theme = ThemeEngine.Current;
1079 if (hscrollbar.Visible && vscrollbar.Visible) {
1080 // Paint the dead space in the bottom right corner
1081 Rectangle rect = new Rectangle (hscrollbar.Right, vscrollbar.Bottom, vscrollbar.Width, hscrollbar.Height);
1082 if (rect.IntersectsWith (clip))
1083 dc.FillRectangle (theme.ResPool.GetSolidBrush (theme.ColorControl), rect);
1086 dc.FillRectangle (theme.ResPool.GetSolidBrush (BackColor), items_area);
1088 if (Items.Count == 0)
1091 for (int i = top_index; i <= last_visible_index; i++) {
1092 Rectangle rect = GetItemDisplayRectangle (i, top_index);
1094 if (!clip.IntersectsWith (rect))
1097 DrawItemState state = DrawItemState.None;
1099 if (SelectedIndices.Contains (i))
1100 state |= DrawItemState.Selected;
1102 if (has_focus && FocusedItem == i)
1103 state |= DrawItemState.Focus;
1105 if (MultiColumn == false && hscrollbar != null && hscrollbar.Visible) {
1106 rect.X -= hscrollbar.Value;
1107 rect.Width += hscrollbar.Value;
1110 OnDrawItem (new DrawItemEventArgs (dc, Font, rect, i, state, ForeColor, BackColor));
1114 // Converts a GetItemRectangle to a one that we can display
1115 internal Rectangle GetItemDisplayRectangle (int index, int first_displayble)
1117 Rectangle item_rect;
1118 Rectangle first_item_rect = GetItemRectangle (first_displayble);
1119 item_rect = GetItemRectangle (index);
1120 item_rect.X -= first_item_rect.X;
1121 item_rect.Y -= first_item_rect.Y;
1127 private void HorizontalScrollEvent (object sender, EventArgs e)
1130 int top_item = top_index;
1131 int last_item = last_visible_index;
1133 top_index = RowCount * hscrollbar.Value;
1134 last_visible_index = LastVisibleItem ();
1136 if (top_item != top_index || last_item != last_visible_index)
1137 Invalidate (items_area);
1140 int old_offset = hbar_offset;
1141 hbar_offset = hscrollbar.Value;
1143 if (hbar_offset < 0)
1146 if (IsHandleCreated)
1147 XplatUI.ScrollWindow (Handle, items_area, old_offset - hbar_offset, 0, false);
1151 // Only returns visible points. The diference of with IndexFromPoint is that the rectangle
1152 // has screen coordinates
1153 private int IndexAtClientPoint (int x, int y)
1155 if (Items.Count == 0)
1160 else if (x > ClientRectangle.Right)
1161 x = ClientRectangle.Right;
1165 else if (y > ClientRectangle.Bottom)
1166 y = ClientRectangle.Bottom;
1168 for (int i = top_index; i <= last_visible_index; i++)
1169 if (GetItemDisplayRectangle (i, top_index).Contains (x, y))
1175 private int LastVisibleItem ()
1177 Rectangle item_rect;
1178 int top_y = items_area.Y + items_area.Height;
1181 if (top_index >= Items.Count)
1184 for (i = top_index; i < Items.Count; i++) {
1186 item_rect = GetItemDisplayRectangle (i, top_index);
1189 if (item_rect.X > items_area.Width)
1193 if (item_rect.Y + item_rect.Height > top_y) {
1201 private void UpdateTopItem ()
1204 int col = top_index / RowCount;
1206 if (col > hscrollbar.Maximum)
1207 hscrollbar.Value = hscrollbar.Maximum;
1209 hscrollbar.Value = col;
1211 int val = vscrollbar.Value;
1212 if (top_index > vscrollbar.Maximum)
1213 vscrollbar.Value = vscrollbar.Maximum;
1215 vscrollbar.Value = top_index;
1216 Scroll (vscrollbar, vscrollbar.Value - top_index);
1217 if (IsHandleCreated)
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 if (IsHandleCreated)
1931 XplatUI.ScrollWindow (Handle, items_area, 0, ItemHeight * diff, false);
1934 #endregion Private Methods
1936 [ListBindable (false)]
1937 public class ObjectCollection : IList, ICollection, IEnumerable
1939 internal class ListObjectComparer : IComparer
1941 public int Compare (object a, object b)
1943 string str1 = a.ToString ();
1944 string str2 = b.ToString ();
1945 return str1.CompareTo (str2);
1949 private ListBox owner;
1950 internal ArrayList object_items = new ArrayList ();
1952 public ObjectCollection (ListBox owner)
1957 public ObjectCollection (ListBox owner, object[] obj)
1963 public ObjectCollection (ListBox owner, ObjectCollection obj)
1969 #region Public Properties
1971 get { return object_items.Count; }
1974 public bool IsReadOnly {
1975 get { return false; }
1979 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
1980 public virtual object this [int index] {
1982 if (index < 0 || index >= Count)
1983 throw new ArgumentOutOfRangeException ("Index of out range");
1985 return object_items[index];
1988 if (index < 0 || index >= Count)
1989 throw new ArgumentOutOfRangeException ("Index of out range");
1991 throw new ArgumentNullException ("value");
1993 object_items[index] = value;
1994 owner.CollectionChanged ();
1998 bool ICollection.IsSynchronized {
1999 get { return false; }
2002 object ICollection.SyncRoot {
2003 get { return this; }
2006 bool IList.IsFixedSize {
2007 get { return false; }
2010 #endregion Public Properties
2012 #region Public Methods
2013 public int Add (object item)
2017 idx = AddItem (item);
2018 owner.CollectionChanged ();
2022 public void AddRange (object[] items)
2024 foreach (object mi in items)
2027 owner.CollectionChanged ();
2030 public void AddRange (ObjectCollection col)
2032 foreach (object mi in col)
2035 owner.CollectionChanged ();
2038 internal void AddRange (IList list)
2040 foreach (object mi in list)
2043 owner.CollectionChanged ();
2046 public virtual void Clear ()
2048 owner.selection.Clear ();
2049 object_items.Clear ();
2050 owner.CollectionChanged ();
2052 public bool Contains (object obj)
2054 return object_items.Contains (obj);
2057 public void CopyTo (object[] dest, int arrayIndex)
2059 object_items.CopyTo (dest, arrayIndex);
2062 void ICollection.CopyTo (Array dest, int index)
2064 object_items.CopyTo (dest, index);
2067 public IEnumerator GetEnumerator ()
2069 return object_items.GetEnumerator ();
2072 int IList.Add (object item)
2077 public int IndexOf (object value)
2079 return object_items.IndexOf (value);
2082 public void Insert (int index, object item)
2084 if (index < 0 || index > Count)
2085 throw new ArgumentOutOfRangeException ("Index of out range");
2087 owner.BeginUpdate ();
2088 object_items.Insert (index, item);
2089 owner.CollectionChanged ();
2093 public void Remove (object value)
2095 RemoveAt (IndexOf (value));
2098 public void RemoveAt (int index)
2100 if (index < 0 || index >= Count)
2101 throw new ArgumentOutOfRangeException ("Index of out range");
2103 owner.selection.Remove (object_items [index]);
2104 object_items.RemoveAt (index);
2105 owner.CollectionChanged ();
2107 #endregion Public Methods
2109 #region Private Methods
2110 internal int AddItem (object item)
2113 throw new ArgumentNullException ("item");
2115 int cnt = object_items.Count;
2116 object_items.Add (item);
2120 internal void Sort ()
2122 object_items.Sort (new ListObjectComparer ());
2125 #endregion Private Methods
2128 public class SelectedIndexCollection : IList, ICollection, IEnumerable
2130 private ListBox owner;
2132 public SelectedIndexCollection (ListBox owner)
2137 #region Public Properties
2140 get { return owner.selection.Count; }
2143 public bool IsReadOnly {
2144 get { return true; }
2147 public int this [int index] {
2149 if (index < 0 || index >= Count)
2150 throw new ArgumentOutOfRangeException ("Index of out range");
2152 return owner.Items.IndexOf (owner.selection [index]);
2156 bool ICollection.IsSynchronized {
2157 get { return true; }
2160 bool IList.IsFixedSize{
2161 get { return true; }
2164 object ICollection.SyncRoot {
2165 get { return this; }
2168 #endregion Public Properties
2170 #region Public Methods
2171 public bool Contains (int selectedIndex)
2173 foreach (object o in owner.selection)
2174 if (owner.Items.IndexOf (o) == selectedIndex)
2179 public void CopyTo (Array dest, int index)
2181 foreach (object o in owner.selection)
2182 dest.SetValue(owner.Items.IndexOf (o), index++);
2185 public IEnumerator GetEnumerator ()
2187 //FIXME: write an enumerator that uses owner.selection.GetEnumerator
2188 // so that invalidation is write on selection changes
2189 ArrayList indices = new ArrayList ();
2190 foreach (object o in owner.selection)
2191 indices.Add (owner.Items.IndexOf (o));
2192 return indices.GetEnumerator ();
2195 int IList.Add (object obj)
2197 throw new NotSupportedException ();
2202 throw new NotSupportedException ();
2205 bool IList.Contains (object selectedIndex)
2207 return Contains ((int)selectedIndex);
2210 int IList.IndexOf (object selectedIndex)
2212 return IndexOf ((int) selectedIndex);
2215 void IList.Insert (int index, object value)
2217 throw new NotSupportedException ();
2220 void IList.Remove (object value)
2222 throw new NotSupportedException ();
2225 void IList.RemoveAt (int index)
2227 throw new NotSupportedException ();
2230 object IList.this[int index]{
2231 get {return owner.Items.IndexOf (owner.selection [index]); }
2232 set {throw new NotImplementedException (); }
2235 public int IndexOf (int selectedIndex)
2237 for (int i = 0; i < owner.selection.Count; i++)
2238 if (owner.Items.IndexOf (owner.selection [i]) == selectedIndex)
2242 #endregion Public Methods
2245 public class SelectedObjectCollection : IList, ICollection, IEnumerable
2247 private ListBox owner;
2249 public SelectedObjectCollection (ListBox owner)
2254 #region Public Properties
2256 get { return owner.selection.Count; }
2259 public bool IsReadOnly {
2260 get { return true; }
2264 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
2265 public object this [int index] {
2267 if (index < 0 || index >= Count)
2268 throw new ArgumentOutOfRangeException ("Index of out range");
2270 return owner.selection [index];
2272 set {throw new NotSupportedException ();}
2275 bool ICollection.IsSynchronized {
2276 get { return true; }
2279 object ICollection.SyncRoot {
2280 get { return this; }
2283 bool IList.IsFixedSize {
2284 get { return true; }
2287 #endregion Public Properties
2289 #region Public Methods
2290 public bool Contains (object selectedObject)
2292 return owner.selection.Contains (selectedObject);
2295 public void CopyTo (Array dest, int index)
2297 owner.selection.CopyTo (dest, index);
2300 int IList.Add (object value)
2302 throw new NotSupportedException ();
2307 throw new NotSupportedException ();
2310 void IList.Insert (int index, object value)
2312 throw new NotSupportedException ();
2315 void IList.Remove (object value)
2317 throw new NotSupportedException ();
2320 void IList.RemoveAt (int index)
2322 throw new NotSupportedException ();
2325 public int IndexOf (object item)
2327 return owner.selection.IndexOf (item);
2330 public IEnumerator GetEnumerator ()
2332 return owner.selection.GetEnumerator ();
2335 #endregion Public Methods