2007-09-28 Carlos Alberto Cortez <calberto.cortez@gmail.com>
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / ListBox.cs
index b8a3cc17e0c588d213dfa14c5523fa5fb1993e87..9b4ae5f6abcb8b184df3edb448cbb85684153108 100644 (file)
@@ -35,11 +35,20 @@ using System.ComponentModel.Design.Serialization;
 using System.Reflection;
 using System.Runtime.InteropServices;
 
+#if NET_2_0
+using System.Collections.Generic;
+#endif
+
 namespace System.Windows.Forms
 {
        [DefaultProperty("Items")]
        [DefaultEvent("SelectedIndexChanged")]
        [Designer ("System.Windows.Forms.Design.ListBoxDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
+#if NET_2_0
+       [DefaultBindingProperty ("SelectedValue")]
+       [ClassInterface (ClassInterfaceType.AutoDispatch)]
+       [ComVisible (true)]
+#endif
        public class ListBox : ListControl
        {
                public const int DefaultItemHeight = 13;
@@ -71,7 +80,6 @@ namespace System.Windows.Forms
                private SelectedIndexCollection selected_indices;               
                private SelectedObjectCollection selected_items;
                private ArrayList selection = new ArrayList ();
-               private ArrayList display_selection = new ArrayList ();
                private SelectionMode selection_mode = SelectionMode.One;
                private bool sorted = false;
                private bool use_tabstops = true;
@@ -82,17 +90,21 @@ namespace System.Windows.Forms
                private bool suspend_layout;
                private bool ctrl_pressed = false;
                private bool shift_pressed = false;
-               private bool has_focus = false;
                private bool explicit_item_height = false;
                private int top_index = 0;
                private int last_visible_index = 0;
                private Rectangle items_area;
                private int focused_item = -1;          
                private ObjectCollection items;
+#if NET_2_0
+               private IntegerCollection custom_tab_offsets;
+               private Padding padding;
+               private bool use_custom_tab_offsets;
+#endif
 
                public ListBox ()
                {
-                       border_style = BorderStyle.Fixed3D;                     
+                       InternalBorderStyle = BorderStyle.Fixed3D;                      
                        BackColor = ThemeEngine.Current.ColorWindow;
 
                        items = CreateItemCollection ();
@@ -117,6 +129,9 @@ namespace System.Windows.Forms
                        hscrollbar.Visible = false;
                        hscrollbar.ValueChanged += new EventHandler (HorizontalScrollEvent);
 
+                       Controls.AddImplicit (vscrollbar);
+                       Controls.AddImplicit (hscrollbar);
+
                        /* Events */
                        MouseDown += new MouseEventHandler (OnMouseDownLB);
                        MouseMove += new MouseEventHandler (OnMouseMoveLB);
@@ -128,9 +143,17 @@ namespace System.Windows.Forms
                        LostFocus += new EventHandler (OnLostFocus);
                        
                        SetStyle (ControlStyles.UserPaint, false);
+
+#if NET_2_0
+                       custom_tab_offsets = new IntegerCollection (this);
+#endif
                }
 
                #region Events
+               static object DrawItemEvent = new object ();
+               static object MeasureItemEvent = new object ();
+               static object SelectedIndexChangedEvent = new object ();
+
                [Browsable (false)]
                [EditorBrowsable (EditorBrowsableState.Never)]
                public new event EventHandler BackgroundImageChanged {
@@ -138,15 +161,50 @@ namespace System.Windows.Forms
                        remove { base.BackgroundImageChanged -= value; }
                }
 
+#if NET_2_0
+               [Browsable (false)]
+               [EditorBrowsable (EditorBrowsableState.Never)]
+               public new event EventHandler BackgroundImageLayoutChanged {
+                       add { base.BackgroundImageLayoutChanged += value; }
+                       remove { base.BackgroundImageLayoutChanged -= value; }
+               }
+
+               [Browsable (true)]
+               [EditorBrowsable (EditorBrowsableState.Always)]
+#else
                [Browsable (false)]
                [EditorBrowsable (EditorBrowsableState.Advanced)]
+#endif
                public new event EventHandler Click {
                        add { base.Click += value; }
                        remove { base.Click -= value; }
                }
 
-               public event DrawItemEventHandler DrawItem;
-               public event MeasureItemEventHandler MeasureItem;
+               public event DrawItemEventHandler DrawItem {
+                       add { Events.AddHandler (DrawItemEvent, value); }
+                       remove { Events.RemoveHandler (DrawItemEvent, value); }
+               }
+
+               public event MeasureItemEventHandler MeasureItem {
+                       add { Events.AddHandler (MeasureItemEvent, value); }
+                       remove { Events.RemoveHandler (MeasureItemEvent, value); }
+               }
+
+#if NET_2_0
+               [Browsable (true)]
+               [EditorBrowsable (EditorBrowsableState.Always)]
+               public new event MouseEventHandler MouseClick {
+                       add { base.MouseClick += value; }
+                       remove { base.MouseClick -= value; }
+               }
+
+               [Browsable (false)]
+               [EditorBrowsable (EditorBrowsableState.Never)]
+               public new event EventHandler PaddingChanged {
+                       add { base.PaddingChanged += value; }
+                       remove { base.PaddingChanged -= value; }
+               }
+#endif
 
                [Browsable (false)]
                [EditorBrowsable (EditorBrowsableState.Never)]
@@ -155,7 +213,10 @@ namespace System.Windows.Forms
                        remove { base.Paint -= value; }
                }
 
-               public event EventHandler SelectedIndexChanged;
+               public event EventHandler SelectedIndexChanged {
+                       add { Events.AddHandler (SelectedIndexChangedEvent, value); }
+                       remove { Events.RemoveHandler (SelectedIndexChangedEvent, value); }
+               }
 
                [Browsable (false)]
                [EditorBrowsable (EditorBrowsableState.Advanced)]
@@ -187,13 +248,22 @@ namespace System.Windows.Forms
                        }
                }
 
+#if NET_2_0
+               [Browsable (false)]
+               [EditorBrowsable (EditorBrowsableState.Never)]
+               public override ImageLayout BackgroundImageLayout {
+                       get { return base.BackgroundImageLayout; }
+                       set { base.BackgroundImageLayout = value; }
+               }
+#endif
+
                [DefaultValue (BorderStyle.Fixed3D)]
                [DispId(-504)]
                public BorderStyle BorderStyle {
                        get { return InternalBorderStyle; }
                        set { 
                                InternalBorderStyle = value; 
-                               UpdateBounds ();
+                               UpdateListBoxBounds ();
                        }
                }
 
@@ -220,6 +290,14 @@ namespace System.Windows.Forms
                        get { return base.CreateParams;}
                }
 
+#if NET_2_0
+               [Browsable (false)]
+               [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
+               public IntegerCollection CustomTabOffsets {
+                       get { return custom_tab_offsets; }
+               }
+#endif
+
                protected override Size DefaultSize {
                        get { return new Size (120, 96); }
                }
@@ -250,6 +328,13 @@ namespace System.Windows.Forms
                        }
                }
 
+#if NET_2_0
+               public override Font Font {
+                       get { return base.Font; }
+                       set { base.Font = value; }
+               }
+#endif
+
                public override Color ForeColor {
                        get { return base.ForeColor; }
                        set {
@@ -299,7 +384,7 @@ namespace System.Windows.Forms
                                        return;
 
                                integral_height = value;
-                               UpdateBounds ();
+                               UpdateListBoxBounds ();
                        }
                }
 
@@ -309,7 +394,7 @@ namespace System.Windows.Forms
                public virtual int ItemHeight {
                        get {
                                if (item_height == -1) {
-                                       SizeF sz = DeviceContext.MeasureString ("The quick brown Fox", Font);
+                                       SizeF sz = TextRenderer.MeasureString ("The quick brown Fox", Font);
                                        item_height = (int) sz.Height;
                                }
                                return item_height;
@@ -324,14 +409,17 @@ namespace System.Windows.Forms
 
                                item_height = value;
                                if (IntegralHeight)
-                                       UpdateBounds ();
-                               Layout ();
+                                       UpdateListBoxBounds ();
+                               LayoutListBox ();
                        }
                }
 
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
                [Localizable (true)]
                [Editor ("System.Windows.Forms.Design.ListControlStringCollectionEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
+#if NET_2_0
+               [MergableProperty (false)]
+#endif
                public ObjectCollection Items {
                        get { return items; }
                }
@@ -347,10 +435,20 @@ namespace System.Windows.Forms
                                        throw new ArgumentException ("A multicolumn ListBox cannot have a variable-sized height.");
                                        
                                multicolumn = value;
-                               Layout ();
+                               LayoutListBox ();
                        }
                }
 
+#if NET_2_0
+               [Browsable (false)]
+               [EditorBrowsable (EditorBrowsableState.Never)]
+               [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
+               public new Padding Padding {
+                       get { return padding; }
+                       set { padding = value; }
+               }
+#endif
+
                [Browsable (false)]
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
                [EditorBrowsable (EditorBrowsableState.Advanced)]
@@ -416,6 +514,17 @@ namespace System.Windows.Forms
                                else if (SelectionMode == SelectionMode.One)
                                        UnSelectItem (selected_index, true);
 
+                               if (value != -1 && value < top_index) {
+                                       top_index = value;
+                                       UpdateTopItem ();
+                               } else {
+                                       int rows = items_area.Height / ItemHeight;
+                                       if (value >= (top_index + rows))
+                                       {
+                                               top_index = value - rows + 1;
+                                               UpdateTopItem ();
+                                       }
+                               }
                                SelectItem (value);
                                selected_index = value;
                                FocusedItem = value;
@@ -542,6 +651,19 @@ namespace System.Windows.Forms
                        }
                }
 
+#if NET_2_0
+               [Browsable (false)]
+               [DefaultValue (false)]
+               public bool UseCustomTabOffsets {
+                       get { return use_custom_tab_offsets; }
+                       set { 
+                               if (use_custom_tab_offsets != value) {
+                                       use_custom_tab_offsets = value;
+                                       CalculateTabStops ();
+                               }
+                        }
+               }
+#endif
                [DefaultValue (true)]
                public bool UseTabStops {
                        get { return use_tabstops; }
@@ -550,15 +672,20 @@ namespace System.Windows.Forms
                                if (use_tabstops == value)
                                        return;
 
-                               use_tabstops = value;                                   
-                               if (use_tabstops)
-                                       StringFormat.SetTabStops (0, new float [] {(float)(Font.Height * 3.7)});
-                               else
-                                       StringFormat.SetTabStops (0, new float [0]);
-                               base.Refresh ();
+                               use_tabstops = value;
+                               
+                               CalculateTabStops ();
                        }
                }
 
+#if NET_2_0
+               protected override bool AllowSelection {
+                       get {
+                               return SelectionMode != SelectionMode.None;
+                       }
+               }
+#endif
+
                #endregion Public Properties
 
                #region Private Properties
@@ -578,6 +705,9 @@ namespace System.Windows.Forms
                #endregion Private Properties
 
                #region Public Methods
+#if NET_2_0
+               [Obsolete ("this method has been deprecated")]
+#endif
                protected virtual void AddItemsCore (object[] value)
                {
                        Items.AddRange (value);
@@ -605,7 +735,7 @@ namespace System.Windows.Forms
                public void EndUpdate ()
                {
                        suspend_layout = false;
-                       Layout ();
+                       LayoutListBox ();
                        base.Refresh ();
                }
 
@@ -707,9 +837,41 @@ namespace System.Windows.Forms
                                }                               
                        }
 
+                       if (this is CheckedListBox)
+                               rect.Width += 15;
+                               
                        return rect;
                }
 
+#if NET_2_0
+               [EditorBrowsable (EditorBrowsableState.Advanced)]
+               protected override Rectangle GetScaledBounds (Rectangle bounds, SizeF factor, BoundsSpecified specified)
+               {
+                       // For some reason, it always uses the control's Height instead of
+                       // the Height passed in
+                       bounds.Height = this.bounds.Height;
+
+                       if ((specified & BoundsSpecified.X) == BoundsSpecified.X)
+                               bounds.X = (int)Math.Round (bounds.Left * factor.Width);
+                       if ((specified & BoundsSpecified.Y) == BoundsSpecified.Y)
+                               bounds.Y = (int)Math.Round (bounds.Top * factor.Height);
+                       
+                       if ((specified & BoundsSpecified.Width) == BoundsSpecified.Width && !GetStyle (ControlStyles.FixedWidth))
+                               bounds.Width = (int)Math.Round (bounds.Width * factor.Width);
+                       if ((specified & BoundsSpecified.Height) == BoundsSpecified.Height && !GetStyle (ControlStyles.FixedHeight))
+                               bounds.Height = (int)Math.Round (bounds.Height * factor.Height);
+
+                       Size size = ClientSizeFromSize (bounds.Size);
+
+                       if ((specified & BoundsSpecified.Width) == BoundsSpecified.Width && !GetStyle (ControlStyles.FixedWidth))
+                               bounds.Width -= (int)((bounds.Width - size.Width) * (factor.Width - 1));
+                       if ((specified & BoundsSpecified.Height) == BoundsSpecified.Height && !GetStyle (ControlStyles.FixedHeight))
+                               bounds.Height -= (int)((bounds.Height - size.Height) * (factor.Height - 1));
+
+                       return bounds;
+               }
+#endif
+
                public bool GetSelected (int index)
                {
                        if (index < 0 || index >= Items.Count)
@@ -773,8 +935,10 @@ namespace System.Windows.Forms
                        switch (DrawMode) {
                        case DrawMode.OwnerDrawFixed:
                        case DrawMode.OwnerDrawVariable:
-                               if (DrawItem != null)
-                                       DrawItem (this, e);
+                               DrawItemEventHandler eh = (DrawItemEventHandler)(Events [DrawItemEvent]);
+                               if (eh != null)
+                                       eh (this, e);
+
                                break;
 
                        default:
@@ -793,23 +957,18 @@ namespace System.Windows.Forms
                        if (explicit_item_height) {
                                base.Refresh ();
                        } else {
-                               SizeF sz = DeviceContext.MeasureString ("The quick brown Fox", Font);
+                               SizeF sz = TextRenderer.MeasureString ("The quick brown Fox", Font);
                                item_height = (int) sz.Height;
                                if (IntegralHeight)
-                                       UpdateBounds ();
-                               Layout ();
+                                       UpdateListBoxBounds ();
+                               LayoutListBox ();
                        }
                }
 
                protected override void OnHandleCreated (EventArgs e)
                {
                        base.OnHandleCreated (e);
-
-                       SuspendLayout ();
-                       Controls.AddImplicit (vscrollbar);
-                       Controls.AddImplicit (hscrollbar);
-                       ResumeLayout ();
-                       Layout ();
+                       LayoutListBox ();
                }
 
                protected override void OnHandleDestroyed (EventArgs e)
@@ -821,9 +980,10 @@ namespace System.Windows.Forms
                {
                        if (draw_mode != DrawMode.OwnerDrawVariable)
                                return;
-                               
-                       if (MeasureItem != null)
-                               MeasureItem (this, e);
+
+                       MeasureItemEventHandler eh = (MeasureItemEventHandler)(Events [MeasureItemEvent]);
+                       if (eh != null)
+                               eh (this, e);
                }
 
                protected override void OnParentChanged (EventArgs e)
@@ -835,15 +995,16 @@ namespace System.Windows.Forms
                {
                        base.OnResize (e);
                        if (canvas_size.IsEmpty || MultiColumn)
-                               Layout ();
+                               LayoutListBox ();
                }
 
                protected override void OnSelectedIndexChanged (EventArgs e)
                {
                        base.OnSelectedIndexChanged (e);
 
-                       if (SelectedIndexChanged != null)
-                               SelectedIndexChanged (this, e);
+                       EventHandler eh = (EventHandler)(Events [SelectedIndexChangedEvent]);
+                       if (eh != null)
+                               eh (this, e);
                }
 
                protected override void OnSelectedValueChanged (EventArgs e)
@@ -868,6 +1029,32 @@ namespace System.Windows.Forms
                                item_heights.Remove (Items [index]);
                }
 
+#if NET_2_0
+               protected override void RefreshItems ()
+               {
+                       for (int i = 0; i < Items.Count; i++) {
+                               RefreshItem (i);
+                       }
+               }
+
+               public override void ResetBackColor ()
+               {
+                       base.ResetBackColor ();
+               }
+
+               public override void ResetForeColor ()
+               {
+                       base.ResetForeColor ();
+               }
+
+               protected override void ScaleControl (SizeF factor, BoundsSpecified specified)
+               {
+                       Rectangle new_bounds = GetScaledBounds (new Rectangle (Location, new Size (Width, Height)), factor, specified);
+
+                       SetBounds (new_bounds.X, new_bounds.Y, new_bounds.Width, new_bounds.Height, specified);
+               }
+#endif
+               
                protected override void SetBoundsCore (int x,  int y, int width, int height, BoundsSpecified specified)
                {
                        if ((specified & BoundsSpecified.Height) == BoundsSpecified.Height)
@@ -956,9 +1143,28 @@ namespace System.Windows.Forms
 
                #region Private Methods
 
+               private void CalculateTabStops ()
+               {
+                       if (use_tabstops) {
+#if NET_2_0
+                               if (use_custom_tab_offsets) {
+                                       float[] f = new float[custom_tab_offsets.Count];
+                                       custom_tab_offsets.CopyTo (f, 0);
+                                       StringFormat.SetTabStops (0, f);
+                               }
+                               else
+#endif
+                                       StringFormat.SetTabStops (0, new float[] { (float)(Font.Height * 3.7) });
+                       }       
+                       else
+                               StringFormat.SetTabStops (0, new float[0]);
+                               
+                       this.Invalidate ();
+               }
+
                private Size canvas_size;
 
-               private void Layout ()
+               private void LayoutListBox ()
                {
                        if (!IsHandleCreated || suspend_layout)
                                return;
@@ -995,9 +1201,14 @@ namespace System.Windows.Forms
                                height = Items.Count * ItemHeight;
                                width = 0;
                                for (int i = 0; i < Items.Count; i++) {
-                                       SizeF sz = DeviceContext.MeasureString (GetItemText (Items[i]), Font);
-                                       if ((int) sz.Width > width)
-                                               width = (int) sz.Width;
+                                       SizeF sz = TextRenderer.MeasureString (GetItemText (Items[i]), Font);
+                                       int t = (int)sz.Width;
+                                       
+                                       if (this is CheckedListBox)
+                                               t += 15;
+                                               
+                                       if (t > width)
+                                               width = t;
                                }
                                break;
                        }
@@ -1073,6 +1284,19 @@ namespace System.Windows.Forms
                        return item_rect;
                }
 
+               internal override int HeightInternal {
+                       get { 
+                               if (requested_height > -1)
+                                       return requested_height;
+                               else
+                                       return bounds.Height;
+                       }
+                       set {
+                               base.HeightInternal = value;
+                               requested_height = value;
+                       }
+               }
+
                // Value Changed
                private void HorizontalScrollEvent (object sender, EventArgs e)
                {
@@ -1093,7 +1317,8 @@ namespace System.Windows.Forms
                                if (hbar_offset < 0)
                                        hbar_offset = 0;
 
-                               XplatUI.ScrollWindow (Handle, items_area, old_offset - hbar_offset, 0, false);
+                               if (IsHandleCreated)
+                                       XplatUI.ScrollWindow (Handle, items_area, old_offset - hbar_offset, 0, false);
                        }
                }
 
@@ -1121,6 +1346,11 @@ namespace System.Windows.Forms
                        return -1;
                }
 
+               internal override bool IsInputCharInternal (char charCode)
+               {
+                       return true;
+               }
+
                private int LastVisibleItem ()
                {
                        Rectangle item_rect;
@@ -1163,7 +1393,8 @@ namespace System.Windows.Forms
                                else
                                        vscrollbar.Value = top_index;
                                Scroll (vscrollbar, vscrollbar.Value - top_index);
-                               XplatUI.ScrollWindow (Handle, items_area, 0, ItemHeight * (val - vscrollbar.Value), false);
+                               if (IsHandleCreated)
+                                       XplatUI.ScrollWindow (Handle, items_area, 0, ItemHeight * (val - vscrollbar.Value), false);
                        }
                }
                
@@ -1330,16 +1561,12 @@ namespace System.Windows.Forms
                
                private void OnGotFocus (object sender, EventArgs e)                    
                {                       
-                       has_focus = true;                       
-                       
                        if (FocusedItem != -1)
                                InvalidateItem (FocusedItem);
                }               
                
                private void OnLostFocus (object sender, EventArgs e)                   
                {                       
-                       has_focus = false;
-                       
                        if (FocusedItem != -1)
                                InvalidateItem (FocusedItem);
                }               
@@ -1432,6 +1659,8 @@ namespace System.Windows.Forms
 
                internal void InvalidateItem (int index)
                {
+                       if (!IsHandleCreated)
+                               return;
                        Rectangle bounds = GetItemDisplayRectangle (index, top_index);
                        if (ClientRectangle.IntersectsWith (bounds))
                                Invalidate (bounds);
@@ -1760,8 +1989,7 @@ namespace System.Windows.Forms
                                                string_format.Alignment = StringAlignment.Far;
                                        else
                                                string_format.Alignment = StringAlignment.Near;
-                                       if (use_tabstops)
-                                               string_format.SetTabStops (0, new float [] {(float)(Font.Height * 3.7)});
+                                       CalculateTabStops ();
                                }
                                return string_format;
                        }
@@ -1782,17 +2010,17 @@ namespace System.Windows.Forms
                        if (!IsHandleCreated || suspend_layout)
                                return;
 
-                       Layout ();
+                       LayoutListBox ();
 
                        base.Refresh ();
                }
 
-               private void UpdateBounds ()
+               private void UpdateListBoxBounds ()
                {
                        if (requested_height == -1)
                                return;
 
-                       SetBounds(0, 0, 0, requested_height, BoundsSpecified.Height);
+                       SetBounds(bounds.X, bounds.Y, bounds.Width, requested_height, BoundsSpecified.None);
                }
 
                private void UpdateScrollBars ()
@@ -1833,7 +2061,7 @@ namespace System.Windows.Forms
                        } else if (canvas_size.Width > ClientRectangle.Width && HorizontalScrollbar) {
                                show = true;                                    
                                hscrollbar.Maximum = canvas_size.Width;
-                               hscrollbar.LargeChange = items_area.Width;
+                               hscrollbar.LargeChange = Math.Max (0, items_area.Width);
                        }
 
                        hbar_offset = hscrollbar.Value;
@@ -1846,7 +2074,7 @@ namespace System.Windows.Forms
                /* Determines if the vertical scrollbar has to be displyed */
                private bool UpdateVerticalScrollBar ()
                {
-                       if (MultiColumn) {
+                       if (MultiColumn || Items.Count == 0) {
                                vscrollbar.Visible = false;
                                return false;
                        }
@@ -1879,23 +2107,184 @@ namespace System.Windows.Forms
 
                        int diff = top_item - top_index;
 
-                       XplatUI.ScrollWindow (Handle, items_area, 0, ItemHeight * diff, false);
+                       if (IsHandleCreated)
+                               XplatUI.ScrollWindow (Handle, items_area, 0, ItemHeight * diff, false);
                }
 
                #endregion Private Methods
 
-               [ListBindable (false)]
-               public class ObjectCollection : IList, ICollection, IEnumerable
+#if NET_2_0
+               public class IntegerCollection : IList, ICollection, IEnumerable
                {
-                       internal class ListObjectComparer : IComparer
+                       private ListBox owner;
+                       private List<int> list;
+                       
+                       #region Public Constructor
+                       public IntegerCollection (ListBox owner)
                        {
-                               private ListBox owner;
+                               this.owner = owner;
+                               list = new List<int> ();
+                       }
+                       #endregion
+
+                       #region Public Properties
+                       [Browsable (false)]
+                       public int Count {
+                               get { return list.Count; }
+                       }
                        
-                               public ListObjectComparer (ListBox owner)
-                               {
-                                       this.owner = owner;
+                       public int this [int index] {
+                               get { return list[index]; }
+                               set { list[index] = value; owner.CalculateTabStops (); }
+                       }
+                       #endregion
+
+                       #region Public Methods
+                       public int Add (int item)
+                       {
+                               // This collection does not allow duplicates
+                               if (!list.Contains (item)) {
+                                       list.Add (item);
+                                       list.Sort ();
+                                       owner.CalculateTabStops ();
                                }
                                
+                               return list.IndexOf (item);
+                       }
+                       
+                       public void AddRange (int[] items)
+                       {
+                               foreach (int i in items)
+                                       if (!list.Contains (i))
+                                               list.Add (i);
+                                               
+                               list.Sort ();
+                       }
+                       
+                       public void AddRange (IntegerCollection value)
+                       {
+                               foreach (int i in value)
+                                       if (!list.Contains (i))
+                                               list.Add (i);
+
+                               list.Sort ();
+                       }
+                       
+                       public void Clear ()
+                       {
+                               list.Clear ();
+                               owner.CalculateTabStops ();
+                       }
+                       
+                       public bool Contains (int item)
+                       {
+                               return list.Contains (item);
+                       }
+                       
+                       public void CopyTo (Array destination, int index)
+                       {
+                               for (int i = index; i < list.Count; i++)
+                                       destination.SetValue (list[i], i);
+                       }
+                       
+                       public int IndexOf (int item)
+                       {
+                               return list.IndexOf (item);
+                       }
+                       
+                       public void Remove (int item)
+                       {
+                               list.Remove (item);
+                               list.Sort ();
+                               owner.CalculateTabStops ();
+                       }
+                       
+                       public void RemoveAt (int index)
+                       {
+                               list.RemoveAt (index);
+                               list.Sort ();
+                               owner.CalculateTabStops ();
+                       }
+                       #endregion
+
+                       #region IEnumerable Members
+                       IEnumerator IEnumerable.GetEnumerator ()
+                       {
+                               return list.GetEnumerator ();
+                       }
+                       #endregion
+
+                       #region IList Members
+                       int IList.Add (object value)
+                       {
+                               return Add ((int)value);
+                       }
+
+                       void IList.Clear ()
+                       {
+                               Clear ();
+                       }
+
+                       bool IList.Contains (object value)
+                       {
+                               return Contains ((int)value);
+                       }
+
+                       int IList.IndexOf (object value)
+                       {
+                               return IndexOf ((int)value);
+                       }
+
+                       void IList.Insert (int index, object value)
+                       {
+                               throw new Exception ("The method or operation is not implemented.");
+                       }
+
+                       bool IList.IsFixedSize
+                       {
+                               get { return false; }
+                       }
+
+                       bool IList.IsReadOnly
+                       {
+                               get { return false; }
+                       }
+
+                       void IList.Remove (object value)
+                       {
+                               Remove ((int)value);
+                       }
+
+                       void IList.RemoveAt (int index)
+                       {
+                               RemoveAt (index);
+                       }
+
+                       object IList.this[int index] {
+                               get { return this[index]; }
+                               set { this[index] = (int)value; }
+                       }
+                       #endregion
+
+                       #region ICollection Members
+                       bool ICollection.IsSynchronized
+                       {
+                               get { throw new Exception ("The method or operation is not implemented."); }
+                       }
+
+                       object ICollection.SyncRoot
+                       {
+                               get { throw new Exception ("The method or operation is not implemented."); }
+                       }
+                       #endregion
+               }
+#endif
+
+               [ListBindable (false)]
+               public class ObjectCollection : IList, ICollection, IEnumerable
+               {
+                       internal class ListObjectComparer : IComparer
+                       {
                                public int Compare (object a, object b)
                                {
                                        string str1 = a.ToString ();
@@ -1979,6 +2368,9 @@ namespace System.Windows.Forms
 
                        public void AddRange (object[] items)
                        {
+                               if (items == null)
+                                       throw new ArgumentNullException ("items");
+
                                foreach (object mi in items)
                                        AddItem (mi);
 
@@ -1987,6 +2379,9 @@ namespace System.Windows.Forms
 
                        public void AddRange (ObjectCollection col)
                        {
+                               if (col == null)
+                                       throw new ArgumentNullException ("col");
+
                                foreach (object mi in col)
                                        AddItem (mi);
 
@@ -2009,6 +2404,9 @@ namespace System.Windows.Forms
                        }
                        public bool Contains (object obj)
                        {
+                               if (obj == null)
+                                       throw new ArgumentNullException ("obj");
+
                                return object_items.Contains (obj);
                        }
 
@@ -2034,6 +2432,9 @@ namespace System.Windows.Forms
 
                        public int IndexOf (object value)
                        {
+                               if (value == null)
+                                       throw new ArgumentNullException ("value");
+
                                return object_items.IndexOf (value);
                        }
 
@@ -2041,6 +2442,8 @@ namespace System.Windows.Forms
                        {
                                if (index < 0 || index > Count)
                                        throw new ArgumentOutOfRangeException ("Index of out range");
+                               if (item == null)
+                                       throw new ArgumentNullException ("item");
                                        
                                owner.BeginUpdate ();
                                object_items.Insert (index, item);
@@ -2050,6 +2453,9 @@ namespace System.Windows.Forms
 
                        public void Remove (object value)
                        {                               
+                               if (value == null)
+                                       return;
+
                                RemoveAt (IndexOf (value));                             
                        }
 
@@ -2077,7 +2483,7 @@ namespace System.Windows.Forms
 
                        internal void Sort ()
                        {
-                               object_items.Sort (new ListObjectComparer (owner));
+                               object_items.Sort (new ListObjectComparer ());
                        }
 
                        #endregion Private Methods
@@ -2126,6 +2532,24 @@ namespace System.Windows.Forms
                        #endregion Public Properties
 
                        #region Public Methods
+#if NET_2_0
+                       public void Add (int index)
+                       {
+                               object item = owner.items[index];
+                               
+                               if (!owner.selection.Contains (item)) {
+                                       owner.selection.Add (item);
+                                       owner.CollectionChanged ();
+                               }
+                       }
+
+                       public void Clear ()
+                       {
+                               owner.selection.Clear ();
+                               owner.CollectionChanged ();
+                       }
+#endif
+
                        public bool Contains (int selectedIndex)
                        {
                                foreach (object o in owner.selection)
@@ -2150,6 +2574,19 @@ namespace System.Windows.Forms
                                return indices.GetEnumerator ();
                        }
 
+#if NET_2_0
+                       public void Remove (int index)
+                       {
+                               object value = owner.items[index];
+                               
+                               if (value == null)
+                                       return;
+
+                               owner.selection.Remove (value);
+                               owner.CollectionChanged ();
+                       }
+#endif
+
                        int IList.Add (object obj)
                        {
                                throw new NotSupportedException ();
@@ -2245,6 +2682,22 @@ namespace System.Windows.Forms
                        #endregion Public Properties
 
                        #region Public Methods
+#if NET_2_0
+                       public void Add (object item)
+                       {
+                               if (!owner.selection.Contains (item)) {
+                                       owner.selection.Add (item);
+                                       owner.CollectionChanged ();
+                               }
+                       }
+
+                       public void Clear ()
+                       {
+                               owner.selection.Clear ();
+                               owner.CollectionChanged ();
+                       }
+#endif
+
                        public bool Contains (object selectedObject)
                        {
                                return owner.selection.Contains (selectedObject);
@@ -2255,6 +2708,17 @@ namespace System.Windows.Forms
                                owner.selection.CopyTo (dest, index);
                        }
 
+#if NET_2_0
+                       public void Remove (object value)
+                       {
+                               if (value == null)
+                                       return;
+
+                               owner.selection.Remove (value);
+                               owner.CollectionChanged ();
+                       }
+#endif
+
                        int IList.Add (object value)
                        {
                                throw new NotSupportedException ();