Mark tests as not working under TARGET_JVM
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / ListBox.cs
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:
8 //
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
11 //
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.
19 //
20 // Copyright (c) 2004-2006 Novell, Inc.
21 //
22 // Authors:
23 //      Jordi Mas i Hernandez, jordi@ximian.com
24 //      Mike Kestner  <mkestner@novell.com>
25 //
26
27 // COMPLETE
28
29 using System;
30 using System.Drawing;
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;
37
38 namespace System.Windows.Forms
39 {
40         [DefaultProperty("Items")]
41         [DefaultEvent("SelectedIndexChanged")]
42         [Designer ("System.Windows.Forms.Design.ListBoxDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
43 #if NET_2_0
44         [DefaultBindingProperty ("SelectedValue")]
45         [ClassInterface (ClassInterfaceType.AutoDispatch)]
46         [ComVisible (true)]
47 #endif
48         public class ListBox : ListControl
49         {
50                 public const int DefaultItemHeight = 13;
51                 public const int NoMatches = -1;
52                 
53                 internal enum ItemNavigation
54                 {
55                         First,
56                         Last,
57                         Next,
58                         Previous,
59                         NextPage,
60                         PreviousPage,
61                         PreviousColumn,
62                         NextColumn
63                 }
64                 
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;
95
96                 public ListBox ()
97                 {
98                         border_style = BorderStyle.Fixed3D;                     
99                         BackColor = ThemeEngine.Current.ColorWindow;
100
101                         items = CreateItemCollection ();
102                         selected_indices = new SelectedIndexCollection (this);
103                         selected_items = new SelectedObjectCollection (this);
104
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;
113
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);
122
123                         Controls.AddImplicit (vscrollbar);
124                         Controls.AddImplicit (hscrollbar);
125
126                         /* Events */
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);
135                         
136                         SetStyle (ControlStyles.UserPaint, false);
137                 }
138
139                 #region Events
140                 static object DrawItemEvent = new object ();
141                 static object MeasureItemEvent = new object ();
142                 static object SelectedIndexChangedEvent = new object ();
143
144                 [Browsable (false)]
145                 [EditorBrowsable (EditorBrowsableState.Never)]
146                 public new event EventHandler BackgroundImageChanged {
147                         add { base.BackgroundImageChanged += value; }
148                         remove { base.BackgroundImageChanged -= value; }
149                 }
150
151 #if NET_2_0
152                 [Browsable (true)]
153                 [EditorBrowsable (EditorBrowsableState.Always)]
154 #else
155                 [Browsable (false)]
156                 [EditorBrowsable (EditorBrowsableState.Advanced)]
157 #endif
158                 public new event EventHandler Click {
159                         add { base.Click += value; }
160                         remove { base.Click -= value; }
161                 }
162
163                 public event DrawItemEventHandler DrawItem {
164                         add { Events.AddHandler (DrawItemEvent, value); }
165                         remove { Events.RemoveHandler (DrawItemEvent, value); }
166                 }
167
168                 public event MeasureItemEventHandler MeasureItem {
169                         add { Events.AddHandler (MeasureItemEvent, value); }
170                         remove { Events.RemoveHandler (MeasureItemEvent, value); }
171                 }
172
173                 [Browsable (false)]
174                 [EditorBrowsable (EditorBrowsableState.Never)]
175                 public new event PaintEventHandler Paint {
176                         add { base.Paint += value; }
177                         remove { base.Paint -= value; }
178                 }
179
180                 public event EventHandler SelectedIndexChanged {
181                         add { Events.AddHandler (SelectedIndexChangedEvent, value); }
182                         remove { Events.RemoveHandler (SelectedIndexChangedEvent, value); }
183                 }
184
185                 [Browsable (false)]
186                 [EditorBrowsable (EditorBrowsableState.Advanced)]
187                 public new event EventHandler TextChanged {
188                         add { base.TextChanged += value; }
189                         remove { base.TextChanged -= value; }
190                 }
191                 #endregion // Events
192
193                 #region Public Properties
194                 public override Color BackColor {
195                         get { return base.BackColor; }
196                         set {
197                                 if (base.BackColor == value)
198                                         return;
199
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
203                 }
204
205                 [Browsable (false)]
206                 [EditorBrowsable (EditorBrowsableState.Never)]
207                 public override Image BackgroundImage {
208                         get { return base.BackgroundImage; }
209                         set { 
210                                 base.BackgroundImage = value;
211                                 base.Refresh ();
212                         }
213                 }
214
215                 [DefaultValue (BorderStyle.Fixed3D)]
216                 [DispId(-504)]
217                 public BorderStyle BorderStyle {
218                         get { return InternalBorderStyle; }
219                         set { 
220                                 InternalBorderStyle = value; 
221                                 UpdateListBoxBounds ();
222                         }
223                 }
224
225                 [DefaultValue (0)]
226                 [Localizable (true)]
227                 public int ColumnWidth {
228                         get { return column_width; }
229                         set {
230                                 if (value < 0)
231                                         throw new ArgumentException ("A value less than zero is assigned to the property.");
232
233                                 column_width = value;
234
235                                 if (value == 0)
236                                         ColumnWidthInternal = 120;
237                                 else
238                                         ColumnWidthInternal = value;
239
240                                 base.Refresh ();
241                         }
242                 }
243
244                 protected override CreateParams CreateParams {
245                         get { return base.CreateParams;}
246                 }
247
248                 protected override Size DefaultSize {
249                         get { return new Size (120, 96); }
250                 }
251
252                 [RefreshProperties(RefreshProperties.Repaint)]
253                 [DefaultValue (DrawMode.Normal)]
254                 public virtual DrawMode DrawMode {
255                         get { return draw_mode; }
256
257                         set {
258                                 if (!Enum.IsDefined (typeof (DrawMode), value))
259                                         throw new InvalidEnumArgumentException (string.Format("Enum argument value '{0}' is not valid for DrawMode", value));
260                                         
261                                 if (value == DrawMode.OwnerDrawVariable && multicolumn == true)
262                                         throw new ArgumentException ("Cannot have variable height and multicolumn");
263
264                                 if (draw_mode == value)
265                                         return;
266
267                                 draw_mode = value;
268
269                                 if (draw_mode == DrawMode.OwnerDrawVariable)
270                                         item_heights = new Hashtable ();
271                                 else
272                                         item_heights = null;
273
274                                 base.Refresh ();
275                         }
276                 }
277
278                 public override Color ForeColor {
279                         get { return base.ForeColor; }
280                         set {
281
282                                 if (base.ForeColor == value)
283                                         return;
284
285                                 base.ForeColor = value;
286                                 base.Refresh ();
287                         }
288                 }
289
290                 [DefaultValue (0)]
291                 [Localizable (true)]
292                 public int HorizontalExtent {
293                         get { return horizontal_extent; }
294                         set {
295                                 if (horizontal_extent == value)
296                                         return;
297
298                                 horizontal_extent = value;
299                                 base.Refresh ();
300                         }
301                 }
302
303                 [DefaultValue (false)]
304                 [Localizable (true)]
305                 public bool HorizontalScrollbar {
306                         get { return horizontal_scrollbar; }
307                         set {
308                                 if (horizontal_scrollbar == value)
309                                         return;
310
311                                 horizontal_scrollbar = value;
312                                 UpdateScrollBars ();
313                                 base.Refresh ();
314                         }
315                 }
316
317                 [DefaultValue (true)]
318                 [Localizable (true)]
319                 [RefreshProperties(RefreshProperties.Repaint)]
320                 public bool IntegralHeight {
321                         get { return integral_height; }
322                         set {
323                                 if (integral_height == value)
324                                         return;
325
326                                 integral_height = value;
327                                 UpdateListBoxBounds ();
328                         }
329                 }
330
331                 [DefaultValue (13)]
332                 [Localizable (true)]
333                 [RefreshProperties(RefreshProperties.Repaint)]
334                 public virtual int ItemHeight {
335                         get {
336                                 if (item_height == -1) {
337                                         SizeF sz = DeviceContext.MeasureString ("The quick brown Fox", Font);
338                                         item_height = (int) sz.Height;
339                                 }
340                                 return item_height;
341                         }
342                         set {
343                                 if (value > 255)
344                                         throw new ArgumentOutOfRangeException ("The ItemHeight property was set beyond 255 pixels");
345
346                                 explicit_item_height = true;
347                                 if (item_height == value)
348                                         return;
349
350                                 item_height = value;
351                                 if (IntegralHeight)
352                                         UpdateListBoxBounds ();
353                                 LayoutListBox ();
354                         }
355                 }
356
357                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
358                 [Localizable (true)]
359                 [Editor ("System.Windows.Forms.Design.ListControlStringCollectionEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
360 #if NET_2_0
361                 [MergableProperty (false)]
362 #endif
363                 public ObjectCollection Items {
364                         get { return items; }
365                 }
366
367                 [DefaultValue (false)]
368                 public bool MultiColumn {
369                         get { return multicolumn; }
370                         set {
371                                 if (multicolumn == value)
372                                         return;
373
374                                 if (value == true && DrawMode == DrawMode.OwnerDrawVariable)
375                                         throw new ArgumentException ("A multicolumn ListBox cannot have a variable-sized height.");
376                                         
377                                 multicolumn = value;
378                                 LayoutListBox ();
379                         }
380                 }
381
382                 [Browsable (false)]
383                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
384                 [EditorBrowsable (EditorBrowsableState.Advanced)]
385                 public int PreferredHeight {
386                         get {
387                                 int itemsHeight = 0;
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]];
395                                 }
396                                 
397                                 return itemsHeight;
398                         }
399                 }
400
401                 public override RightToLeft RightToLeft {
402                         get { return base.RightToLeft; }
403                         set {
404                                 base.RightToLeft = value;                               
405                                 if (base.RightToLeft == RightToLeft.Yes)
406                                         StringFormat.Alignment = StringAlignment.Far;                           
407                                 else
408                                         StringFormat.Alignment = StringAlignment.Near;                          
409                                 base.Refresh ();
410                         }
411                 }
412
413                 // Only affects the Vertical ScrollBar
414                 [DefaultValue (false)]
415                 [Localizable (true)]
416                 public bool ScrollAlwaysVisible {
417                         get { return scroll_always_visible; }
418                         set {
419                                 if (scroll_always_visible == value)
420                                         return;
421
422                                 scroll_always_visible = value;
423                                 UpdateScrollBars ();
424                         }
425                 }
426
427                 [Bindable(true)]
428                 [Browsable (false)]
429                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
430                 public override int SelectedIndex {
431                         get { return selected_index;}
432                         set {
433                                 if (value < -1 || value >= Items.Count)
434                                         throw new ArgumentOutOfRangeException ("Index of out range");
435
436                                 if (SelectionMode == SelectionMode.None)
437                                         throw new ArgumentException ("cannot call this method if SelectionMode is SelectionMode.None");
438
439                                 if (selected_index == value)
440                                         return;
441
442                                 if (value == -1)
443                                         ClearSelected ();
444                                 else if (SelectionMode == SelectionMode.One)
445                                         UnSelectItem (selected_index, true);
446
447                                 if (value < top_index)
448                                 {
449                                         top_index = value;
450                                         UpdateTopItem ();
451                                 } else {
452                                         int rows = items_area.Height / ItemHeight;
453                                         if (value >= (top_index + rows))
454                                         {
455                                                 top_index = value - rows + 1;
456                                                 UpdateTopItem ();
457                                         }
458                                 }
459                                 SelectItem (value);
460                                 selected_index = value;
461                                 FocusedItem = value;
462                                 OnSelectedIndexChanged  (new EventArgs ());
463                                 OnSelectedValueChanged (new EventArgs ());
464                         }
465                 }
466
467                 [Browsable (false)]
468                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
469                 public SelectedIndexCollection SelectedIndices {
470                         get { return selected_indices; }
471                 }
472
473                 [Bindable(true)]
474                 [Browsable (false)]
475                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
476                 public object SelectedItem {
477                         get {
478                                 if (SelectedItems.Count > 0)
479                                         return SelectedItems[0];
480                                 else
481                                         return null;
482                         }
483                         set {
484                                 if (value != null && !Items.Contains (value))
485                                         return; // FIXME: this is probably an exception
486                                         
487                                 SelectedIndex = value == null ? - 1 : Items.IndexOf (value);
488                         }
489                 }
490
491                 [Browsable (false)]
492                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
493                 public SelectedObjectCollection SelectedItems {
494                         get {return selected_items;}
495                 }
496
497                 [DefaultValue (SelectionMode.One)]
498                 public virtual SelectionMode SelectionMode {
499                         get { return selection_mode; }
500                         set {
501                                 if (!Enum.IsDefined (typeof (SelectionMode), value))
502                                         throw new InvalidEnumArgumentException (string.Format("Enum argument value '{0}' is not valid for SelectionMode", value));
503
504                                 if (selection_mode == value)
505                                         return;
506                                         
507                                 selection_mode = value;
508                                         
509                                 switch (selection_mode) {
510                                 case SelectionMode.None: 
511                                         ClearSelected ();
512                                         break;                                          
513
514                                 case SelectionMode.One:
515                                         while (SelectedIndices.Count > 1)
516                                                 UnSelectItem (SelectedIndices [SelectedIndices.Count - 1], true);
517                                         break;
518
519                                 default:
520                                         break;                                          
521                                 }
522                         }
523                 }
524
525                 [DefaultValue (false)]
526                 public bool Sorted {
527                         get { return sorted; }
528
529                         set {
530                                 if (sorted == value)
531                                         return;
532
533                                 sorted = value;
534                                 if (sorted)
535                                         Sort ();
536                         }
537                 }
538
539                 [Bindable (false)]
540                 [Browsable (false)]
541                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
542                 [EditorBrowsable (EditorBrowsableState.Advanced)]
543                 public override string Text {
544                         get {
545                                 if (SelectionMode != SelectionMode.None && SelectedIndex != -1)
546                                         return GetItemText (SelectedItem);
547
548                                 return base.Text;
549                         }
550                         set {
551
552                                 base.Text = value;
553
554                                 if (SelectionMode == SelectionMode.None)
555                                         return;
556
557                                 int index;
558
559                                 index = FindStringExact (value);
560
561                                 if (index == -1)
562                                         return;
563
564                                 SelectedIndex = index;
565                         }
566                 }
567
568                 [Browsable (false)]
569                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
570                 public int TopIndex {
571                         get { return top_index; }
572                         set {
573                                 if (value == top_index)
574                                         return;
575
576                                 if (value < 0 || value >= Items.Count)
577                                         return;
578
579                                 top_index = value;
580                                 UpdateTopItem ();
581                                 base.Refresh ();
582                         }
583                 }
584
585                 [DefaultValue (true)]
586                 public bool UseTabStops {
587                         get { return use_tabstops; }
588
589                         set {
590                                 if (use_tabstops == value)
591                                         return;
592
593                                 use_tabstops = value;                                   
594                                 if (use_tabstops)
595                                         StringFormat.SetTabStops (0, new float [] {(float)(Font.Height * 3.7)});
596                                 else
597                                         StringFormat.SetTabStops (0, new float [0]);
598                                 base.Refresh ();
599                         }
600                 }
601
602 #if NET_2_0
603                 protected override bool AllowSelection {
604                         get {
605                                 return SelectionMode != SelectionMode.None;
606                         }
607                 }
608 #endif
609
610                 #endregion Public Properties
611
612                 #region Private Properties
613
614                 private int ColumnWidthInternal {
615                         get { return column_width_internal; }
616                         set { column_width_internal = value; }
617                 }
618
619                 private int row_count = 1;
620                 private int RowCount {
621                         get {
622                                 return MultiColumn ? row_count : Items.Count;
623                         }
624                 }
625
626                 #endregion Private Properties
627
628                 #region Public Methods
629 #if NET_2_0
630                 [Obsolete ("this method has been deprecated")]
631 #endif
632                 protected virtual void AddItemsCore (object[] value)
633                 {
634                         Items.AddRange (value);
635                 }
636
637                 public void BeginUpdate ()
638                 {
639                         suspend_layout = true;
640                 }
641
642                 public void ClearSelected ()
643                 {
644                         foreach (int i in selected_indices) {
645                                 UnSelectItem (i, false);
646                         }
647
648                         selection.Clear ();
649                 }
650
651                 protected virtual ObjectCollection CreateItemCollection ()
652                 {
653                         return new ObjectCollection (this);
654                 }
655
656                 public void EndUpdate ()
657                 {
658                         suspend_layout = false;
659                         LayoutListBox ();
660                         base.Refresh ();
661                 }
662
663                 public int FindString (String s)
664                 {
665                         return FindString (s, -1);
666                 }
667
668                 public int FindString (string s,  int startIndex)
669                 {
670                         if (Items.Count == 0)
671                                 return -1; // No exception throwing if empty
672
673                         if (startIndex < -1 || startIndex >= Items.Count - 1)
674                                 throw new ArgumentOutOfRangeException ("Index of out range");
675
676                         startIndex++;
677                         for (int i = startIndex; i < Items.Count; i++) {
678                                 if ((GetItemText (Items[i])).StartsWith (s))
679                                         return i;
680                         }
681
682                         return NoMatches;
683                 }
684
685                 public int FindStringExact (string s)
686                 {
687                         return FindStringExact (s, -1);
688                 }
689
690                 public int FindStringExact (string s,  int startIndex)
691                 {
692                         if (Items.Count == 0)
693                                 return -1; // No exception throwing if empty
694
695                         if (startIndex < -1 || startIndex >= Items.Count - 1)
696                                 throw new ArgumentOutOfRangeException ("Index of out range");
697
698                         startIndex++;
699                         for (int i = startIndex; i < Items.Count; i++) {
700                                 if ((GetItemText (Items[i])).Equals (s))
701                                         return i;
702                         }
703
704                         return NoMatches;
705                 }
706
707                 public int GetItemHeight (int index)
708                 {
709                         if (index < 0 || index >= Items.Count)
710                                 throw new ArgumentOutOfRangeException ("Index of out range");
711                                 
712                         if (DrawMode == DrawMode.OwnerDrawVariable && IsHandleCreated == true) {
713                                 
714                                 object o = Items [index];
715                                 if (item_heights.Contains (o))
716                                         return (int) item_heights [o];
717                                 
718                                 MeasureItemEventArgs args = new MeasureItemEventArgs (DeviceContext, index, ItemHeight);
719                                 OnMeasureItem (args);
720                                 item_heights [o] = args.ItemHeight;
721                                 return args.ItemHeight;
722                         }
723
724                         return ItemHeight;
725                 }
726
727                 public Rectangle GetItemRectangle (int index)
728                 {
729                         if (index < 0 || index >= Items.Count)
730                                 throw new  ArgumentOutOfRangeException ("GetItemRectangle index out of range.");
731
732                         Rectangle rect = new Rectangle ();
733
734                         if (MultiColumn) {
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;
740                         } else {
741                                 rect.X = 0;                             
742                                 rect.Height = GetItemHeight (index);
743                                 rect.Width = items_area.Width;
744                                 
745                                 if (DrawMode == DrawMode.OwnerDrawVariable) {
746                                         rect.Y = 0;
747                                         if (index >= top_index) {
748                                                 for (int i = top_index; i < index; i++) {
749                                                         rect.Y += GetItemHeight (i);
750                                                 }
751                                         } else {
752                                                 for (int i = index; i < top_index; i++) {
753                                                         rect.Y -= GetItemHeight (i);
754                                                 }
755                                         }
756                                 } else {
757                                         rect.Y = ItemHeight * (index - top_index);      
758                                 }                               
759                         }
760
761                         return rect;
762                 }
763
764                 public bool GetSelected (int index)
765                 {
766                         if (index < 0 || index >= Items.Count)
767                                 throw new ArgumentOutOfRangeException ("Index of out range");
768
769                         return SelectedIndices.Contains (index);
770                 }
771
772                 public int IndexFromPoint (Point p)
773                 {
774                         return IndexFromPoint (p.X, p.Y);
775                 }
776
777                 // Only returns visible points
778                 public int IndexFromPoint (int x, int y)
779                 {
780
781                         if (Items.Count == 0) {
782                                 return -1;
783                         }
784
785                         for (int i = top_index; i <= last_visible_index; i++) {
786                                 if (GetItemRectangle (i).Contains (x,y) == true)
787                                         return i;
788                         }
789
790                         return -1;
791                 }
792
793                 protected override void OnChangeUICues (UICuesEventArgs e)
794                 {
795                         base.OnChangeUICues (e);
796                 }
797
798                 protected override void OnDataSourceChanged (EventArgs e)
799                 {
800                         base.OnDataSourceChanged (e);
801                         BindDataItems ();
802                         
803                         if (DataSource == null || DataManager == null) {
804                                 SelectedIndex = -1;
805                         } 
806                         else {
807                                 SelectedIndex = DataManager.Position;
808                         }
809                 }
810
811                 protected override void OnDisplayMemberChanged (EventArgs e)
812                 {
813                         base.OnDisplayMemberChanged (e);
814
815                         if (DataManager == null || !IsHandleCreated)
816                                 return;
817
818                         BindDataItems ();
819                         base.Refresh ();
820                 }
821
822                 protected virtual void OnDrawItem (DrawItemEventArgs e)
823                 {                       
824                         switch (DrawMode) {
825                         case DrawMode.OwnerDrawFixed:
826                         case DrawMode.OwnerDrawVariable:
827                                 DrawItemEventHandler eh = (DrawItemEventHandler)(Events [DrawItemEvent]);
828                                 if (eh != null)
829                                         eh (this, e);
830
831                                 break;
832
833                         default:
834                                 ThemeEngine.Current.DrawListBoxItem (this, e);
835                                 break;
836                         }
837                 }
838
839                 protected override void OnFontChanged (EventArgs e)
840                 {
841                         base.OnFontChanged (e);
842
843                         if (use_tabstops)
844                                 StringFormat.SetTabStops (0, new float [] {(float)(Font.Height * 3.7)});
845
846                         if (explicit_item_height) {
847                                 base.Refresh ();
848                         } else {
849                                 SizeF sz = DeviceContext.MeasureString ("The quick brown Fox", Font);
850                                 item_height = (int) sz.Height;
851                                 if (IntegralHeight)
852                                         UpdateListBoxBounds ();
853                                 LayoutListBox ();
854                         }
855                 }
856
857                 protected override void OnHandleCreated (EventArgs e)
858                 {
859                         base.OnHandleCreated (e);
860                         LayoutListBox ();
861                 }
862
863                 protected override void OnHandleDestroyed (EventArgs e)
864                 {
865                         base.OnHandleDestroyed (e);
866                 }
867
868                 protected virtual void OnMeasureItem (MeasureItemEventArgs e)
869                 {
870                         if (draw_mode != DrawMode.OwnerDrawVariable)
871                                 return;
872
873                         MeasureItemEventHandler eh = (MeasureItemEventHandler)(Events [MeasureItemEvent]);
874                         if (eh != null)
875                                 eh (this, e);
876                 }
877
878                 protected override void OnParentChanged (EventArgs e)
879                 {
880                         base.OnParentChanged (e);
881                 }
882
883                 protected override void OnResize (EventArgs e)
884                 {
885                         base.OnResize (e);
886                         if (canvas_size.IsEmpty || MultiColumn)
887                                 LayoutListBox ();
888                 }
889
890                 protected override void OnSelectedIndexChanged (EventArgs e)
891                 {
892                         base.OnSelectedIndexChanged (e);
893
894                         EventHandler eh = (EventHandler)(Events [SelectedIndexChangedEvent]);
895                         if (eh != null)
896                                 eh (this, e);
897                 }
898
899                 protected override void OnSelectedValueChanged (EventArgs e)
900                 {
901                         base.OnSelectedValueChanged (e);
902                 }
903
904                 public override void Refresh ()
905                 {
906                         if (draw_mode == DrawMode.OwnerDrawVariable)
907                                 item_heights.Clear ();
908                         
909                         base.Refresh ();
910                 }
911
912                 protected override void RefreshItem (int index)
913                 {
914                         if (index < 0 || index >= Items.Count)
915                                 throw new ArgumentOutOfRangeException ("Index of out range");
916                                 
917                         if (draw_mode == DrawMode.OwnerDrawVariable)
918                                 item_heights.Remove (Items [index]);
919                 }
920
921                 protected override void SetBoundsCore (int x,  int y, int width, int height, BoundsSpecified specified)
922                 {
923                         if ((specified & BoundsSpecified.Height) == BoundsSpecified.Height)
924                                 requested_height = height;
925
926                         if (IntegralHeight) {
927                                 int border;
928                                 switch (border_style) {
929                                 case BorderStyle.Fixed3D:
930                                         border = ThemeEngine.Current.Border3DSize.Height;
931                                         break;
932                                 case BorderStyle.FixedSingle:
933                                         border = ThemeEngine.Current.BorderSize.Height;
934                                         break;
935                                 case BorderStyle.None:
936                                 default:
937                                         border = 0;
938                                         break;
939                                 }
940                                 height -= (2 * border);
941                                 height -= height % ItemHeight;
942                                 height += (2 * border);
943                         }
944
945                         base.SetBoundsCore (x, y, width, height, specified);
946                         UpdateScrollBars ();
947                 }
948
949                 protected override void SetItemCore (int index,  object value)
950                 {
951                         if (index < 0 || index >= Items.Count)
952                                 return;
953
954                         Items[index] = value;
955                 }
956
957                 protected override void SetItemsCore (IList value)
958                 {
959                         BeginUpdate ();
960                         try {
961                                 Items.Clear ();
962                                 Items.AddRange (value);
963                         } finally {
964                                 EndUpdate ();
965                         }
966                 }
967
968                 public void SetSelected (int index, bool value)
969                 {
970                         if (index < 0 || index >= Items.Count)
971                                 throw new ArgumentOutOfRangeException ("Index of out range");
972
973                         if (SelectionMode == SelectionMode.None)
974                                 throw new InvalidOperationException ();
975
976                         if (value)
977                                 SelectItem (index);
978                         else
979                                 UnSelectItem (index, true);
980                 }
981
982                 protected virtual void Sort ()
983                 {
984                         if (Items.Count == 0)
985                                 return;
986
987                         Items.Sort ();
988                         base.Refresh ();
989                 }
990
991                 public override string ToString ()
992                 {
993                         return base.ToString ();
994                 }
995
996                 protected virtual void WmReflectCommand (ref Message m)
997                 {
998                 }
999
1000                 protected override void WndProc (ref Message m)
1001                 {
1002                         base.WndProc (ref m);
1003                 }
1004
1005                 #endregion Public Methods
1006
1007                 #region Private Methods
1008
1009                 private Size canvas_size;
1010
1011                 private void LayoutListBox ()
1012                 {
1013                         if (!IsHandleCreated || suspend_layout)
1014                                 return;
1015
1016                         if (MultiColumn)
1017                                 LayoutMultiColumn ();
1018                         else
1019                                 LayoutSingleColumn ();
1020
1021                         UpdateScrollBars ();
1022                         last_visible_index = LastVisibleItem ();
1023                 }
1024
1025                 private void LayoutSingleColumn ()
1026                 {
1027                         int height, width;
1028
1029                         switch (DrawMode) {
1030                         case DrawMode.OwnerDrawVariable:
1031                                 height = 0;
1032                                 width = HorizontalExtent;
1033                                 for (int i = 0; i < Items.Count; i++) {
1034                                         height += GetItemHeight (i);
1035                                 }
1036                                 break;
1037
1038                         case DrawMode.OwnerDrawFixed:
1039                                 height = Items.Count * ItemHeight;
1040                                 width = HorizontalExtent;
1041                                 break;
1042
1043                         case DrawMode.Normal:
1044                         default:
1045                                 height = Items.Count * ItemHeight;
1046                                 width = 0;
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;
1051                                 }
1052                                 break;
1053                         }
1054
1055                         canvas_size = new Size (width, height);
1056                 }
1057
1058                 private void LayoutMultiColumn ()
1059                 {
1060                         int usable_height = ClientRectangle.Height - (ScrollAlwaysVisible ? hscrollbar.Height : 0);
1061                         row_count = usable_height / ItemHeight;
1062                         if (row_count == 0)
1063                                 row_count = 1;
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);
1071                         }
1072                         canvas_size = sz;
1073                 }
1074
1075                 internal void Draw (Rectangle clip, Graphics dc)
1076                 {                               
1077                         Theme theme = ThemeEngine.Current;
1078
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);
1084                         }
1085
1086                         dc.FillRectangle (theme.ResPool.GetSolidBrush (BackColor), items_area);
1087
1088                         if (Items.Count == 0)
1089                                 return;
1090
1091                         for (int i = top_index; i <= last_visible_index; i++) {
1092                                 Rectangle rect = GetItemDisplayRectangle (i, top_index);
1093
1094                                 if (!clip.IntersectsWith (rect))
1095                                         continue;
1096
1097                                 DrawItemState state = DrawItemState.None;
1098
1099                                 if (SelectedIndices.Contains (i))
1100                                         state |= DrawItemState.Selected;
1101                                         
1102                                 if (has_focus && FocusedItem == i)
1103                                         state |= DrawItemState.Focus;
1104                                         
1105                                 if (MultiColumn == false && hscrollbar != null && hscrollbar.Visible) {
1106                                         rect.X -= hscrollbar.Value;
1107                                         rect.Width += hscrollbar.Value;
1108                                 }
1109
1110                                 OnDrawItem (new DrawItemEventArgs (dc, Font, rect, i, state, ForeColor, BackColor));
1111                         }
1112                 }
1113
1114                 // Converts a GetItemRectangle to a one that we can display
1115                 internal Rectangle GetItemDisplayRectangle (int index, int first_displayble)
1116                 {
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;
1122                         
1123                         return item_rect;
1124                 }
1125
1126                 // Value Changed
1127                 private void HorizontalScrollEvent (object sender, EventArgs e)
1128                 {
1129                         if (multicolumn) {
1130                                 int top_item = top_index;
1131                                 int last_item = last_visible_index;
1132
1133                                 top_index = RowCount * hscrollbar.Value;
1134                                 last_visible_index = LastVisibleItem ();
1135
1136                                 if (top_item != top_index || last_item != last_visible_index)
1137                                         Invalidate (items_area);
1138                         }
1139                         else {
1140                                 int old_offset = hbar_offset;
1141                                 hbar_offset = hscrollbar.Value;
1142
1143                                 if (hbar_offset < 0)
1144                                         hbar_offset = 0;
1145
1146                                 if (IsHandleCreated)
1147                                         XplatUI.ScrollWindow (Handle, items_area, old_offset - hbar_offset, 0, false);
1148                         }
1149                 }
1150
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)
1154                 {       
1155                         if (Items.Count == 0)
1156                                 return -1;
1157                         
1158                         if (x < 0)
1159                                 x = 0;
1160                         else if (x > ClientRectangle.Right)
1161                                 x = ClientRectangle.Right;
1162
1163                         if (y < 0)
1164                                 y = 0;
1165                         else if (y > ClientRectangle.Bottom)
1166                                 y = ClientRectangle.Bottom;
1167
1168                         for (int i = top_index; i <= last_visible_index; i++)
1169                                 if (GetItemDisplayRectangle (i, top_index).Contains (x, y))
1170                                         return i;
1171
1172                         return -1;
1173                 }
1174
1175                 private int LastVisibleItem ()
1176                 {
1177                         Rectangle item_rect;
1178                         int top_y = items_area.Y + items_area.Height;
1179                         int i = 0;
1180
1181                         if (top_index >= Items.Count)
1182                                 return top_index;
1183
1184                         for (i = top_index; i < Items.Count; i++) {
1185
1186                                 item_rect = GetItemDisplayRectangle (i, top_index);
1187                                 if (MultiColumn) {
1188
1189                                         if (item_rect.X > items_area.Width)
1190                                                 return i - 1;
1191                                 }
1192                                 else {                                  
1193                                         if (item_rect.Y + item_rect.Height > top_y) {
1194                                                 return i;
1195                                         }
1196                                 }
1197                         }
1198                         return i - 1;
1199                 }
1200
1201                 private void UpdateTopItem ()
1202                 {
1203                         if (MultiColumn) {                              
1204                                 int col = top_index / RowCount;
1205                                 
1206                                 if (col > hscrollbar.Maximum)
1207                                         hscrollbar.Value = hscrollbar.Maximum;
1208                                 else
1209                                         hscrollbar.Value = col;
1210                         } else {
1211                                 int val = vscrollbar.Value;
1212                                 if (top_index > vscrollbar.Maximum)
1213                                         vscrollbar.Value = vscrollbar.Maximum;
1214                                 else
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);
1219                         }
1220                 }
1221                 
1222                 // Navigates to the indicated item and returns the new item
1223                 private int NavigateItemVisually (ItemNavigation navigation)
1224                 {                       
1225                         int page_size, columns, selected_index = -1;
1226
1227                         if (multicolumn) {
1228                                 columns = items_area.Width / ColumnWidthInternal; 
1229                                 page_size = columns * RowCount;
1230                                 if (page_size == 0) {
1231                                         page_size = RowCount;
1232                                 }
1233                         } else {
1234                                 page_size = items_area.Height / ItemHeight;     
1235                         }
1236
1237                         switch (navigation) {
1238
1239                         case ItemNavigation.PreviousColumn: {
1240                                 if (FocusedItem - RowCount < 0) {
1241                                         return -1;
1242                                 }
1243
1244                                 if (FocusedItem - RowCount < top_index) {
1245                                         top_index = FocusedItem - RowCount;
1246                                         UpdateTopItem ();
1247                                 }
1248                                         
1249                                 selected_index = FocusedItem - RowCount;
1250                                 break;
1251                         }
1252                         
1253                         case ItemNavigation.NextColumn: {
1254                                 if (FocusedItem + RowCount >= Items.Count) {
1255                                         break;
1256                                 }
1257
1258                                 if (FocusedItem + RowCount > last_visible_index) {
1259                                         top_index = FocusedItem;
1260                                         UpdateTopItem ();
1261                                 }
1262                                         
1263                                 selected_index = FocusedItem + RowCount;                                        
1264                                 break;
1265                         }
1266
1267                         case ItemNavigation.First: {
1268                                 top_index = 0;
1269                                 selected_index  = 0;
1270                                 UpdateTopItem ();
1271                                 break;
1272                         }
1273
1274                         case ItemNavigation.Last: {
1275
1276                                 int rows = items_area.Height / ItemHeight;
1277                                 if (Items.Count < rows) {
1278                                         top_index = 0;
1279                                         selected_index  = Items.Count - 1;
1280                                         UpdateTopItem ();
1281                                 } else {
1282                                         top_index = Items.Count - rows;
1283                                         selected_index  = Items.Count - 1;
1284                                         UpdateTopItem ();
1285                                 }
1286                                 break;
1287                         }
1288
1289                         case ItemNavigation.Next: {
1290                                 if (FocusedItem == Items.Count - 1)
1291                                         return -1;
1292
1293                                 int bottom = 0;
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);
1298                                                 bottom += h;
1299                                                 heights.Add (h);
1300                                         }
1301                                 } else {
1302                                         bottom = ((FocusedItem + 1) - top_index + 1) * ItemHeight;
1303                                 }
1304
1305                                 if (bottom >= items_area.Height) {
1306                                         int overhang = bottom - items_area.Height;
1307
1308                                         int offset = 0;
1309                                         if (draw_mode == DrawMode.OwnerDrawVariable)
1310                                                 while (overhang > 0)
1311                                                         overhang -= (int) heights [offset];
1312                                         else
1313                                                 offset = (int) Math.Ceiling ((float)overhang / (float) ItemHeight);
1314                                         top_index += offset;
1315                                         UpdateTopItem ();                                               
1316                                 }
1317                                 selected_index = FocusedItem + 1;
1318                                 break;
1319                         }
1320
1321                         case ItemNavigation.Previous: {
1322                                 if (FocusedItem > 0) {
1323                                         if (FocusedItem - 1 < top_index) {
1324                                                 top_index--;
1325                                                 UpdateTopItem ();
1326                                         }
1327                                         selected_index = FocusedItem - 1;
1328                                 }                                       
1329                                 break;
1330                         }
1331
1332                         case ItemNavigation.NextPage: {
1333                                 if (Items.Count < page_size) {
1334                                         NavigateItemVisually (ItemNavigation.Last);
1335                                         break;
1336                                 }
1337
1338                                 if (FocusedItem + page_size - 1 >= Items.Count) {
1339                                         top_index = Items.Count - page_size;
1340                                         UpdateTopItem ();
1341                                         selected_index = Items.Count - 1;                                               
1342                                 }
1343                                 else {
1344                                         if (FocusedItem + page_size - 1  > last_visible_index) {
1345                                                 top_index = FocusedItem;
1346                                                 UpdateTopItem ();
1347                                         }
1348                                         
1349                                         selected_index = FocusedItem + page_size - 1;                                           
1350                                 }
1351                                         
1352                                 break;
1353                         }                       
1354
1355                         case ItemNavigation.PreviousPage: {
1356                                         
1357                                 int rows = items_area.Height / ItemHeight;
1358                                 if (FocusedItem - (rows - 1) <= 0) {
1359                                                                                                                                                 
1360                                         top_index = 0;                                  
1361                                         UpdateTopItem ();                                       
1362                                         SelectedIndex = 0;                                      
1363                                 }
1364                                 else { 
1365                                         if (FocusedItem - (rows - 1)  < top_index) {
1366                                                 top_index = FocusedItem - (rows - 1);
1367                                                 UpdateTopItem ();                                               
1368                                         }
1369                                         
1370                                         selected_index = FocusedItem - (rows - 1);
1371                                 }
1372                                         
1373                                 break;
1374                         }               
1375                         default:
1376                                 break;                          
1377                         }
1378                         
1379                         return selected_index;
1380                 }
1381                 
1382                 
1383                 private void OnGotFocus (object sender, EventArgs e)                    
1384                 {                       
1385                         if (FocusedItem != -1)
1386                                 InvalidateItem (FocusedItem);
1387                 }               
1388                 
1389                 private void OnLostFocus (object sender, EventArgs e)                   
1390                 {                       
1391                         if (FocusedItem != -1)
1392                                 InvalidateItem (FocusedItem);
1393                 }               
1394
1395                 private void OnKeyDownLB (object sender, KeyEventArgs e)
1396                 {                                       
1397                         int new_item = -1;
1398                         
1399                         if (Items.Count == 0)
1400                                 return;
1401
1402                         switch (e.KeyCode) {
1403                                 
1404                                 case Keys.ControlKey:
1405                                         ctrl_pressed = true;
1406                                         break;
1407                                         
1408                                 case Keys.ShiftKey:
1409                                         shift_pressed = true;
1410                                         break;
1411                                         
1412                                 case Keys.Home:
1413                                         new_item = NavigateItemVisually (ItemNavigation.First);
1414                                         break;  
1415
1416                                 case Keys.End:
1417                                         new_item = NavigateItemVisually (ItemNavigation.Last);
1418                                         break;  
1419
1420                                 case Keys.Up:
1421                                         new_item = NavigateItemVisually (ItemNavigation.Previous);
1422                                         break;                          
1423         
1424                                 case Keys.Down:                         
1425                                         new_item = NavigateItemVisually (ItemNavigation.Next);
1426                                         break;
1427                                 
1428                                 case Keys.PageUp:
1429                                         new_item = NavigateItemVisually (ItemNavigation.PreviousPage);
1430                                         break;                          
1431         
1432                                 case Keys.PageDown:                             
1433                                         new_item = NavigateItemVisually (ItemNavigation.NextPage);
1434                                         break;
1435
1436                                 case Keys.Right:
1437                                         if (multicolumn == true) {
1438                                                 new_item = NavigateItemVisually (ItemNavigation.NextColumn);
1439                                         }
1440                                         break;                          
1441         
1442                                 case Keys.Left:                 
1443                                         if (multicolumn == true) {      
1444                                                 new_item = NavigateItemVisually (ItemNavigation.PreviousColumn);
1445                                         }
1446                                         break;
1447                                         
1448                                 case Keys.Space:
1449                                         if (selection_mode == SelectionMode.MultiSimple) {
1450                                                 SelectedItemFromNavigation (FocusedItem);
1451                                         }
1452                                         break;
1453                                 
1454
1455                                 default:
1456                                         break;
1457                                 }
1458                                 
1459                                 if (new_item != -1) {
1460                                         FocusedItem = new_item;
1461                                         if (selection_mode != SelectionMode.MultiSimple && selection_mode != SelectionMode.None) {
1462                                                 SelectedItemFromNavigation (new_item);
1463                                         }
1464                                 }
1465                 }
1466                 
1467                 private void OnKeyUpLB (object sender, KeyEventArgs e)                  
1468                 {
1469                         switch (e.KeyCode) {
1470                                 case Keys.ControlKey:
1471                                         ctrl_pressed = false;
1472                                         break;
1473                                 case Keys.ShiftKey:
1474                                         shift_pressed = false;
1475                                         break;
1476                                 default: 
1477                                         break;
1478                         }
1479                 }               
1480
1481                 internal void InvalidateItem (int index)
1482                 {
1483                         Rectangle bounds = GetItemDisplayRectangle (index, top_index);
1484                         if (ClientRectangle.IntersectsWith (bounds))
1485                                 Invalidate (bounds);
1486                 }
1487
1488                 internal virtual void OnItemClick (int index)
1489                 {
1490                         OnSelectedIndexChanged  (EventArgs.Empty);
1491                         OnSelectedValueChanged (EventArgs.Empty);
1492                 }
1493
1494                 int anchor = -1;
1495                 int[] prev_selection;
1496                 bool button_pressed = false;
1497
1498                 private void SelectExtended (int index)
1499                 {
1500                         SuspendLayout ();
1501
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);
1507
1508                         if (ctrl_pressed)
1509                                 foreach (int i in prev_selection)
1510                                         if (!selection.Contains (i))
1511                                                 new_selection.Add (i);
1512
1513                         foreach (int i in SelectedIndices)
1514                                 if (!new_selection.Contains (i))
1515                                         UnSelectItem (i, true);
1516
1517                         foreach (int i in new_selection)
1518                                 if (!SelectedIndices.Contains (i))
1519                                         SelectItem (i);
1520                         ResumeLayout ();
1521                 }
1522
1523                 private void OnMouseDownLB (object sender, MouseEventArgs e)
1524                 {
1525                         int index = IndexAtClientPoint (e.X, e.Y);
1526                                                         
1527                         if (index == -1)
1528                                 return;                 
1529
1530                         switch (SelectionMode) {
1531                         case SelectionMode.One:
1532                                 if (SelectedIndex != index) {
1533                                         UnSelectItem (SelectedIndex, true);
1534                                         SelectItem (index);
1535                                 }
1536                                 selected_index = index;
1537                                 break;
1538
1539                         case SelectionMode.MultiSimple:
1540                                 if (SelectedIndices.Contains (index))
1541                                         UnSelectItem (index, true);
1542                                 else
1543                                         SelectItem (index);
1544                                 break;
1545
1546                         case SelectionMode.MultiExtended:
1547                                 shift_pressed = (XplatUI.State.ModifierKeys & Keys.Shift) != 0;
1548                                 ctrl_pressed = (XplatUI.State.ModifierKeys & Keys.Control) != 0;
1549
1550                                 if (ctrl_pressed) {
1551                                         prev_selection = new int [selection.Count];
1552                                         SelectedIndices.CopyTo (prev_selection, 0);
1553                                 } else
1554                                         ClearSelected ();
1555
1556                                 if (!shift_pressed)
1557                                         anchor = index;
1558
1559                                 SelectExtended (index);
1560                                 break;
1561
1562                         case SelectionMode.None:
1563                         default:
1564                                 return;
1565                         }
1566                                 
1567                         button_pressed = true;
1568                         FocusedItem = index;
1569                 }
1570
1571                 private void OnMouseMoveLB (object sender, MouseEventArgs e)
1572                 {
1573                         if (!button_pressed)
1574                                 return;
1575
1576                         int index = IndexAtClientPoint (e.X, e.Y);
1577
1578                         switch (SelectionMode) {
1579                         case SelectionMode.One:
1580                                 if (index == selected_index)
1581                                         return;
1582
1583                                 UnSelectItem (SelectedIndex, true);
1584                                 SelectItem (index);
1585                                 selected_index = index;
1586                                 break;
1587
1588                         case SelectionMode.MultiSimple:
1589                                 break;
1590
1591                         case SelectionMode.MultiExtended:
1592                                 SelectExtended (index);
1593                                 break;
1594
1595                         case SelectionMode.None:
1596                         default:
1597                                 return;
1598                         }
1599
1600                         FocusedItem = index;
1601                 }
1602
1603                 private void OnMouseUpLB (object sender, MouseEventArgs e)
1604                 {
1605                         if (e.Clicks > 1)
1606                                 OnDoubleClick (EventArgs.Empty);
1607                         else if (e.Clicks == 1)
1608                                 OnClick (EventArgs.Empty);
1609                         
1610                         if (!button_pressed)
1611                                 return;
1612
1613                         int index = IndexAtClientPoint (e.X, e.Y);
1614                         OnItemClick (index);
1615                         button_pressed = ctrl_pressed = shift_pressed = false;
1616                 }
1617
1618                 private void Scroll (ScrollBar scrollbar, int delta)
1619                 {
1620                         if (delta == 0 || !scrollbar.Visible || !scrollbar.Enabled)
1621                                 return;
1622
1623                         int max;
1624                         if (scrollbar == hscrollbar)
1625                                 max = hscrollbar.Maximum - (items_area.Width / ColumnWidthInternal) + 1;
1626                         else
1627                                 max = vscrollbar.Maximum - (items_area.Height / ItemHeight) + 1;
1628
1629                         int val = scrollbar.Value + delta;
1630                         if (val > max)
1631                                 val = max;
1632                         else if (val < scrollbar.Minimum)
1633                                 val = scrollbar.Minimum;
1634                         scrollbar.Value = val;
1635                 }
1636
1637                 private void OnMouseWheelLB (object sender, MouseEventArgs me)
1638                 {
1639                         if (Items.Count == 0)
1640                                 return;
1641
1642                         int lines = me.Delta / 120;
1643
1644                         if (MultiColumn)
1645                                 Scroll (hscrollbar, -SystemInformation.MouseWheelScrollLines * lines);
1646                         else
1647                                 Scroll (vscrollbar, -lines);
1648                 }
1649
1650                 internal override void OnPaintInternal (PaintEventArgs pevent)
1651                 {
1652                         if (suspend_layout)
1653                                 return;
1654
1655                         Draw (pevent.ClipRectangle, pevent.Graphics);
1656                 }
1657
1658                 internal void RepositionScrollBars ()
1659                 {
1660                         if (vscrollbar.is_visible) {
1661                                 vscrollbar.Size = new Size (vscrollbar.Width, items_area.Height);
1662                                 vscrollbar.Location = new Point (items_area.Width, 0);
1663                         }
1664
1665                         if (hscrollbar.is_visible) {
1666                                 hscrollbar.Size = new Size (items_area.Width, hscrollbar.Height);
1667                                 hscrollbar.Location = new Point (0, items_area.Height);
1668                         }
1669                 }
1670
1671                 // Add an item in the Selection array and marks it visually as selected
1672                 private void SelectItem (int index)
1673                 {
1674                         if (index == -1 || SelectedIndices.Contains (index))
1675                                 return;
1676
1677                         selection.Add (Items[index]);
1678                         InvalidateItem (index);
1679                 }               
1680                 
1681                 // An item navigation operation (mouse or keyboard) has caused to select a new item
1682                 internal void SelectedItemFromNavigation (int index)
1683                 {
1684                         switch (SelectionMode) {
1685                                 case SelectionMode.None: // Do nothing
1686                                         break;
1687                                 case SelectionMode.One: {
1688                                         SelectedIndex = index;
1689                                         break;
1690                                 }
1691                                 case SelectionMode.MultiSimple: {
1692                                         if (SelectedIndex == -1) {
1693                                                 SelectedIndex = index;
1694                                         } else {
1695
1696                                                 if (SelectedIndices.Contains (index))
1697                                                         UnSelectItem (index, true);
1698                                                 else {
1699                                                         SelectItem (index);
1700                                                         OnSelectedIndexChanged  (new EventArgs ());
1701                                                         OnSelectedValueChanged (new EventArgs ());
1702                                                 }
1703                                         }
1704                                         break;
1705                                 }
1706                                 
1707                                 case SelectionMode.MultiExtended: {
1708                                         if (SelectedIndex == -1) {
1709                                                 SelectedIndex = index;
1710                                         } else {
1711
1712                                                 if (ctrl_pressed == false && shift_pressed == false) {
1713                                                         ClearSelected ();
1714                                                 }
1715                                                 
1716                                                 if (shift_pressed == true) {
1717                                                         ShiftSelection (index);
1718                                                 } else { // ctrl_pressed or single item
1719                                                         SelectItem (index);
1720                                                 }
1721                                                 
1722                                                 OnSelectedIndexChanged  (new EventArgs ());
1723                                                 OnSelectedValueChanged (new EventArgs ());
1724                                         }
1725                                         break;
1726                                 }                               
1727                                 
1728                                 default:
1729                                         break;
1730                         }                       
1731                 }
1732                 
1733                 private void ShiftSelection (int index)
1734                 {
1735                         int shorter_item = -1, dist = Items.Count + 1, cur_dist;
1736                         
1737                         foreach (int idx in selected_indices) {
1738                                 if (idx > index) {
1739                                         cur_dist = idx - index;
1740                                 }
1741                                 else {
1742                                         cur_dist = index - idx;                                 
1743                                 }
1744                                                 
1745                                 if (cur_dist < dist) {
1746                                         dist = cur_dist;
1747                                         shorter_item = idx;
1748                                 }
1749                         }
1750                         
1751                         if (shorter_item != -1) {
1752                                 int start, end;
1753                                 
1754                                 if (shorter_item > index) {
1755                                         start = index;
1756                                         end = shorter_item;
1757                                 } else {
1758                                         start = shorter_item;
1759                                         end = index;
1760                                 }
1761                                 
1762                                 ClearSelected ();
1763                                 for (int idx = start; idx <= end; idx++) {
1764                                         SelectItem (idx);       
1765                                 }
1766                         }
1767                 }
1768                 
1769                 internal int FocusedItem {
1770                         get { return focused_item; }
1771                         set {                   
1772                                 if (focused_item == value)
1773                                         return;
1774
1775                                 int prev = focused_item;                        
1776                         
1777                                 focused_item = value;
1778                         
1779                                 if (has_focus == false)
1780                                         return;
1781
1782                                 if (prev != -1)
1783                                         InvalidateItem (prev);
1784                         
1785                                 if (value != -1)
1786                                         InvalidateItem (value);
1787                         }
1788                 }
1789
1790                 // Removes an item in the Selection array and marks it visually as unselected
1791                 private void UnSelectItem (int index, bool remove)
1792                 {
1793                         if (index == -1)
1794                                 return;
1795
1796                         if (remove)
1797                                 selection.Remove (Items[index]);
1798
1799                         InvalidateItem (index);
1800                 }
1801
1802                 StringFormat string_format;
1803                 internal StringFormat StringFormat {
1804                         get {
1805                                 if (string_format == null) {
1806                                         string_format = new StringFormat ();
1807                                         if (RightToLeft == RightToLeft.Yes)
1808                                                 string_format.Alignment = StringAlignment.Far;
1809                                         else
1810                                                 string_format.Alignment = StringAlignment.Near;
1811                                         if (use_tabstops)
1812                                                 string_format.SetTabStops (0, new float [] {(float)(Font.Height * 3.7)});
1813                                 }
1814                                 return string_format;
1815                         }
1816
1817                 }
1818
1819                 internal virtual void CollectionChanged ()
1820                 {
1821                         if (sorted) 
1822                                 Sort ();
1823                         
1824                         if (Items.Count == 0) {
1825                                 selected_index = -1;
1826                                 focused_item = -1;
1827                                 top_index = 0;
1828                         }
1829                         
1830                         if (!IsHandleCreated || suspend_layout)
1831                                 return;
1832
1833                         LayoutListBox ();
1834
1835                         base.Refresh ();
1836                 }
1837
1838                 private void UpdateListBoxBounds ()
1839                 {
1840                         if (requested_height == -1)
1841                                 return;
1842
1843                         SetBounds(0, 0, 0, requested_height, BoundsSpecified.Height);
1844                 }
1845
1846                 private void UpdateScrollBars ()
1847                 {
1848                         items_area = ClientRectangle;
1849                         if (UpdateHorizontalScrollBar ()) {
1850                                 items_area.Height -= hscrollbar.Height;
1851                                 if (UpdateVerticalScrollBar ()) {
1852                                         items_area.Width -= vscrollbar.Width;
1853                                         UpdateHorizontalScrollBar ();
1854                                 }
1855                         } else if (UpdateVerticalScrollBar ()) {
1856                                 items_area.Width -= vscrollbar.Width;
1857                                 if (UpdateHorizontalScrollBar ()) {
1858                                         items_area.Height -= hscrollbar.Height;
1859                                         UpdateVerticalScrollBar ();
1860                                 }
1861                         }
1862
1863                         RepositionScrollBars ();
1864                 }
1865
1866                 /* Determines if the horizontal scrollbar has to be displyed */
1867                 private bool UpdateHorizontalScrollBar ()
1868                 {
1869                         bool show = false;
1870                         bool enabled = true;
1871
1872                         if (MultiColumn) {
1873                                 if (canvas_size.Width > items_area.Width) {
1874                                         show = true;
1875                                         hscrollbar.Maximum  = canvas_size.Width / ColumnWidthInternal - 1;
1876                                 } else if (ScrollAlwaysVisible == true) {
1877                                         enabled = false;
1878                                         show = true;
1879                                         hscrollbar.Maximum  = 0;
1880                                 }
1881                         } else if (canvas_size.Width > ClientRectangle.Width && HorizontalScrollbar) {
1882                                 show = true;                                    
1883                                 hscrollbar.Maximum = canvas_size.Width;
1884                                 hscrollbar.LargeChange = items_area.Width;
1885                         }
1886
1887                         hbar_offset = hscrollbar.Value;
1888                         hscrollbar.Enabled = enabled;
1889                         hscrollbar.Visible = show;
1890
1891                         return show;
1892                 }
1893
1894                 /* Determines if the vertical scrollbar has to be displyed */
1895                 private bool UpdateVerticalScrollBar ()
1896                 {
1897                         if (MultiColumn || Items.Count == 0) {
1898                                 vscrollbar.Visible = false;
1899                                 return false;
1900                         }
1901
1902                         bool show = false;
1903                         bool enabled = true;
1904                         if (canvas_size.Height > items_area.Height) {
1905                                 show = true;
1906                                 vscrollbar.Maximum = Items.Count - 1;
1907                                 vscrollbar.LargeChange = items_area.Height / ItemHeight;
1908                         } else if (ScrollAlwaysVisible) {
1909                                 show = true;
1910                                 enabled = false;
1911                                 vscrollbar.Maximum = 0;
1912                         }
1913
1914                         vscrollbar.Enabled = enabled;
1915                         vscrollbar.Visible = show;
1916
1917                         return show;
1918                 }
1919
1920                 // Value Changed
1921                 private void VerticalScrollEvent (object sender, EventArgs e)
1922                 {
1923                         int top_item = top_index;
1924
1925                         top_index = /*row_count + */ vscrollbar.Value;
1926                         last_visible_index = LastVisibleItem ();
1927
1928                         int diff = top_item - top_index;
1929
1930                         if (IsHandleCreated)
1931                                 XplatUI.ScrollWindow (Handle, items_area, 0, ItemHeight * diff, false);
1932                 }
1933
1934                 #endregion Private Methods
1935
1936                 [ListBindable (false)]
1937                 public class ObjectCollection : IList, ICollection, IEnumerable
1938                 {
1939                         internal class ListObjectComparer : IComparer
1940                         {
1941                                 public int Compare (object a, object b)
1942                                 {
1943                                         string str1 = a.ToString ();
1944                                         string str2 = b.ToString ();                                    
1945                                         return str1.CompareTo (str2);
1946                                 }
1947                         }
1948
1949                         private ListBox owner;
1950                         internal ArrayList object_items = new ArrayList ();
1951
1952                         public ObjectCollection (ListBox owner)
1953                         {
1954                                 this.owner = owner;
1955                         }
1956
1957                         public ObjectCollection (ListBox owner, object[] obj)
1958                         {
1959                                 this.owner = owner;
1960                                 AddRange (obj);
1961                         }
1962
1963                         public ObjectCollection (ListBox owner,  ObjectCollection obj)
1964                         {
1965                                 this.owner = owner;
1966                                 AddRange (obj);
1967                         }
1968
1969                         #region Public Properties
1970                         public int Count {
1971                                 get { return object_items.Count; }
1972                         }
1973
1974                         public bool IsReadOnly {
1975                                 get { return false; }
1976                         }
1977
1978                         [Browsable(false)]
1979                         [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
1980                         public virtual object this [int index] {
1981                                 get {
1982                                         if (index < 0 || index >= Count)
1983                                                 throw new ArgumentOutOfRangeException ("Index of out range");
1984
1985                                         return object_items[index];
1986                                 }
1987                                 set {
1988                                         if (index < 0 || index >= Count)
1989                                                 throw new ArgumentOutOfRangeException ("Index of out range");
1990                                         if (value == null)
1991                                                 throw new ArgumentNullException ("value");
1992
1993                                         object_items[index] = value;
1994                                         owner.CollectionChanged ();
1995                                 }
1996                         }
1997
1998                         bool ICollection.IsSynchronized {
1999                                 get { return false; }
2000                         }
2001
2002                         object ICollection.SyncRoot {
2003                                 get { return this; }
2004                         }
2005
2006                         bool IList.IsFixedSize {
2007                                 get { return false; }
2008                         }
2009
2010                         #endregion Public Properties
2011                         
2012                         #region Public Methods
2013                         public int Add (object item)
2014                         {
2015                                 int idx;
2016
2017                                 idx = AddItem (item);
2018                                 owner.CollectionChanged ();
2019                                 return idx;
2020                         }
2021
2022                         public void AddRange (object[] items)
2023                         {
2024                                 foreach (object mi in items)
2025                                         AddItem (mi);
2026
2027                                 owner.CollectionChanged ();
2028                         }
2029
2030                         public void AddRange (ObjectCollection col)
2031                         {
2032                                 foreach (object mi in col)
2033                                         AddItem (mi);
2034
2035                                 owner.CollectionChanged ();
2036                         }
2037
2038                         internal void AddRange (IList list)
2039                         {
2040                                 foreach (object mi in list)
2041                                         AddItem (mi);
2042
2043                                 owner.CollectionChanged ();
2044                         }
2045
2046                         public virtual void Clear ()
2047                         {
2048                                 owner.selection.Clear ();
2049                                 object_items.Clear ();
2050                                 owner.CollectionChanged ();
2051                         }
2052                         public bool Contains (object obj)
2053                         {
2054                                 return object_items.Contains (obj);
2055                         }
2056
2057                         public void CopyTo (object[] dest, int arrayIndex)
2058                         {
2059                                 object_items.CopyTo (dest, arrayIndex);
2060                         }
2061
2062                         void ICollection.CopyTo (Array dest, int index)
2063                         {
2064                                 object_items.CopyTo (dest, index);
2065                         }
2066
2067                         public IEnumerator GetEnumerator ()
2068                         {
2069                                 return object_items.GetEnumerator ();
2070                         }
2071
2072                         int IList.Add (object item)
2073                         {
2074                                 return Add (item);
2075                         }
2076
2077                         public int IndexOf (object value)
2078                         {
2079                                 return object_items.IndexOf (value);
2080                         }
2081
2082                         public void Insert (int index,  object item)
2083                         {
2084                                 if (index < 0 || index > Count)
2085                                         throw new ArgumentOutOfRangeException ("Index of out range");
2086                                         
2087                                 owner.BeginUpdate ();
2088                                 object_items.Insert (index, item);
2089                                 owner.CollectionChanged ();
2090                                 owner.EndUpdate ();
2091                         }
2092
2093                         public void Remove (object value)
2094                         {                               
2095                                 RemoveAt (IndexOf (value));                             
2096                         }
2097
2098                         public void RemoveAt (int index)
2099                         {
2100                                 if (index < 0 || index >= Count)
2101                                         throw new ArgumentOutOfRangeException ("Index of out range");
2102
2103                                 owner.selection.Remove (object_items [index]);
2104                                 object_items.RemoveAt (index);
2105                                 owner.CollectionChanged ();
2106                         }
2107                         #endregion Public Methods
2108
2109                         #region Private Methods
2110                         internal int AddItem (object item)
2111                         {
2112                                 if (item == null)
2113                                         throw new ArgumentNullException ("item");
2114
2115                                 int cnt = object_items.Count;
2116                                 object_items.Add (item);
2117                                 return cnt;
2118                         }
2119
2120                         internal void Sort ()
2121                         {
2122                                 object_items.Sort (new ListObjectComparer ());
2123                         }
2124
2125                         #endregion Private Methods
2126                 }
2127
2128                 public class SelectedIndexCollection : IList, ICollection, IEnumerable
2129                 {
2130                         private ListBox owner;
2131
2132                         public SelectedIndexCollection (ListBox owner)
2133                         {
2134                                 this.owner = owner;
2135                         }
2136
2137                         #region Public Properties
2138                         [Browsable (false)]
2139                         public int Count {
2140                                 get { return owner.selection.Count; }
2141                         }
2142
2143                         public bool IsReadOnly {
2144                                 get { return true; }
2145                         }
2146
2147                         public int this [int index] {
2148                                 get {
2149                                         if (index < 0 || index >= Count)
2150                                                 throw new ArgumentOutOfRangeException ("Index of out range");
2151
2152                                         return owner.Items.IndexOf (owner.selection [index]);
2153                                 }
2154                         }
2155
2156                         bool ICollection.IsSynchronized {
2157                                 get { return true; }
2158                         }
2159
2160                         bool IList.IsFixedSize{
2161                                 get { return true; }
2162                         }
2163
2164                         object ICollection.SyncRoot {
2165                                 get { return this; }
2166                         }
2167
2168                         #endregion Public Properties
2169
2170                         #region Public Methods
2171                         public bool Contains (int selectedIndex)
2172                         {
2173                                 foreach (object o in owner.selection)
2174                                         if (owner.Items.IndexOf (o) == selectedIndex)
2175                                                 return true;
2176                                 return false;
2177                         }
2178
2179                         public void CopyTo (Array dest, int index)
2180                         {
2181                                 foreach (object o in owner.selection)
2182                                         dest.SetValue(owner.Items.IndexOf (o), index++);
2183                         }
2184
2185                         public IEnumerator GetEnumerator ()
2186                         {
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 ();
2193                         }
2194
2195                         int IList.Add (object obj)
2196                         {
2197                                 throw new NotSupportedException ();
2198                         }
2199
2200                         void IList.Clear ()
2201                         {
2202                                 throw new NotSupportedException ();
2203                         }
2204
2205                         bool IList.Contains (object selectedIndex)
2206                         {
2207                                 return Contains ((int)selectedIndex);
2208                         }
2209
2210                         int IList.IndexOf (object selectedIndex)
2211                         {
2212                                 return IndexOf ((int) selectedIndex);
2213                         }
2214
2215                         void IList.Insert (int index, object value)
2216                         {
2217                                 throw new NotSupportedException ();
2218                         }
2219
2220                         void IList.Remove (object value)
2221                         {
2222                                 throw new NotSupportedException ();
2223                         }
2224
2225                         void IList.RemoveAt (int index)
2226                         {
2227                                 throw new NotSupportedException ();
2228                         }
2229
2230                         object IList.this[int index]{
2231                                 get {return owner.Items.IndexOf (owner.selection [index]); }
2232                                 set {throw new NotImplementedException (); }
2233                         }
2234
2235                         public int IndexOf (int selectedIndex)
2236                         {
2237                                 for (int i = 0; i < owner.selection.Count; i++)
2238                                         if (owner.Items.IndexOf (owner.selection [i]) == selectedIndex)
2239                                                 return i;
2240                                 return -1;
2241                         }
2242                         #endregion Public Methods
2243                 }
2244
2245                 public class SelectedObjectCollection : IList, ICollection, IEnumerable
2246                 {
2247                         private ListBox owner;
2248
2249                         public SelectedObjectCollection (ListBox owner)
2250                         {
2251                                 this.owner = owner;
2252                         }
2253
2254                         #region Public Properties
2255                         public int Count {
2256                                 get { return owner.selection.Count; }
2257                         }
2258
2259                         public bool IsReadOnly {
2260                                 get { return true; }
2261                         }
2262
2263                         [Browsable(false)]
2264                         [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
2265                         public object this [int index] {
2266                                 get {
2267                                         if (index < 0 || index >= Count)
2268                                                 throw new ArgumentOutOfRangeException ("Index of out range");
2269
2270                                         return owner.selection [index];
2271                                 }
2272                                 set {throw new NotSupportedException ();}
2273                         }
2274
2275                         bool ICollection.IsSynchronized {
2276                                 get { return true; }
2277                         }
2278
2279                         object ICollection.SyncRoot {
2280                                 get { return this; }
2281                         }
2282
2283                         bool IList.IsFixedSize {
2284                                 get { return true; }
2285                         }
2286
2287                         #endregion Public Properties
2288
2289                         #region Public Methods
2290                         public bool Contains (object selectedObject)
2291                         {
2292                                 return owner.selection.Contains (selectedObject);
2293                         }
2294
2295                         public void CopyTo (Array dest, int index)
2296                         {
2297                                 owner.selection.CopyTo (dest, index);
2298                         }
2299
2300                         int IList.Add (object value)
2301                         {
2302                                 throw new NotSupportedException ();
2303                         }
2304
2305                         void IList.Clear ()
2306                         {
2307                                 throw new NotSupportedException ();
2308                         }
2309
2310                         void IList.Insert (int index, object value)
2311                         {
2312                                 throw new NotSupportedException ();
2313                         }
2314
2315                         void IList.Remove (object value)
2316                         {
2317                                 throw new NotSupportedException ();
2318                         }
2319
2320                         void IList.RemoveAt (int index)
2321                         {
2322                                 throw new NotSupportedException ();
2323                         }
2324         
2325                         public int IndexOf (object item)
2326                         {
2327                                 return owner.selection.IndexOf (item);
2328                         }
2329
2330                         public IEnumerator GetEnumerator ()
2331                         {
2332                                 return owner.selection.GetEnumerator ();
2333                         }
2334
2335                         #endregion Public Methods
2336                 }
2337
2338         }
2339 }
2340