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