merged Sys.Web.Services 2.0 support in my branch:
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / ComboBox.cs
index 6ee911ae53fd3c22e4d4eaa0d1699d7e3e562f5b..5c9d713b1307d32c6abae34a57b583abe2403a74 100644 (file)
@@ -22,8 +22,7 @@
 // Authors:
 //     Jordi Mas i Hernandez, jordi@ximian.com
 //     Mike Kestner  <mkestner@novell.com>
-//
-// NOT COMPLETE
+//     Daniel Nauck    (dna(at)mono-project(dot)de)
 
 using System;
 using System.Drawing;
@@ -37,16 +36,20 @@ using System.Runtime.InteropServices;
 
 namespace System.Windows.Forms
 {
-
        [DefaultProperty("Items")]
        [DefaultEvent("SelectedIndexChanged")]
        [Designer ("System.Windows.Forms.Design.ComboBoxDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
+#if NET_2_0
+       [DefaultBindingProperty ("Text")]
+       [ClassInterface (ClassInterfaceType.AutoDispatch)]
+       [ComVisible(true)]
+#endif
        public class ComboBox : ListControl
        {
                private DrawMode draw_mode = DrawMode.Normal;
                private ComboBoxStyle dropdown_style = (ComboBoxStyle)(-1);
                private int dropdown_width = -1;                
-               private object selected_item = null;
+               private int selected_index = -1;
                internal ObjectCollection items = null;
                private bool suspend_ctrlupdate;
                private int maxdrop_items = 8;                  
@@ -54,7 +57,7 @@ namespace System.Windows.Forms
                private bool sorted;
                private int max_length;
                private ComboListBox listbox_ctrl;              
-               private TextBox textbox_ctrl;
+               private ComboTextBox textbox_ctrl;
                private bool process_textchanged_event = true;
                private bool item_height_specified = false;
                private int item_height;
@@ -67,15 +70,18 @@ namespace System.Windows.Forms
                private Rectangle button_area;
                private Rectangle listbox_area;
                private const int button_width = 16;
+#if NET_2_0
+               private AutoCompleteStringCollection auto_complete_custom_source = null;
+               private AutoCompleteMode auto_complete_mode = AutoCompleteMode.None;
+               private AutoCompleteSource auto_complete_source = AutoCompleteSource.None;
+#endif
 
                [ComVisible(true)]
                public class ChildAccessibleObject : AccessibleObject {
-                       private ComboBox        owner;
-                       private IntPtr          handle;
 
-                       public ChildAccessibleObject (ComboBox owner, IntPtr handle) {
-                               this.owner = owner;
-                               this.handle = handle;
+                       public ChildAccessibleObject (ComboBox owner, IntPtr handle)
+                               : base (owner)
+                       {
                        }
 
                        public override string Name {
@@ -97,6 +103,7 @@ namespace System.Windows.Forms
                        MouseDown += new MouseEventHandler (OnMouseDownCB);
                        MouseUp += new MouseEventHandler (OnMouseUpCB);
                        MouseMove += new MouseEventHandler (OnMouseMoveCB);
+                       MouseWheel += new MouseEventHandler (OnMouseWheelCB);                           
                        KeyDown +=new KeyEventHandler(OnKeyDownCB);
                }
 
@@ -108,11 +115,33 @@ namespace System.Windows.Forms
                        add { base.BackgroundImageChanged += value; }
                        remove { base.BackgroundImageChanged -= value; }
                }
-               
-               public event DrawItemEventHandler DrawItem;             
-               public event EventHandler DropDown;             
-               public event EventHandler DropDownStyleChanged;         
-               public event MeasureItemEventHandler MeasureItem;
+
+               static object DrawItemEvent = new object ();
+               static object DropDownEvent = new object ();
+               static object DropDownStyleChangedEvent = new object ();
+               static object MeasureItemEvent = new object ();
+               static object SelectedIndexChangedEvent = new object ();
+               static object SelectionChangeCommittedEvent = new object ();
+
+               public event DrawItemEventHandler DrawItem {
+                       add { Events.AddHandler (DrawItemEvent, value); }
+                       remove { Events.RemoveHandler (DrawItemEvent, value); }
+               }
+
+               public event EventHandler DropDown {
+                       add { Events.AddHandler (DropDownEvent, value); }
+                       remove { Events.RemoveHandler (DropDownEvent, value); }
+               }
+
+               public event EventHandler DropDownStyleChanged {
+                       add { Events.AddHandler (DropDownStyleChangedEvent, value); }
+                       remove { Events.RemoveHandler (DropDownStyleChangedEvent, value); }
+               }
+
+               public event MeasureItemEventHandler MeasureItem {
+                       add { Events.AddHandler (MeasureItemEvent, value); }
+                       remove { Events.RemoveHandler (MeasureItemEvent, value); }
+               }
                
                [Browsable (false)]
                [EditorBrowsable (EditorBrowsableState.Never)]
@@ -121,11 +150,83 @@ namespace System.Windows.Forms
                        remove { base.Paint -= value; }
                }
                
-               public event EventHandler SelectedIndexChanged;         
-               public event EventHandler SelectionChangeCommitted;
+               public event EventHandler SelectedIndexChanged {
+                       add { Events.AddHandler (SelectedIndexChangedEvent, value); }
+                       remove { Events.RemoveHandler (SelectedIndexChangedEvent, value); }
+               }
+
+               public event EventHandler SelectionChangeCommitted {
+                       add { Events.AddHandler (SelectionChangeCommittedEvent, value); }
+                       remove { Events.RemoveHandler (SelectionChangeCommittedEvent, value); }
+               }
+
                #endregion Events
 
                #region Public Properties
+#if NET_2_0
+               [MonoTODO("AutoCompletion algorithm is currently not implemented.")]
+               [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
+               [Browsable (true)]
+               [EditorBrowsable (EditorBrowsableState.Always)]
+               [Localizable (true)]
+               [Editor ("System.Windows.Forms.Design.ListControlStringCollectionEditor, " + Consts.AssemblySystem_Design,
+                        "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
+               public AutoCompleteStringCollection AutoCompleteCustomSource { 
+                       get {
+                               if(auto_complete_custom_source == null) {
+                                       auto_complete_custom_source = new AutoCompleteStringCollection ();
+                                       auto_complete_custom_source.CollectionChanged += new CollectionChangeEventHandler (OnAutoCompleteCustomSourceChanged);
+                               }
+                               return auto_complete_custom_source;
+                       }
+                       set {
+                               if(auto_complete_custom_source == value)
+                                       return;
+
+                               if(auto_complete_custom_source != null) //remove eventhandler from old collection
+                                       auto_complete_custom_source.CollectionChanged -= new CollectionChangeEventHandler (OnAutoCompleteCustomSourceChanged);
+
+                               auto_complete_custom_source = value;
+
+                               if(auto_complete_custom_source != null)
+                                       auto_complete_custom_source.CollectionChanged += new CollectionChangeEventHandler (OnAutoCompleteCustomSourceChanged);
+                       }
+               }
+
+               [MonoTODO("AutoCompletion algorithm is currently not implemented.")]
+               [Browsable (true)]
+               [EditorBrowsable (EditorBrowsableState.Always)]
+               [DefaultValue (AutoCompleteMode.None)]
+               public AutoCompleteMode AutoCompleteMode {
+                       get { return auto_complete_mode; }
+                       set {
+                               if(auto_complete_mode == value)
+                                       return;
+
+                               if((value < AutoCompleteMode.None) || (value > AutoCompleteMode.SuggestAppend))
+                                       throw new InvalidEnumArgumentException (Locale.GetText ("Enum argument value '{0}' is not valid for AutoCompleteMode", value));
+
+                               auto_complete_mode = value;
+                       }
+               }
+
+               [MonoTODO("AutoCompletion algorithm is currently not implemented.")]
+               [Browsable (true)]
+               [EditorBrowsable (EditorBrowsableState.Always)]
+               [DefaultValue (AutoCompleteSource.None)]
+               public AutoCompleteSource AutoCompleteSource {
+                       get { return auto_complete_source; }
+                       set {
+                               if(auto_complete_source == value)
+                                       return;
+
+                               if(!Enum.IsDefined (typeof (AutoCompleteSource), value))
+                                       throw new InvalidEnumArgumentException (Locale.GetText ("Enum argument value '{0}' is not valid for AutoCompleteSource", value));
+
+                               auto_complete_source = value;
+                       }
+               }
+#endif
                public override Color BackColor {
                        get { return base.BackColor; }
                        set {
@@ -191,7 +292,9 @@ namespace System.Windows.Forms
 
                                if (dropdown_style == value)
                                        return;                                 
-                                                                       
+
+                               SuspendLayout ();
+
                                if (dropdown_style == ComboBoxStyle.Simple) {
                                        if (listbox_ctrl != null) {                                             
                                                Controls.RemoveImplicit (listbox_ctrl);
@@ -213,36 +316,34 @@ namespace System.Windows.Forms
                                        
                                        CreateComboListBox ();
 
-                                       if (IsHandleCreated)
+                                       if (IsHandleCreated) {
                                                Controls.AddImplicit (listbox_ctrl);
+                                               listbox_ctrl.Visible = true;
+                                       }
                                } else {
                                        show_dropdown_button = true;
                                        button_state = ButtonState.Normal;
                                }                               
        
                                if (dropdown_style != ComboBoxStyle.DropDownList && textbox_ctrl == null) {
-                                       textbox_ctrl = new FixedSizeTextBox ();
+                                       textbox_ctrl = new ComboTextBox (this);
+                                       object selected_item = SelectedItem;
                                        if (selected_item != null)
                                                textbox_ctrl.Text = GetItemText (selected_item);
                                        textbox_ctrl.BorderStyle = BorderStyle.None;
                                        textbox_ctrl.TextChanged += new EventHandler (OnTextChangedEdit);
-                                       textbox_ctrl.KeyPress += new KeyPressEventHandler(textbox_ctrl_KeyPress);
-                                       textbox_ctrl.KeyDown += new KeyEventHandler (OnKeyDownCB);
-                                       textbox_ctrl.GotFocus += new EventHandler(textbox_ctrl_GotFocus);
-                                       textbox_ctrl.LostFocus += new EventHandler(textbox_ctrl_LostFocus);
-                                       textbox_ctrl.MouseDown += new MouseEventHandler(textbox_ctrl_MouseDown);
-                                       textbox_ctrl.MouseMove += new MouseEventHandler(textbox_ctrl_MouseMove);
-                                       textbox_ctrl.MouseUp += new MouseEventHandler(textbox_ctrl_MouseUp);
+                                       textbox_ctrl.Click += new EventHandler (OnTextBoxClick);
 
                                        if (IsHandleCreated == true) {
                                                Controls.AddImplicit (textbox_ctrl);
                                        }
                                }
                                
+                               ResumeLayout ();
                                OnDropDownStyleChanged (EventArgs.Empty);
                                
-                               Layout ();
-                               UpdateBounds ();
+                               LayoutComboBox ();
+                               UpdateComboBoxBounds ();
                                Refresh ();
                        }
                }
@@ -259,17 +360,22 @@ namespace System.Windows.Forms
                                        return;
                                        
                                if (value < 1)
-                                       throw new ArgumentException ("The DropDownWidth value is less than one");
+#if NET_2_0
+                                       throw new ArgumentOutOfRangeException ("DropDownWidth",
+                                               "The DropDownWidth value is less than one.");
+#else
+                                       throw new ArgumentException ("The DropDownWidth value is less than one.");
+#endif
 
-                               dropdown_width = value;                         
+                               dropdown_width = value;
                        }
                }
                
                [Browsable (false)]
-               [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]              
+               [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
                public bool DroppedDown {
                        get { 
-                               if (dropdown_style == ComboBoxStyle.Simple)                             
+                               if (dropdown_style == ComboBoxStyle.Simple)
                                        return true;
                                
                                return dropped_down;
@@ -309,7 +415,7 @@ namespace System.Windows.Forms
                                        return;
 
                                integral_height = value;
-                               UpdateBounds ();
+                               UpdateComboBoxBounds ();
                                Refresh ();
                        }
                }
@@ -324,21 +430,29 @@ namespace System.Windows.Forms
                                return item_height;
                        }
                        set {
-                               if (value < 0)
-                                       throw new ArgumentException ("The item height value is less than zero");
+                               if (value < 1)
+#if NET_2_0
+                                       throw new ArgumentOutOfRangeException ("ItemHeight",
+                                               "The item height value is less than one.");
+#else
+                                       throw new ArgumentException ("The item height value is less than one.");
+#endif
 
                                item_height_specified = true;
                                item_height = value;
                                if (IntegralHeight)
-                                       UpdateBounds ();
-                               Layout ();
+                                       UpdateComboBoxBounds ();
+                               LayoutComboBox ();
                                Refresh ();
                        }
                }
 
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
                [Localizable (true)]
-               [Editor ("System.Windows.Forms.Design.ListControlStringCollectionEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]                
+               [Editor ("System.Windows.Forms.Design.ListControlStringCollectionEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
+#if NET_2_0
+               [MergableProperty (false)]
+#endif
                public ComboBox.ObjectCollection Items {
                        get { return items; }
                }
@@ -387,16 +501,31 @@ namespace System.Windows.Forms
                [Browsable (false)]
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
                public override int SelectedIndex {
-                       get { return Items.IndexOf (selected_item); }
+                       get { return selected_index; }
                        set {
+                               if (selected_index == value)
+                                       return;
+
                                if (value <= -2 || value >= Items.Count)
                                        throw new ArgumentOutOfRangeException ("Index of out range");
+                               selected_index = value;
 
-                               object item = null;
-                               if (value != -1)
-                                       item = Items [value];
+                               if (dropdown_style != ComboBoxStyle.DropDownList) {
+                                       if (value == -1)
+                                               SetControlText("");
+                                       else
+                                               SetControlText (GetItemText (Items [value]));
+                               }
+
+                               if (DropDownStyle == ComboBoxStyle.DropDownList)
+                                       Invalidate ();
+
+                               if (listbox_ctrl != null)
+                                       listbox_ctrl.HighlightedIndex = value;
 
-                               SelectedItem = item;
+                               OnSelectedValueChanged (new EventArgs ());
+                               OnSelectedIndexChanged (new EventArgs ());
+                               OnSelectedItemChanged (new EventArgs ());
                        }
                }
 
@@ -404,30 +533,13 @@ namespace System.Windows.Forms
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
                [Bindable(true)]
                public object SelectedItem {
-                       get { return selected_item; }
+                       get { return selected_index == -1 ? null : Items [selected_index]; }
                        set {                           
-                               if (selected_item == value)
+                               object item = selected_index == -1 ? null : Items [selected_index];
+                               if (item == value)
                                        return;
 
-                               selected_item = value;
-                               
-                               if (dropdown_style != ComboBoxStyle.DropDownList) {
-                                       if (selected_item == null)
-                                               SetControlText("");
-                                       else {
-                                               SetControlText (GetItemText (selected_item));
-                                               SelectAll ();
-                                       }
-                               }
-
-                               OnSelectedValueChanged (new EventArgs ());
-                               OnSelectedIndexChanged  (new EventArgs ());
-                               OnSelectedItemChanged (new EventArgs ());
-                               if (DropDownStyle == ComboBoxStyle.DropDownList)
-                                       Refresh ();
-
-                               if (listbox_ctrl != null)
-                                       listbox_ctrl.HighlightedItem = value;
+                               SelectedIndex = Items.IndexOf (value);
                        }
                }
                
@@ -455,7 +567,8 @@ namespace System.Windows.Forms
                                if (dropdown_style == ComboBoxStyle.DropDownList) 
                                        return 0;
                                
-                               return textbox_ctrl.SelectionLength;
+                               int result = textbox_ctrl.SelectionLength;
+                               return result == -1 ? 0 : result;
                        }
                        set {
                                if (dropdown_style == ComboBoxStyle.DropDownList) 
@@ -497,6 +610,11 @@ namespace System.Windows.Forms
                                        return;
 
                                sorted = value;
+                               SelectedIndex = -1;
+                               if (sorted) {
+                                       Items.Sort ();
+                                       LayoutComboBox ();
+                               }
                        }
                }
 
@@ -536,6 +654,9 @@ namespace System.Windows.Forms
                #endregion Public Properties
 
                #region Public Methods
+#if NET_2_0
+               [Obsolete ("This method has been deprecated")]
+#endif
                protected virtual void AddItemsCore (object[] value)
                {
                        
@@ -641,6 +762,8 @@ namespace System.Windows.Forms
                        switch (keyData) {
                        case Keys.Up:
                        case Keys.Down:
+                       case Keys.Left:
+                       case Keys.Right:
                        case Keys.PageUp:
                        case Keys.PageDown:                     
                                return true;
@@ -658,7 +781,7 @@ namespace System.Windows.Forms
                protected override void OnDataSourceChanged (EventArgs e)
                {
                        base.OnDataSourceChanged (e);
-                       BindDataItems (items);
+                       BindDataItems ();
                        
                        if (DataSource == null || DataManager == null) {
                                SelectedIndex = -1;
@@ -675,7 +798,7 @@ namespace System.Windows.Forms
                        if (DataManager == null || !IsHandleCreated)
                               return;
 
-                       BindDataItems (items);
+                       BindDataItems ();
                        SelectedIndex = DataManager.Position;
                }
 
@@ -684,8 +807,9 @@ 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:
                                ThemeEngine.Current.DrawComboBoxItem (this, e);
@@ -695,14 +819,16 @@ namespace System.Windows.Forms
 
                protected virtual void OnDropDown (EventArgs e)
                {
-                       if (DropDown != null)
-                               DropDown (this, e);
+                       EventHandler eh = (EventHandler)(Events [DropDownEvent]);
+                       if (eh != null)
+                               eh (this, e);
                }
 
                protected virtual void OnDropDownStyleChanged (EventArgs e)
                {
-                       if (DropDownStyleChanged != null)
-                               DropDownStyleChanged (this, e);
+                       EventHandler eh = (EventHandler)(Events [DropDownStyleChangedEvent]);
+                       if (eh != null)
+                               eh (this, e);
                }
 
                protected override void OnFontChanged (EventArgs e)
@@ -718,9 +844,9 @@ namespace System.Windows.Forms
                        }
 
                        if (IntegralHeight)
-                               UpdateBounds ();
+                               UpdateComboBoxBounds ();
 
-                       Layout ();
+                       LayoutComboBox ();
                }
 
                protected override void OnForeColorChanged (EventArgs e)
@@ -729,28 +855,59 @@ namespace System.Windows.Forms
                }
 
                [EditorBrowsable(EditorBrowsableState.Advanced)]                
-               protected override void OnGotFocus (EventArgs e) {                      
-                       has_focus = true;
-                       Invalidate ();
+               protected override void OnGotFocus (EventArgs e)
+               {
+                       if (dropdown_style == ComboBoxStyle.DropDownList) {
+                               // We draw DDL styles manually, so they require a
+                               // refresh to have their selection drawn
+                               Invalidate ();
+                       }
+                       
+                       if (textbox_ctrl != null) {
+                               textbox_ctrl.SetSelectable (false);
+                               textbox_ctrl.ActivateCaret (true);
+                               textbox_ctrl.ShowSelection = true;
+                               textbox_ctrl.SelectAll ();
+                       }
+
+                       base.OnGotFocus (e);
                }
 
                [EditorBrowsable(EditorBrowsableState.Advanced)]                
-               protected override void OnLostFocus (EventArgs e) {                     
-                       has_focus = false;
-                       Invalidate ();
-               }               
+               protected override void OnLostFocus (EventArgs e)
+               {
+                       if (dropdown_style == ComboBoxStyle.DropDownList) {
+                               // We draw DDL styles manually, so they require a
+                               // refresh to have their selection drawn
+                               Invalidate ();
+                       }
+
+                       if (listbox_ctrl != null && dropped_down) {
+                               listbox_ctrl.HideWindow ();
+                       }
+
+                       if (textbox_ctrl != null) {
+                               textbox_ctrl.SetSelectable (true);
+                               textbox_ctrl.ActivateCaret (false);
+                               textbox_ctrl.ShowSelection = false;
+                       }
+
+                       base.OnLostFocus (e);
+               }
 
                protected override void OnHandleCreated (EventArgs e)
                {
                        base.OnHandleCreated (e);
 
-                       if (listbox_ctrl != null)
+                       if (listbox_ctrl != null) {
                                Controls.AddImplicit (listbox_ctrl);
-                       
+                               listbox_ctrl.Visible = true;
+                       }
+
                        if (textbox_ctrl != null)
                                Controls.AddImplicit (textbox_ctrl);
 
-                       Layout ();
+                       LayoutComboBox ();
                }
 
                protected override void OnHandleDestroyed (EventArgs e)
@@ -760,13 +917,18 @@ namespace System.Windows.Forms
 
                protected override void OnKeyPress (KeyPressEventArgs e)
                {
+                       // int index = FindStringCaseInsensitive (e.KeyChar.ToString (), SelectedIndex);
+                       //if (index != -1)
+                       //      SelectedIndex = index;
+
                        base.OnKeyPress (e);
                }
 
                protected virtual void OnMeasureItem (MeasureItemEventArgs e)
                {
-                       if (MeasureItem != null)
-                               MeasureItem (this, e);
+                       MeasureItemEventHandler eh = (MeasureItemEventHandler)(Events [MeasureItemEvent]);
+                       if (eh != null)
+                               eh (this, e);
                }
 
                protected override void OnParentBackColorChanged (EventArgs e)
@@ -776,7 +938,7 @@ namespace System.Windows.Forms
 
                protected override void OnResize (EventArgs e)
                {                       
-                       Layout ();
+                       LayoutComboBox ();
                        if (listbox_ctrl != null)
                                listbox_ctrl.CalcListBoxArea ();
                }
@@ -785,8 +947,9 @@ namespace System.Windows.Forms
                {
                        base.OnSelectedIndexChanged (e);
 
-                       if (SelectedIndexChanged != null)
-                               SelectedIndexChanged (this, e);
+                       EventHandler eh = (EventHandler)(Events [SelectedIndexChangedEvent]);
+                       if (eh != null)
+                               eh (this, e);
                }
 
                protected virtual void OnSelectedItemChanged (EventArgs e)
@@ -801,8 +964,9 @@ namespace System.Windows.Forms
 
                protected virtual void OnSelectionChangeCommitted (EventArgs e)
                {
-                       if (SelectionChangeCommitted != null)
-                               SelectionChangeCommitted (this, e);
+                       EventHandler eh = (EventHandler)(Events [SelectionChangeCommittedEvent]);
+                       if (eh != null)
+                               eh (this, e);
                }
 
                protected override void RefreshItem (int index)
@@ -814,6 +978,41 @@ namespace System.Windows.Forms
                                item_heights.Remove (Items [index]);
                }
 
+#if NET_2_0
+               protected override bool ProcessKeyEventArgs (ref Message m)
+               {
+                       return base.ProcessKeyEventArgs (ref m);
+               }
+
+               [EditorBrowsable (EditorBrowsableState.Advanced)]
+               protected override void OnKeyDown (KeyEventArgs e)
+               {
+                       base.OnKeyDown (e);
+               }
+
+               [EditorBrowsable (EditorBrowsableState.Advanced)]
+               protected override void OnValidating (CancelEventArgs e)
+               {
+                       base.OnValidating (e);
+               }
+
+               [EditorBrowsable (EditorBrowsableState.Advanced)]
+               protected override void OnTextChanged (EventArgs e)
+               {
+                       base.OnTextChanged (e);
+               }
+
+               protected override void OnMouseLeave (EventArgs e)
+               {
+                       base.OnMouseLeave (e);
+               }
+               
+               protected override void OnMouseEnter (EventArgs e)
+               {
+                       base.OnMouseEnter (e);
+               }
+#endif
+
                public void Select (int start, int length)
                {
                        if (start < 0)
@@ -824,7 +1023,7 @@ namespace System.Windows.Forms
                                
                        if (dropdown_style == ComboBoxStyle.DropDownList)
                                return;
-                               
+
                        textbox_ctrl.Select (start, length);
                }
 
@@ -832,8 +1031,11 @@ namespace System.Windows.Forms
                {
                        if (dropdown_style == ComboBoxStyle.DropDownList)
                                return;
-                               
-                       textbox_ctrl.SelectAll ();
+
+                       if (textbox_ctrl != null) {
+                               textbox_ctrl.ShowSelection = true;
+                               textbox_ctrl.SelectAll ();
+                       }
                }               
 
                protected override void SetBoundsCore (int x, int y, int width, int height, BoundsSpecified specified)
@@ -868,7 +1070,13 @@ namespace System.Windows.Forms
 
                protected override void SetItemsCore (IList value)
                {
-                       Items.AddRange (value);
+                       BeginUpdate ();
+                       try {
+                               Items.Clear ();
+                               Items.AddRange (value);
+                       } finally {
+                               EndUpdate ();
+                       }
                }
 
                public override string ToString ()
@@ -879,6 +1087,16 @@ namespace System.Windows.Forms
                protected override void WndProc (ref Message m)
                {
                        switch ((Msg) m.Msg) {
+                       case Msg.WM_KEYUP:
+                       case Msg.WM_KEYDOWN:
+                               Keys keys = (Keys) m.WParam.ToInt32 ();
+                               if (keys == Keys.Up || keys == Keys.Down)
+                                       break;
+                               goto case Msg.WM_CHAR;
+                       case Msg.WM_CHAR:
+                               if (textbox_ctrl != null)
+                                       XplatUI.SendMessage (textbox_ctrl.Handle, (Msg) m.Msg, m.WParam, m.LParam);
+                               break;
                        case Msg.WM_MOUSE_LEAVE:
                                Point location = PointToClient (Control.MousePosition);
                                if (ClientRectangle.Contains (location))
@@ -893,43 +1111,20 @@ namespace System.Windows.Forms
                #endregion Public Methods
 
                #region Private Methods
+#if NET_2_0
+               void OnAutoCompleteCustomSourceChanged(object sender, CollectionChangeEventArgs e) {
+                       if(auto_complete_source == AutoCompleteSource.CustomSource) {
+                               //FIXME: handle add, remove and refresh events in AutoComplete algorithm.
+                       }
+               }
+#endif
 
                internal override bool InternalCapture {
                        get { return Capture; }
                        set {}
                }
-
-               private void textbox_ctrl_KeyPress(object sender, KeyPressEventArgs e) 
-               {
-                       OnKeyPress (e);
-               }
-               
-               private void textbox_ctrl_GotFocus(object sender, EventArgs e )
-               {
-                       OnGotFocus(e);
-               }
-               
-               private void textbox_ctrl_LostFocus(object sender, EventArgs e )
-               {
-                       OnLostFocus(e);
-               }
-               
-               private void textbox_ctrl_MouseDown(object sender, MouseEventArgs e )
-               {
-                       OnMouseDown(e);
-               }
-               
-               private void textbox_ctrl_MouseMove(object sender, MouseEventArgs e )
-               {
-                       OnMouseMove(e);
-               }
                
-               private void textbox_ctrl_MouseUp(object sender, MouseEventArgs e )
-               {
-                       OnMouseUp(e);
-               }
-               
-               void Layout ()
+               void LayoutComboBox ()
                {                       
                        int border = ThemeEngine.Current.Border3DSize.Width;
 
@@ -975,8 +1170,7 @@ namespace System.Windows.Forms
                private void CreateComboListBox ()
                {                       
                        listbox_ctrl = new ComboListBox (this);                 
-                       if (selected_item != null)
-                               listbox_ctrl.HighlightedItem = selected_item;
+                       listbox_ctrl.HighlightedIndex = SelectedIndex;
                }
                
                internal void Draw (Rectangle clip, Graphics dc)
@@ -1000,7 +1194,7 @@ namespace System.Windows.Forms
                                item_rect.Width -= (button_area.Width + 2 * border);                            
                                item_rect.Height -= 2 * border;                         
                                                                
-                               if (has_focus) {
+                               if (Focused) {
                                        state = DrawItemState.Selected;
                                        state |= DrawItemState.Focus;
                                }
@@ -1035,8 +1229,6 @@ namespace System.Windows.Forms
                        button_state = ButtonState.Pushed;                              
                        if (dropdown_style == ComboBoxStyle.DropDownList)
                                Invalidate (text_area);
-
-                       OnDropDown (EventArgs.Empty);
                }
                
                internal void DropDownListBoxFinished ()
@@ -1064,6 +1256,21 @@ namespace System.Windows.Forms
                        return -1;
                }
 
+               internal int FindStringCaseInsensitive (string search, int start_index)
+               {
+                       if (search.Length == 0) {
+                               return -1;
+                       }
+
+                       for (int i = 0; i < Items.Count; i++) {
+                               int index = (i + start_index) % Items.Count;
+                               if (String.Compare (GetItemText (Items [index]), 0, search, 0, search.Length, true) == 0)
+                                       return index;
+                       }
+
+                       return -1;
+               }
+
                private void OnKeyDownCB(object sender, KeyEventArgs e)
                {
                        if (Items.Count == 0)
@@ -1075,7 +1282,7 @@ namespace System.Windows.Forms
                                        SelectedIndex = Math.Max(SelectedIndex-1, 0);
                                        break;                          
        
-                               case Keys.Down:                 
+                               case Keys.Down:
                                        SelectedIndex = Math.Min(SelectedIndex+1, Items.Count-1);
                                        break;
                                
@@ -1095,7 +1302,7 @@ namespace System.Windows.Forms
                }
                
                void OnMouseDownCB (object sender, MouseEventArgs e)
-               {                       
+               {
                        Rectangle area;
                        if (DropDownStyle == ComboBoxStyle.DropDownList)
                                area = ClientRectangle;
@@ -1131,6 +1338,25 @@ namespace System.Windows.Forms
                                listbox_ctrl.Capture = true;
                }
 
+               private void OnMouseWheelCB (object sender, MouseEventArgs me)
+               {
+                       if (Items.Count == 0)
+                               return;
+
+                       if (listbox_ctrl != null && listbox_ctrl.Visible) {
+                               int lines = me.Delta / 120 * SystemInformation.MouseWheelScrollLines;
+                               listbox_ctrl.Scroll (-lines);
+                       } else {
+                               int lines = me.Delta / 120;
+                               int index = SelectedIndex - lines;
+                               if (index < 0)
+                                       index = 0;
+                               else if (index >= Items.Count)
+                                       index = Items.Count - 1;
+                               SelectedIndex = index;
+                       }
+               }
+
                internal override void OnPaintInternal (PaintEventArgs pevent)
                {
                        if (suspend_ctrlupdate)
@@ -1139,33 +1365,51 @@ namespace System.Windows.Forms
                        Draw (ClientRectangle, pevent.Graphics);                        
                }
                
+               private void OnTextBoxClick (object sender, EventArgs e)
+               {
+                       OnClick (e);
+               }
+
                private void OnTextChangedEdit (object sender, EventArgs e)
                {
                        if (process_textchanged_event == false)
                                return; 
                                
+                       OnTextChanged (EventArgs.Empty);
+
                        int item = FindStringCaseInsensitive (textbox_ctrl.Text);
                        
                        if (item == -1)
                                return;
 
+                       // TODO:  THIS IS BROKEN-ISH
+                       // I don't think we should hilight, and setting the top item does weirdness
+                       // when there is no scrollbar
+                       
                        if (listbox_ctrl != null) {
                                listbox_ctrl.SetTopItem (item);
-                               listbox_ctrl.HighlightedItem = Items [item];
+                               listbox_ctrl.HighlightedIndex = item;
                        }
+
+                       base.Text = textbox_ctrl.Text;
                }
                
                internal void SetControlText (string s)
                {               
-                       process_textchanged_event = false; 
+                       process_textchanged_event = false;
                        textbox_ctrl.Text = s;
                        process_textchanged_event = true;
                }
                
-               void UpdateBounds ()
+               void UpdateComboBoxBounds ()
                {
-                       if (requested_height != -1)
-                               SetBoundsCore (0, 0, 0, requested_height, BoundsSpecified.Height);
+                       if (requested_height == -1)
+                               return;
+
+                       // Save the requested height since set bounds can destroy it
+                       int save_height = requested_height;
+                       SetBounds (0, 0, 0, requested_height, BoundsSpecified.Height);
+                       requested_height = save_height;
                }
 
                private void UpdatedItems ()
@@ -1212,8 +1456,18 @@ namespace System.Windows.Forms
                                set {
                                        if (index < 0 || index >= Count)
                                                throw new ArgumentOutOfRangeException ("Index of out range");
+                                       if (value == null)
+                                               throw new ArgumentNullException ("value");
 
                                        object_items[index] = value;
+                                       if (owner.listbox_ctrl != null)
+                                               owner.listbox_ctrl.InvalidateItem (index);
+                                       if (index == owner.SelectedIndex) {
+                                               if (owner.textbox_ctrl == null)
+                                                       owner.Refresh ();
+                                               else
+                                                       owner.textbox_ctrl.SelectedText = value.ToString ();
+                                       }
                                }
                        }
 
@@ -1231,16 +1485,6 @@ namespace System.Windows.Forms
 
                        #endregion Public Properties
                        
-                       #region Private Properties                      
-                       internal ArrayList ObjectItems {
-                               get { return object_items;}
-                               set {
-                                       object_items = value;
-                               }
-                       }
-                       
-                       #endregion Private Properties
-
                        #region Public Methods
                        public int Add (object item)
                        {
@@ -1253,6 +1497,9 @@ namespace System.Windows.Forms
 
                        public void AddRange (object[] items)
                        {
+                               if (items == null)
+                                       throw new ArgumentNullException ("items");
+
                                foreach (object mi in items)
                                        AddItem (mi);
                                        
@@ -1261,7 +1508,7 @@ namespace System.Windows.Forms
 
                        public void Clear ()
                        {
-                               owner.selected_item = null;
+                               owner.selected_index = -1;
                                object_items.Clear ();
                                owner.UpdatedItems ();
                                owner.Refresh ();
@@ -1269,6 +1516,9 @@ namespace System.Windows.Forms
                        
                        public bool Contains (object obj)
                        {
+                               if (obj == null)
+                                       throw new ArgumentNullException ("obj");
+
                                return object_items.Contains (obj);
                        }
 
@@ -1294,6 +1544,9 @@ namespace System.Windows.Forms
 
                        public int IndexOf (object value)
                        {
+                               if (value == null)
+                                       throw new ArgumentNullException ("value");
+
                                return object_items.IndexOf (value);
                        }
 
@@ -1301,21 +1554,28 @@ 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);
+                               if (owner.Sorted)
+                                       AddItem (item);
+                               else
+                                       object_items.Insert (index, item);
                                                                                                
                                owner.EndUpdate ();     // Calls UpdatedItems
                        }
 
                        public void Remove (object value)
                        {                               
+                               if (value == null)
+                                       return;
+
                                if (IndexOf (value) == owner.SelectedIndex)
-                                       owner.SelectedItem = null;
+                                       owner.SelectedIndex = -1;
                                
                                RemoveAt (IndexOf (value));                             
-                               
                        }
 
                        public void RemoveAt (int index)
@@ -1324,7 +1584,7 @@ namespace System.Windows.Forms
                                        throw new ArgumentOutOfRangeException ("Index of out range");
                                        
                                if (index == owner.SelectedIndex)
-                                       owner.SelectedItem = null;
+                                       owner.SelectedIndex = -1;
 
                                object_items.RemoveAt (index);
                                owner.UpdatedItems ();
@@ -1334,9 +1594,21 @@ namespace System.Windows.Forms
                        #region Private Methods
                        private int AddItem (object item)
                        {
-                               int cnt = object_items.Count;
+                               if (item == null)
+                                       throw new ArgumentNullException ("item");
+
+                               if (owner.Sorted) {
+                                       int index = 0;
+                                       foreach (object o in object_items) {
+                                               if (String.Compare (item.ToString (), o.ToString ()) < 0) {
+                                                       object_items.Insert (index, item);
+                                                       return index;
+                                               }
+                                               index++;
+                                       }
+                               }
                                object_items.Add (item);
-                               return cnt;
+                               return object_items.Count - 1;
                        }
                        
                        internal void AddRange (IList items)
@@ -1347,9 +1619,48 @@ namespace System.Windows.Forms
                                owner.UpdatedItems ();
                        }
 
+                       internal void Sort ()
+                       {
+                               object_items.Sort ();
+                       }
+
                        #endregion Private Methods
                }
 
+               internal class ComboTextBox : TextBox {
+
+                       private ComboBox owner;
+
+                       public ComboTextBox (ComboBox owner)
+                       {
+                               this.owner = owner;
+                               ShowSelection = false;
+                       }
+
+                       internal void SetSelectable (bool selectable)
+                       {
+                               SetStyle (ControlStyles.Selectable, selectable);
+                       }
+
+                       internal void ActivateCaret (bool active)
+                       {
+                               if (active)
+                                       document.CaretHasFocus ();
+                               else
+                                       document.CaretLostFocus ();
+                       }
+
+                       internal override void OnGotFocusInternal (EventArgs e)
+                       {
+                               owner.Select (false, true);
+                       }
+
+                       internal override void OnLostFocusInternal (EventArgs e)
+                       {
+                               owner.Select (false, true);
+                       }                       
+               }
+
                internal class ComboListBox : Control
                {
                        private ComboBox owner;                 
@@ -1380,34 +1691,31 @@ namespace System.Windows.Forms
                                        set { }
                                }
 
-                               public bool FireMouseDown (MouseEventArgs e) 
+                               public void FireMouseDown (MouseEventArgs e) 
                                {
-                                       if (Visible) {
-                                               e = TranslateEvent (e);
-                                               if (ClientRectangle.Contains (e.X, e.Y)) {
-                                                       OnMouseDown (e);
-                                                       return true;
-                                               }
-                                       }
-                                       return false;
+                                       if (!Visible) 
+                                               return;
+
+                                       e = TranslateEvent (e);
+                                       OnMouseDown (e);
                                }       
                                
                                public void FireMouseUp (MouseEventArgs e) 
                                {
-                                       if (Visible) {
-                                               e = TranslateEvent (e);
-                                               if (ClientRectangle.Contains (e.X, e.Y))
-                                                       OnMouseUp (e);
-                                       }
+                                       if (!Visible)
+                                               return;
+
+                                       e = TranslateEvent (e);
+                                       OnMouseUp (e);
                                }
                                
                                public void FireMouseMove (MouseEventArgs e) 
                                {
-                                       if (Visible) {
-                                               e = TranslateEvent (e);
-                                               if (ClientRectangle.Contains (e.X, e.Y))
-                                                       OnMouseMove (e);
-                                       }
+                                       if (!Visible)
+                                               return;
+
+                                       e = TranslateEvent (e);
+                                       OnMouseMove (e);
                                }                       
                                
                                MouseEventArgs TranslateEvent (MouseEventArgs e)
@@ -1424,13 +1732,14 @@ namespace System.Windows.Forms
                                last_item = 0;
                                page_size = 0;
 
-                               MouseDown += new MouseEventHandler (OnMouseDownPUW);
-                               MouseUp += new MouseEventHandler (OnMouseUpPUW);
-                               MouseMove += new MouseEventHandler (OnMouseMovePUW);                            
-                               KeyDown += new KeyEventHandler (OnKeyDownPUW);
+                               MouseWheel += new MouseEventHandler (OnMouseWheelCLB);
+
                                SetStyle (ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true);
                                SetStyle (ControlStyles.ResizeRedraw | ControlStyles.Opaque, true);
 
+                               this.is_visible = false;
+                               Hwnd.ObjectFromHandle (this.Handle).no_activate = true;
+
                                if (owner.DropDownStyle == ComboBoxStyle.Simple)
                                        InternalBorderStyle = BorderStyle.Fixed3D;
                                else
@@ -1451,6 +1760,11 @@ namespace System.Windows.Forms
                                }
                        }
 
+                       protected override void Select (bool directed, bool forward)
+                       {
+                               // Do nothing, we never want to be selected
+                       }
+
                        internal override bool InternalCapture {
                                get {
                                        return Capture;
@@ -1460,14 +1774,6 @@ namespace System.Windows.Forms
                                }
                        }
 
-                       protected override void OnLostFocus(EventArgs e) {
-                               if (Capture) {
-                                       HideWindow();
-                               }
-                               base.OnLostFocus (e);
-                       }
-
-
                        int BorderWidth {
                                get {
                                        switch (border_style) {
@@ -1507,6 +1813,8 @@ namespace System.Windows.Forms
                                        }
                                }
                                
+                               page_size = height / owner.ItemHeight;
+
                                if (owner.Items.Count <= owner.MaxDropDownItems) {                                      
                                        if (vscrollbar_ctrl != null)
                                                vscrollbar_ctrl.Visible = false;
@@ -1526,7 +1834,11 @@ namespace System.Windows.Forms
                                                        
                                        vscrollbar_ctrl.Location = new Point (width - vscrollbar_ctrl.Width - BorderWidth - 1, 0);
 
-                                       vscrollbar_ctrl.Maximum = owner.Items.Count - (owner.DropDownStyle == ComboBoxStyle.Simple ? page_size : owner.maxdrop_items);
+                                       vscrollbar_ctrl.Maximum = owner.Items.Count - 2;
+                                       int large = (owner.DropDownStyle == ComboBoxStyle.Simple ? page_size : owner.maxdrop_items) - 1;
+                                       if (large < 0)
+                                               large = 0;
+                                       vscrollbar_ctrl.LargeChange = large;
                                        show_scrollbar = vscrollbar_ctrl.Visible = true;
 
                                        int hli = HighlightedIndex;
@@ -1545,7 +1857,6 @@ namespace System.Windows.Forms
                                        textarea_drawable.Width -= vscrollbar_ctrl.Width;
 
                                last_item = LastVisibleItem ();
-                               page_size = textarea_drawable.Height / owner.ItemHeight;
                        }                       
 
                        private void Draw (Rectangle clip, Graphics dc)
@@ -1576,37 +1887,24 @@ namespace System.Windows.Forms
                                }
                        }
 
+                       int highlighted_index = -1;
+
                        public int HighlightedIndex {
-                               get { return owner.Items.IndexOf (highlighted_item); }
+                               get { return highlighted_index; }
                                set { 
-                                       object item = null;
-                                       if (value != -1)
-                                               item = owner.Items [value];
-                                       HighlightedItem = item; 
-                               }
-                       }
-
-                       object highlighted_item = null;
-
-                       public object HighlightedItem {
-                               get { return highlighted_item; }
-                               set {
-                                       if (highlighted_item == value)
+                                       if (highlighted_index == value)
                                                return;
-                               
-                                       int index = owner.Items.IndexOf (highlighted_item);
-                                       if (index != -1)
-                                               Invalidate (GetItemDisplayRectangle (index, top_item));
-                                       highlighted_item = value;
-                                       index = owner.Items.IndexOf (highlighted_item);
-                                       if (index != -1)
-                                               Invalidate (GetItemDisplayRectangle (index, top_item));
+
+                                       if (highlighted_index != -1 && highlighted_index < this.owner.Items.Count)
+                                               Invalidate (GetItemDisplayRectangle (highlighted_index, top_item));
+                                       highlighted_index = value;
+                                       if (highlighted_index != -1)
+                                               Invalidate (GetItemDisplayRectangle (highlighted_index, top_item));
                                }
                        }
-                       
+
                        private Rectangle GetItemDisplayRectangle (int index, int top_index)
                        {
-                               Console.WriteLine (index + " " + top_index);
                                if (index < 0 || index >= owner.Items.Count)
                                        throw new  ArgumentOutOfRangeException ("GetItemRectangle index out of range.");
 
@@ -1645,10 +1943,11 @@ namespace System.Windows.Forms
 
                                return -1;
                        }
-                       
-                       protected override bool IsInputKey (Keys keyData)
+
+                       public void InvalidateItem (int index)
                        {
-                               return owner.IsInputKey (keyData);
+                               if (Visible)
+                                       Invalidate (GetItemDisplayRectangle (index, top_item));
                        }
 
                        private int LastVisibleItem ()
@@ -1665,153 +1964,72 @@ namespace System.Windows.Forms
                                }
                                return i - 1;
                        }
-                       
-                       private void NavigateItemVisually (ItemNavigation navigation)
-                       {
-                               int item = -1;
-                               
-                               switch (navigation) {
-                               case ItemNavigation.Next:
-                                       if (HighlightedIndex + 1 < owner.Items.Count) {
-                                               if (HighlightedIndex + 1 > last_item) {
-                                                       top_item++;
-                                                       vscrollbar_ctrl.Value = top_item;
-                                               }
-                                               item = HighlightedIndex + 1;
-                                       }
-                                       break;
-                               
-                               case ItemNavigation.Previous:
-                                       if (HighlightedIndex > 0) {                                             
-                                               if (HighlightedIndex - 1 < top_item) {                                                  
-                                                       top_item--;
-                                                       vscrollbar_ctrl.Value = top_item;                                                       
-                                               }
-                                               item = HighlightedIndex - 1;
-                                       }                                       
-                                       break;
-                               
-                               case ItemNavigation.NextPage:
-                                       if (HighlightedIndex + page_size - 1 >= owner.Items.Count) {
-                                               top_item = owner.Items.Count - page_size;
-                                               vscrollbar_ctrl.Value = top_item;
-                                               item = owner.Items.Count - 1;
-                                       } else {
-                                               if (HighlightedIndex + page_size - 1  > last_item) {
-                                                       top_item = HighlightedIndex;
-                                                       vscrollbar_ctrl.Value = HighlightedIndex;
-                                               }
-                                               item = HighlightedIndex + page_size - 1;
-                                       }                                       
-                                       break;
-                               
-                               case ItemNavigation.PreviousPage:
-                                       if (HighlightedIndex - page_size - 1 <= 0) {
-                                               top_item = 0;
-                                               vscrollbar_ctrl.Value = top_item;
-                                               item = 0;                       
-                                       } else {
-                                               if (HighlightedIndex - page_size - 1  < top_item) {
-                                                       top_item = HighlightedIndex - page_size - 1;
-                                                       vscrollbar_ctrl.Value = top_item;
-                                               }
-                                               item = HighlightedIndex - page_size - 1;
-                                       }
-                                       break;
-                                       
-                               default:
-                                       break;
-                               }       
-                               
-                               if (item != -1) {
-                                       HighlightedIndex = item;
-                                       owner.OnSelectionChangeCommitted (new EventArgs ());
-                                       if (owner.DropDownStyle == ComboBoxStyle.Simple)
-                                               owner.SetControlText (owner.GetItemText (owner.Items[item]));
-                               }
-                       }
 
-                       private void OnKeyDownPUW (object sender, KeyEventArgs e)                       
-                       {                               
-                               switch (e.KeyCode) {                    
-                               case Keys.Up:
-                                       NavigateItemVisually (ItemNavigation.Previous);
-                                       break;                          
-       
-                               case Keys.Down:                         
-                                       NavigateItemVisually (ItemNavigation.Next);
-                                       break;
-                               
-                               case Keys.PageUp:
-                                       NavigateItemVisually (ItemNavigation.PreviousPage);
-                                       break;                          
-       
-                               case Keys.PageDown:                             
-                                       NavigateItemVisually (ItemNavigation.NextPage);
-                                       break;
-                               
-                               default:
-                                       break;
-                               }
-                       }
-                       
                        public void SetTopItem (int item)
                        {
                                if (top_item == item)
                                        return;
                                top_item = item;
                                UpdateLastVisibleItem ();
-                               Refresh ();
+                               Invalidate ();
                        }                       
-                       
-                       private void OnMouseDownPUW (object sender, MouseEventArgs e)
-                       {
-                               int index = IndexFromPointDisplayRectangle (e.X, e.Y);
 
-                               if (index == -1) {                                      
-                                       if (vscrollbar_ctrl == null || !vscrollbar_ctrl.FireMouseDown (e))
-                                               HideWindow ();
-                               } else {
-                                       owner.OnSelectionChangeCommitted (new EventArgs ());
-                                       owner.SelectedIndex = index;
-                                       HighlightedIndex = index;
-                                       HideWindow ();
-                               }
-                               
-                               if (owner.DropDownStyle == ComboBoxStyle.Simple) {
-                                       owner.OnMouseDown (e);
-                                       owner.textbox_ctrl.Focus ();
+                       bool scrollbar_grabbed = false;
+
+                       bool InScrollBar {
+                               get {
+                                       if (vscrollbar_ctrl == null || !vscrollbar_ctrl.is_visible)
+                                               return false;
+
+                                       return vscrollbar_ctrl.Bounds.Contains (PointToClient (Control.MousePosition));
                                }
                        }
 
-                       private void OnMouseMovePUW (object sender, MouseEventArgs e)
+                       protected override void OnMouseDown (MouseEventArgs e)
                        {
-                               if (owner.DropDownStyle == ComboBoxStyle.Simple) {
-                                       owner.OnMouseMove (e);
+                               if (InScrollBar) {
+                                       vscrollbar_ctrl.FireMouseDown (e);
+                                       scrollbar_grabbed = true;
+                               }
+                       }
+
+                       protected override void OnMouseMove (MouseEventArgs e)
+                       {                                               
+                               if (owner.DropDownStyle == ComboBoxStyle.Simple)
+                                       return;
+
+                               if (scrollbar_grabbed || (!Capture && InScrollBar)) {
+                                       vscrollbar_ctrl.FireMouseMove (e);
                                        return;
                                }
-                                               
+
                                Point pt = PointToClient (Control.MousePosition);
                                int index = IndexFromPointDisplayRectangle (pt.X, pt.Y);
 
-                               if (index != -1) {
+                               if (index != -1)
                                        HighlightedIndex = index;
-                                       return;
-                               }
-                               
-                               if (vscrollbar_ctrl != null)
-                                       vscrollbar_ctrl.FireMouseMove (e);
                        }
                        
-                       private void OnMouseUpPUW (object sender, MouseEventArgs e)
+                       protected override void OnMouseUp (MouseEventArgs e)
                        {
-                               if (owner.DropDownStyle == ComboBoxStyle.Simple) {
-                                       owner.OnMouseUp (e);
-                                       return;                                 
+                               int index = IndexFromPointDisplayRectangle (e.X, e.Y);
+
+                               if (scrollbar_grabbed) {
+                                       vscrollbar_ctrl.FireMouseUp (e);
+                                       scrollbar_grabbed = false;
+                                       if (index != -1)
+                                               HighlightedIndex = index;
+                                       return;
                                }
 
-                               if (vscrollbar_ctrl != null)
-                                       vscrollbar_ctrl.FireMouseUp (e);
+                               if (index == -1) {                                      
+                                       HideWindow ();
+                                       return;
+                               }
+
+                               owner.SelectedIndex = index;
+                               owner.OnSelectionChangeCommitted (new EventArgs ());
+                               HideWindow ();
                        }
 
                        internal override void OnPaintInternal (PaintEventArgs pevent)
@@ -1823,7 +2041,7 @@ namespace System.Windows.Forms
                        {
                                if (owner.DropDownStyle == ComboBoxStyle.Simple && owner.Items.Count == 0)
                                        return false;
-                                       
+
                                HighlightedIndex = owner.SelectedIndex;
 
                                CalcListBoxArea ();                             
@@ -1839,6 +2057,30 @@ namespace System.Windows.Forms
                                last_item = LastVisibleItem ();
                        }
 
+                       public void Scroll (int delta)
+                       {
+                               if (delta == 0 || vscrollbar_ctrl == null || !vscrollbar_ctrl.Visible)
+                                       return;
+
+                               int max = owner.Items.Count - page_size;
+
+                               int val = vscrollbar_ctrl.Value + delta;
+                               if (val > max)
+                                       val = max;
+                               else if (val < vscrollbar_ctrl.Minimum)
+                                       val = vscrollbar_ctrl.Minimum;
+                               vscrollbar_ctrl.Value = val;
+                       }
+
+                       private void OnMouseWheelCLB (object sender, MouseEventArgs me)
+                       {
+                               if (owner.Items.Count == 0)
+                                       return;
+
+                               int lines = me.Delta / 120 * SystemInformation.MouseWheelScrollLines;
+                               Scroll (-lines);
+                       }
+
                        // Value Changed
                        private void VerticalScrollEvent (object sender, EventArgs e)
                        {                               
@@ -1847,11 +2089,21 @@ namespace System.Windows.Forms
 
                                top_item =  vscrollbar_ctrl.Value;
                                UpdateLastVisibleItem ();
-                               Refresh ();
+                               Invalidate ();
                        }                       
                        
+                       protected override void WndProc(ref Message m) {
+                               if (m.Msg == (int)Msg.WM_SETFOCUS) {
+                                       if (m.WParam != IntPtr.Zero) {
+                                               XplatUI.SetFocus(m.WParam);
+                                       }
+                               }
+                               base.WndProc (ref m);
+                       }
+
                        #endregion Private Methods
                }
        }
 }
 
+