* ComboBox.cs: page_size as well as vscrollbar.LargeChange should be 1
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / ComboBox.cs
index 325a48baf4698d310138cdc66e239a4ad00a3ddb..36a07edaa16737eb513e20cee7714d519d11d4fe 100644 (file)
 //     Daniel Nauck    (dna(at)mono-project(dot)de)
 
 using System;
-using System.Drawing;
 using System.Collections;
 using System.ComponentModel;
-using System.Reflection;
 using System.ComponentModel.Design;
 using System.ComponentModel.Design.Serialization;
+using System.Drawing;
+using System.Globalization;
+using System.Reflection;
 using System.Runtime.InteropServices;
 
-
 namespace System.Windows.Forms
 {
        [DefaultProperty("Items")]
@@ -47,29 +47,30 @@ namespace System.Windows.Forms
        public class ComboBox : ListControl
        {
                private DrawMode draw_mode = DrawMode.Normal;
-               private ComboBoxStyle dropdown_style = (ComboBoxStyle)(-1);
-               private int dropdown_width = -1;                
+               private ComboBoxStyle dropdown_style;
+               private int dropdown_width = -1;
                private int selected_index = -1;
-               internal ObjectCollection items = null;
+               private ObjectCollection items;
                private bool suspend_ctrlupdate;
-               private int maxdrop_items = 8;                  
+               private int maxdrop_items = 8;
                private bool integral_height = true;
                private bool sorted;
                private int max_length;
-               private ComboListBox listbox_ctrl;              
+               private ComboListBox listbox_ctrl;
                private ComboTextBox textbox_ctrl;
                private bool process_textchanged_event = true;
-               private bool item_height_specified = false;
+               private bool item_height_specified;
                private int item_height;
                private int requested_height = -1;
                private Hashtable item_heights;
-               private bool show_dropdown_button = false;
+               private bool show_dropdown_button;
                private ButtonState button_state = ButtonState.Normal;
                private bool dropped_down;
                private Rectangle text_area;
                private Rectangle button_area;
                private Rectangle listbox_area;
                private const int button_width = 16;
+               bool drop_down_button_entered;
 #if NET_2_0
                private AutoCompleteStringCollection auto_complete_custom_source = null;
                private AutoCompleteMode auto_complete_mode = AutoCompleteMode.None;
@@ -98,7 +99,7 @@ namespace System.Windows.Forms
                        items = new ObjectCollection (this);
                        DropDownStyle = ComboBoxStyle.DropDown;
                        item_height = FontHeight + 2;
-                       BackColor = ThemeEngine.Current.ColorWindow;
+                       background_color = ThemeEngine.Current.ColorWindow;
                        border_style = BorderStyle.None;
 
 #if NET_2_0
@@ -110,7 +111,8 @@ namespace System.Windows.Forms
                        MouseDown += new MouseEventHandler (OnMouseDownCB);
                        MouseUp += new MouseEventHandler (OnMouseUpCB);
                        MouseMove += new MouseEventHandler (OnMouseMoveCB);
-                       MouseWheel += new MouseEventHandler (OnMouseWheelCB);                           
+                       MouseWheel += new MouseEventHandler (OnMouseWheelCB);
+                       MouseLeave += new EventHandler (OnMouseLeave);
                        KeyDown +=new KeyEventHandler(OnKeyDownCB);
                }
 
@@ -285,8 +287,7 @@ namespace System.Windows.Forms
                        set {
                                if (base.BackColor == value)
                                        return;
-
-                               base.BackColor = value;
+                               base.BackColor = value;
                                Refresh ();
                        }
                }
@@ -298,8 +299,7 @@ namespace System.Windows.Forms
                        set {
                                if (base.BackgroundImage == value)
                                        return;
-
-                               base.BackgroundImage = value;
+                               base.BackgroundImage = value;
                                Refresh ();
                        }
                }
@@ -326,6 +326,7 @@ namespace System.Windows.Forms
                        set { base.DataSource = value; }
                }
 #endif
+
                protected override Size DefaultSize {
                        get { return new Size (121, 21); }
                }
@@ -334,8 +335,7 @@ namespace System.Windows.Forms
                [DefaultValue (DrawMode.Normal)]
                public DrawMode DrawMode {
                        get { return draw_mode; }
-
-                       set {
+                       set {
                                if (!Enum.IsDefined (typeof (DrawMode), value))
                                        throw new InvalidEnumArgumentException (string.Format("Enum argument value '{0}' is not valid for DrawMode", value));
 
@@ -344,11 +344,11 @@ namespace System.Windows.Forms
 
                                if (draw_mode == DrawMode.OwnerDrawVariable)
                                        item_heights = null;
-                               draw_mode = value;
+                               draw_mode = value;
                                if (draw_mode == DrawMode.OwnerDrawVariable)
                                        item_heights = new Hashtable ();
                                Refresh ();
-                       }
+                       }
                }
 
 #if NET_2_0
@@ -373,46 +373,47 @@ namespace System.Windows.Forms
                [RefreshProperties(RefreshProperties.Repaint)]
                public ComboBoxStyle DropDownStyle {
                        get { return dropdown_style; }
-
-                       set {
-               
+                       set {
                                if (!Enum.IsDefined (typeof (ComboBoxStyle), value))
                                        throw new InvalidEnumArgumentException (string.Format("Enum argument value '{0}' is not valid for ComboBoxStyle", value));
 
                                if (dropdown_style == value)
-                                       return;                                 
+                                       return;
 
                                SuspendLayout ();
 
                                if (dropdown_style == ComboBoxStyle.Simple) {
-                                       if (listbox_ctrl != null) {                                             
+                                       if (listbox_ctrl != null) {
                                                Controls.RemoveImplicit (listbox_ctrl);
-                                               listbox_ctrl.Dispose ();                                                
+                                               listbox_ctrl.Dispose ();
                                                listbox_ctrl = null;
                                        }
                                }
 
-                               dropdown_style = value;                                 
+                               dropdown_style = value;
                                
                                if (dropdown_style == ComboBoxStyle.DropDownList && textbox_ctrl != null) {
                                        Controls.RemoveImplicit (textbox_ctrl);
-                                       textbox_ctrl.Dispose ();                                                
-                                       textbox_ctrl = null;                                            
-                               }                               
+                                       textbox_ctrl.Dispose ();
+                                       textbox_ctrl = null;
+                               }
 
                                if (dropdown_style == ComboBoxStyle.Simple) {
-                                       show_dropdown_button = false;                                   
+                                       show_dropdown_button = false;
                                        
                                        CreateComboListBox ();
-
-                                       if (IsHandleCreated) {
-                                               Controls.AddImplicit (listbox_ctrl);
-                                               listbox_ctrl.Visible = true;
-                                       }
+                                       Controls.AddImplicit (listbox_ctrl);
+                                       listbox_ctrl.Visible = true;
+
+                                       // This should give us a 150 default height
+                                       // for Simple mode if size hasn't been set
+                                       // (DefaultSize doesn't work for us in this case)
+                                       if (requested_height == -1)
+                                               requested_height = 150;
                                } else {
                                        show_dropdown_button = true;
                                        button_state = ButtonState.Normal;
-                               }                               
+                               }
        
                                if (dropdown_style != ComboBoxStyle.DropDownList && textbox_ctrl == null) {
                                        textbox_ctrl = new ComboTextBox (this);
@@ -421,20 +422,21 @@ namespace System.Windows.Forms
                                                textbox_ctrl.Text = GetItemText (selected_item);
                                        textbox_ctrl.BorderStyle = BorderStyle.None;
                                        textbox_ctrl.TextChanged += new EventHandler (OnTextChangedEdit);
+                                       textbox_ctrl.KeyPress += new KeyPressEventHandler (OnTextKeyPress);
                                        textbox_ctrl.Click += new EventHandler (OnTextBoxClick);
+                                       textbox_ctrl.ContextMenu = ContextMenu;
 
-                                       if (IsHandleCreated == true) {
+                                       if (IsHandleCreated == true)
                                                Controls.AddImplicit (textbox_ctrl);
-                                       }
                                }
                                
                                ResumeLayout ();
                                OnDropDownStyleChanged (EventArgs.Empty);
-                               
+                               
                                LayoutComboBox ();
                                UpdateComboBoxBounds ();
                                Refresh ();
-                       }
+                       }
                }
 
                public int DropDownWidth {
@@ -478,7 +480,7 @@ namespace System.Windows.Forms
                                else
                                        listbox_ctrl.Hide ();
                        }
-               }               
+               }
 
 #if NET_2_0
                [DefaultValue (FlatStyle.Standard)]
@@ -494,8 +496,6 @@ namespace System.Windows.Forms
                                Invalidate ();
                        }
                }
-
 #endif
 
                public override bool Focused {
@@ -507,23 +507,21 @@ namespace System.Windows.Forms
                        set {
                                if (base.ForeColor == value)
                                        return;
-
-                               base.ForeColor = value;
+                               base.ForeColor = value;
                                Refresh ();
                        }
                }
 
                [DefaultValue (true)]
-               [Localizable (true)]            
+               [Localizable (true)]
                public bool IntegralHeight {
                        get { return integral_height; }
                        set {
                                if (integral_height == value)
                                        return;
-
-                               integral_height = value;
+                               integral_height = value;
                                UpdateComboBoxBounds ();
-                               Refresh ();
+                               Refresh ();
                        }
                }
 
@@ -531,7 +529,7 @@ namespace System.Windows.Forms
                public 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;
@@ -571,8 +569,7 @@ namespace System.Windows.Forms
                        set {
                                if (maxdrop_items == value)
                                        return;
-
-                               maxdrop_items = value;
+                               maxdrop_items = value;
                        }
                }
 
@@ -584,6 +581,7 @@ namespace System.Windows.Forms
                        }
                }
 #endif
+
                [DefaultValue (0)]
                [Localizable (true)]
                public int MaxLength {
@@ -595,13 +593,11 @@ namespace System.Windows.Forms
                                max_length = value;
                                
                                if (dropdown_style != ComboBoxStyle.DropDownList) {
-                                       
                                        if (value < 0) {
                                                value = 0;
                                        }
-                                       
                                        textbox_ctrl.MaxLength = value;
-                               }                       
+                               }
                        }
                }
 
@@ -623,10 +619,10 @@ namespace System.Windows.Forms
 #endif
 
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
-               [Browsable (false)]             
+               [Browsable (false)]
                public int PreferredHeight {
                        get {
-                               return ItemHeight + 5;
+                               return ItemHeight + 6;
                        }
                }
 
@@ -639,18 +635,18 @@ namespace System.Windows.Forms
                                        return;
 
                                if (value <= -2 || value >= Items.Count)
-                                       throw new ArgumentOutOfRangeException ("Index of out range");
-                               selected_index = value;
+                                       throw new ArgumentOutOfRangeException ("SelectedIndex");
+                               selected_index = value;
 
-                               if (dropdown_style != ComboBoxStyle.DropDownList) {
+                               if (dropdown_style != ComboBoxStyle.DropDownList) {
                                        if (value == -1)
                                                SetControlText("");
                                        else
                                                SetControlText (GetItemText (Items [value]));
-                               }
+                               }
 
                                if (DropDownStyle == ComboBoxStyle.DropDownList)
-                                       Invalidate ();
+                                       Invalidate ();
 
                                if (listbox_ctrl != null)
                                        listbox_ctrl.HighlightedIndex = value;
@@ -666,11 +662,10 @@ namespace System.Windows.Forms
                [Bindable(true)]
                public object SelectedItem {
                        get { return selected_index == -1 ? null : Items [selected_index]; }
-                       set {                           
+                       set {
                                object item = selected_index == -1 ? null : Items [selected_index];
                                if (item == value)
                                        return;
-
                                SelectedIndex = Items.IndexOf (value);
                        }
                }
@@ -680,14 +675,20 @@ namespace System.Windows.Forms
                public string SelectedText {
                        get {
                                if (dropdown_style == ComboBoxStyle.DropDownList)
-                                       return "";
+                                       return string.Empty;
                                        
-                               return textbox_ctrl.SelectedText;
+                               string retval = textbox_ctrl.SelectedText;
+                               
+#if ONLY_1_1
+                               // On 1.1, the textbox will return null, combobox returns ""
+                               if (retval == null && !textbox_ctrl.IsHandleCreated)
+                                       return string.Empty;
+#endif                                 
+                               return retval;
                        }
                        set {
                                if (dropdown_style == ComboBoxStyle.DropDownList)
                                        return;
-                               
                                textbox_ctrl.SelectedText = value;
                        }
                }
@@ -705,10 +706,8 @@ namespace System.Windows.Forms
                        set {
                                if (dropdown_style == ComboBoxStyle.DropDownList) 
                                        return;
-                                       
                                if (textbox_ctrl.SelectionLength == value)
                                        return;
-                                       
                                textbox_ctrl.SelectionLength = value;
                        }
                }
@@ -718,17 +717,14 @@ namespace System.Windows.Forms
                public int SelectionStart {
                        get { 
                                if (dropdown_style == ComboBoxStyle.DropDownList) 
-                                       return 0;                                       
-                               
-                               return textbox_ctrl.SelectionStart;                             
+                                       return 0;
+                               return textbox_ctrl.SelectionStart;
                        }
                        set {
                                if (dropdown_style == ComboBoxStyle.DropDownList) 
                                        return;
-                               
                                if (textbox_ctrl.SelectionStart == value)
-                                       return;                                 
-                               
+                                       return;
                                textbox_ctrl.SelectionStart = value;
                        }
                }
@@ -736,19 +732,17 @@ namespace System.Windows.Forms
                [DefaultValue (false)]
                public bool Sorted {
                        get { return sorted; }
-
-                       set {
+                       set {
                                if (sorted == value)
                                        return;
-
-                               sorted = value;
+                               sorted = value;
                                SelectedIndex = -1;
                                if (sorted) {
                                        Items.Sort ();
                                        LayoutComboBox ();
                                }
-                       }
-               }
+                       }
+               }
 
                [Bindable (true)]
                [Localizable (true)]
@@ -759,25 +753,38 @@ namespace System.Windows.Forms
                                                return textbox_ctrl.Text;
                                        }
                                }
-
+                               
                                if (SelectedItem != null)
                                        return GetItemText (SelectedItem);
-                                                               
-                               return base.Text;                               
+                               
+                               return base.Text;
                        }
-                       set {                           
+                       set {
                                if (value == null) {
-                                       SelectedIndex = -1;
+                                       if (SelectedIndex == -1) {
+                                               if (dropdown_style != ComboBoxStyle.DropDownList)
+                                                       SetControlText ("");
+                                       } else {
+                                               SelectedIndex = -1;
+                                       }
                                        return;
                                }
-                               
-                               int index = FindString (value);
-                               
+
+                               // do nothing if value exactly matches text of selected item
+                               if (SelectedItem != null && string.Compare (value, GetItemText (SelectedItem), false, CultureInfo.CurrentCulture) == 0)
+                                       return;
+
+                               // find exact match using case-sensitive comparison, and if does
+                               // not result in any match then use case-insensitive comparison
+                               int index = FindStringExact (value, -1, false);
+                               if (index == -1) {
+                                       index = FindStringExact (value, -1, true);
+                               }
                                if (index != -1) {
                                        SelectedIndex = index;
-                                       return;                                 
+                                       return;
                                }
-                               
+
                                if (dropdown_style != ComboBoxStyle.DropDownList)
                                        textbox_ctrl.Text = GetItemText (value);
                        }
@@ -810,20 +817,21 @@ namespace System.Windows.Forms
                        base.CreateHandle ();
                }
 #endif
+
                protected override void Dispose (bool disposing)
-               {                                               
+               {
                        if (disposing) {
                                if (listbox_ctrl != null) {
                                        listbox_ctrl.Dispose ();
                                        Controls.RemoveImplicit (listbox_ctrl);
                                        listbox_ctrl = null;
-                               }                       
+                               }
                        
                                if (textbox_ctrl != null) {
                                        Controls.RemoveImplicit (textbox_ctrl);
                                        textbox_ctrl.Dispose ();
                                        textbox_ctrl = null;
-                               }                       
+                               }
                        }
                        
                        base.Dispose (disposing);
@@ -843,17 +851,28 @@ namespace System.Windows.Forms
 
                public int FindString (string s, int startIndex)
                {
-                       if (Items.Count == 0) 
-                               return -1; // No exception throwing if empty
+                       if (s == null || Items.Count == 0) 
+                               return -1;
 
+#if NET_2_0
+                       if (startIndex < -1 || startIndex >= Items.Count)
+#else
                        if (startIndex < -1 || startIndex >= Items.Count - 1)
-                               throw new  ArgumentOutOfRangeException ("Index of out range");
+#endif
+                               throw new ArgumentOutOfRangeException ("startIndex");
 
-                       startIndex++;
-                       for (int i = startIndex; i < Items.Count; i++) {
-                               if ((GetItemText (Items[i])).StartsWith (s))
+                       int i = startIndex;
+#if NET_2_0
+                       if (i == (Items.Count - 1))
+                               i = -1;
+#endif
+                       do {
+                               i++;
+                               if (string.Compare (s, 0, GetItemText (Items [i]), 0, s.Length, true) == 0)
                                        return i;
-                       }
+                               if (i == (Items.Count - 1))
+                                       i = -1;
+                       } while (i != startIndex);
 
                        return -1;
                }
@@ -865,27 +884,39 @@ namespace System.Windows.Forms
 
                public int FindStringExact (string s, int startIndex)
                {
-                       if (Items.Count == 0) 
-                               return -1; // No exception throwing if empty
+                       return FindStringExact (s, startIndex, true);
+               }
+
+               private int FindStringExact (string s, int startIndex, bool ignoreCase)
+               {
+                       if (s == null || Items.Count == 0) 
+                               return -1;
 
 #if NET_2_0
                        if (startIndex < -1 || startIndex >= Items.Count)
 #else
                        if (startIndex < -1 || startIndex >= Items.Count - 1)
 #endif
-                               throw new ArgumentOutOfRangeException ("Index of out range");
+                               throw new ArgumentOutOfRangeException ("startIndex");
 
-                       startIndex++;
-                       for (int i = startIndex; i < Items.Count; i++) {
-                               if ((GetItemText (Items[i])).Equals (s))
+                       int i = startIndex;
+#if NET_2_0
+                       if (i == (Items.Count - 1))
+                               i = -1;
+#endif
+                       do {
+                               i++;
+                               if (string.Compare (s, GetItemText (Items [i]), ignoreCase, CultureInfo.CurrentCulture) == 0)
                                        return i;
-                       }
+                               if (i == (Items.Count - 1))
+                                       i = -1;
+                       } while (i != startIndex);
 
                        return -1;
                }
 
                public int GetItemHeight (int index)
-               {       
+               {
                        if (DrawMode == DrawMode.OwnerDrawVariable && IsHandleCreated) {
 
                                if (index < 0 || index >= Items.Count )
@@ -906,16 +937,18 @@ namespace System.Windows.Forms
 
                protected override bool IsInputKey (Keys keyData)
                {
-                       switch (keyData) {
+                       switch (keyData & ~Keys.Modifiers) {
                        case Keys.Up:
                        case Keys.Down:
                        case Keys.Left:
                        case Keys.Right:
                        case Keys.PageUp:
-                       case Keys.PageDown:                     
+                       case Keys.PageDown:
+                       case Keys.Home:
+                       case Keys.End:
                                return true;
                        
-                       default:                                        
+                       default:
                                return false;
                        }
                }
@@ -923,6 +956,9 @@ namespace System.Windows.Forms
                protected override void OnBackColorChanged (EventArgs e)
                {
                        base.OnBackColorChanged (e);
+
+                       if (textbox_ctrl != null)
+                               textbox_ctrl.BackColor = BackColor;
                }
 
                protected override void OnDataSourceChanged (EventArgs e)
@@ -942,11 +978,17 @@ namespace System.Windows.Forms
                {
                        base.OnDisplayMemberChanged (e);
 
-                       if (DataManager == null || !IsHandleCreated)
-                              return;
+                       if (DataManager == null)
+                               return;
+
+                       if (selected_index != -1 && DropDownStyle != ComboBoxStyle.DropDownList)
+                               SetControlText (GetItemText (Items [selected_index]));
+
+                       if (!IsHandleCreated)
+                               return;
 
-                       BindDataItems ();
                        SelectedIndex = DataManager.Position;
+                       Invalidate ();
                }
 
                protected virtual void OnDrawItem (DrawItemEventArgs e)
@@ -962,7 +1004,7 @@ namespace System.Windows.Forms
                                ThemeEngine.Current.DrawComboBoxItem (this, e);
                                break;
                        }
-               }               
+               }
 
                protected virtual void OnDropDown (EventArgs e)
                {
@@ -979,6 +1021,7 @@ namespace System.Windows.Forms
                                eh (this, e);
                }
 #endif
+
                protected virtual void OnDropDownStyleChanged (EventArgs e)
                {
                        EventHandler eh = (EventHandler)(Events [DropDownStyleChangedEvent]);
@@ -994,7 +1037,7 @@ namespace System.Windows.Forms
                                textbox_ctrl.Font = Font;
                        
                        if (!item_height_specified) {
-                               SizeF sz = DeviceContext.MeasureString ("The quick brown Fox", Font);
+                               SizeF sz = TextRenderer.MeasureString ("The quick brown Fox", Font);
                                item_height = (int) sz.Height;
                        }
 
@@ -1007,9 +1050,11 @@ namespace System.Windows.Forms
                protected override void OnForeColorChanged (EventArgs e)
                {
                        base.OnForeColorChanged (e);
+                       if (textbox_ctrl != null)
+                               textbox_ctrl.ForeColor = ForeColor;
                }
 
-               [EditorBrowsable(EditorBrowsableState.Advanced)]                
+               [EditorBrowsable(EditorBrowsableState.Advanced)]
                protected override void OnGotFocus (EventArgs e)
                {
                        if (dropdown_style == ComboBoxStyle.DropDownList) {
@@ -1020,15 +1065,15 @@ namespace System.Windows.Forms
                        
                        if (textbox_ctrl != null) {
                                textbox_ctrl.SetSelectable (false);
-                               textbox_ctrl.ActivateCaret (true);
                                textbox_ctrl.ShowSelection = true;
+                               textbox_ctrl.ActivateCaret (true);
                                textbox_ctrl.SelectAll ();
                        }
 
                        base.OnGotFocus (e);
                }
 
-               [EditorBrowsable(EditorBrowsableState.Advanced)]                
+               [EditorBrowsable(EditorBrowsableState.Advanced)]
                protected override void OnLostFocus (EventArgs e)
                {
                        if (dropdown_style == ComboBoxStyle.DropDownList) {
@@ -1045,6 +1090,7 @@ namespace System.Windows.Forms
                                textbox_ctrl.SetSelectable (true);
                                textbox_ctrl.ActivateCaret (false);
                                textbox_ctrl.ShowSelection = false;
+                               textbox_ctrl.SelectionLength = 0;
                        }
 
                        base.OnLostFocus (e);
@@ -1054,15 +1100,13 @@ namespace System.Windows.Forms
                {
                        base.OnHandleCreated (e);
 
-                       if (listbox_ctrl != null) {
-                               Controls.AddImplicit (listbox_ctrl);
-                               listbox_ctrl.Visible = true;
-                       }
+                       SetBounds (Left, Top, Width, PreferredHeight, BoundsSpecified.None);
 
                        if (textbox_ctrl != null)
                                Controls.AddImplicit (textbox_ctrl);
 
                        LayoutComboBox ();
+                       UpdateComboBoxBounds ();
                }
 
                protected override void OnHandleDestroyed (EventArgs e)
@@ -1072,9 +1116,19 @@ namespace System.Windows.Forms
 
                protected override void OnKeyPress (KeyPressEventArgs e)
                {
-                       // int index = FindStringCaseInsensitive (e.KeyChar.ToString (), SelectedIndex);
-                       //if (index != -1)
-                       //      SelectedIndex = index;
+                       if (dropdown_style == ComboBoxStyle.DropDownList) {
+                               int index = FindStringCaseInsensitive (e.KeyChar.ToString (), SelectedIndex + 1);
+                               if (index != -1) {
+                                       SelectedIndex = index;
+                                       if (DroppedDown) { //Scroll into view
+                                               if (SelectedIndex >= listbox_ctrl.LastVisibleItem ())
+                                                       listbox_ctrl.Scroll (SelectedIndex - listbox_ctrl.LastVisibleItem () + 1);
+                                               // Or, selecting an item earlier in the list.
+                                               if (SelectedIndex < listbox_ctrl.FirstVisibleItem ())
+                                                       listbox_ctrl.Scroll (SelectedIndex - listbox_ctrl.FirstVisibleItem ());
+                                       }
+                               }
+                       }
 
                        base.OnKeyPress (e);
                }
@@ -1092,7 +1146,7 @@ namespace System.Windows.Forms
                }
 
                protected override void OnResize (EventArgs e)
-               {                       
+               {
                        LayoutComboBox ();
                        if (listbox_ctrl != null)
                                listbox_ctrl.CalcListBoxArea ();
@@ -1109,7 +1163,6 @@ namespace System.Windows.Forms
 
                protected virtual void OnSelectedItemChanged (EventArgs e)
                {
-                       
                }
 
                protected override void OnSelectedValueChanged (EventArgs e)
@@ -1127,13 +1180,20 @@ namespace System.Windows.Forms
                protected override void RefreshItem (int index)
                {
                        if (index < 0 || index >= Items.Count)
-                               throw new ArgumentOutOfRangeException ("Index of out range");
+                               throw new ArgumentOutOfRangeException ("index");
                                
                        if (draw_mode == DrawMode.OwnerDrawVariable)
                                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 ResetText ()
                {
                        Text = String.Empty;
@@ -1189,6 +1249,13 @@ namespace System.Windows.Forms
                }
 #endif
 
+#if NET_2_0
+               protected override void ScaleControl (SizeF factor, BoundsSpecified specified)
+               {
+                       base.ScaleControl (factor, specified);
+               }
+#endif
+
                public void Select (int start, int length)
                {
                        if (start < 0)
@@ -1212,10 +1279,10 @@ namespace System.Windows.Forms
                                textbox_ctrl.ShowSelection = true;
                                textbox_ctrl.SelectAll ();
                        }
-               }               
+               }
 
                protected override void SetBoundsCore (int x, int y, int width, int height, BoundsSpecified specified)
-               {                       
+               {
                        if ((specified & BoundsSpecified.Height) != 0) {
                                requested_height = height;
 
@@ -1251,7 +1318,7 @@ namespace System.Windows.Forms
                                Items.Clear ();
                                Items.AddRange (value);
                        } finally {
-                               EndUpdate ();
+                               EndUpdate ();
                        }
                }
 
@@ -1273,7 +1340,7 @@ namespace System.Windows.Forms
                                if (textbox_ctrl != null)
                                        XplatUI.SendMessage (textbox_ctrl.Handle, (Msg) m.Msg, m.WParam, m.LParam);
                                break;
-                       case Msg.WM_MOUSE_LEAVE:
+                       case Msg.WM_MOUSELEAVE:
                                Point location = PointToClient (Control.MousePosition);
                                if (ClientRectangle.Contains (location))
                                        return;
@@ -1301,7 +1368,7 @@ namespace System.Windows.Forms
                }
                
                void LayoutComboBox ()
-               {                       
+               {
                        int border = ThemeEngine.Current.Border3DSize.Width;
 
                        text_area = ClientRectangle;
@@ -1317,8 +1384,8 @@ namespace System.Windows.Forms
                                button_area = Rectangle.Empty;
                        else {
                                button_area = text_area;
-                               button_area.X = text_area.Right - button_width - border;
-                               button_area.Y = text_area.Y + border;
+                               button_area.X = text_area.Right - button_width - border;
+                               button_area.Y = text_area.Y + border;
                                button_area.Width = button_width;
                                button_area.Height = text_area.Height - 2 * border;
 #if NET_2_0
@@ -1339,9 +1406,10 @@ namespace System.Windows.Forms
                        }
 
                        if (textbox_ctrl != null) {
-                               textbox_ctrl.Location = new Point (text_area.X + border, text_area.Y + border);
-                               textbox_ctrl.Width = text_area.Width - button_area.Width - border * 2;
-                               textbox_ctrl.Height = text_area.Height - border * 2;
+                               int text_border = border + 1;
+                               textbox_ctrl.Location = new Point (text_area.X + text_border, text_area.Y + text_border);
+                               textbox_ctrl.Width = text_area.Width - button_area.Width - text_border * 2;
+                               textbox_ctrl.Height = text_area.Height - text_border * 2;
                        }
 
                        if (listbox_ctrl != null && dropdown_style == ComboBoxStyle.Simple) {
@@ -1351,13 +1419,13 @@ namespace System.Windows.Forms
                }
 
                private void CreateComboListBox ()
-               {                       
-                       listbox_ctrl = new ComboListBox (this);                 
+               {
+                       listbox_ctrl = new ComboListBox (this);
                        listbox_ctrl.HighlightedIndex = SelectedIndex;
                }
                
                internal void Draw (Rectangle clip, Graphics dc)
-               {                               
+               {
                        Theme theme = ThemeEngine.Current;
                        FlatStyle style = FlatStyle.Standard;
                        bool is_flat = false;
@@ -1367,6 +1435,9 @@ namespace System.Windows.Forms
                        is_flat = style == FlatStyle.Flat || style == FlatStyle.Popup;
 #endif
 
+                       if (!Enabled)
+                               dc.FillRectangle (theme.ResPool.GetSolidBrush (theme.ColorControl), bounds);
+
                        if (DropDownStyle == ComboBoxStyle.Simple)
                                dc.FillRectangle (theme.ResPool.GetSolidBrush (Parent.BackColor), ClientRectangle);
 
@@ -1388,54 +1459,73 @@ namespace System.Windows.Forms
                                Rectangle item_rect = text_area;
                                item_rect.X += border;
                                item_rect.Y += border;
-                               item_rect.Width -= (button_area.Width + 2 * border);                            
-                               item_rect.Height -= 2 * border;                         
-                                                               
+                               item_rect.Width -= (button_area.Width + 2 * border);
+                               item_rect.Height -= 2 * border;
+                               
                                if (Focused) {
                                        state = DrawItemState.Selected;
                                        state |= DrawItemState.Focus;
                                }
                                
-                               state |= DrawItemState.ComboBoxEdit;                            
+                               state |= DrawItemState.ComboBoxEdit;
                                OnDrawItem (new DrawItemEventArgs (dc, Font, item_rect, SelectedIndex, state, ForeColor, BackColor));
-                       }                                               
+                       }
                        
                        if (show_dropdown_button) {
-                               dc.FillRectangle (theme.ResPool.GetSolidBrush (theme.ColorControl), button_area);
+                               ButtonState current_state;
+                               if (is_enabled)
+                                       current_state = button_state;
+                               else
+                                       current_state = ButtonState.Inactive;
+
+                               if (is_flat || theme.ComboBoxNormalDropDownButtonHasTransparentBackground (this, current_state))
+                                       dc.FillRectangle (theme.ResPool.GetSolidBrush (theme.ColorControl), button_area);
 
-                               if (!is_enabled)
-                                       button_state = ButtonState.Inactive;
-                               
                                if (is_flat) {
-                                       theme.DrawFlatStyleComboButton (dc, button_area, button_state);
+                                       theme.DrawFlatStyleComboButton (dc, button_area, current_state);
                                } else {
-                                       theme.CPDrawComboButton (dc, button_area, button_state);
+                                       theme.ComboBoxDrawNormalDropDownButton (this, dc, clip, button_area, current_state); 
                                }
-                       }                       
+                       }
+               }
+
+               internal bool DropDownButtonEntered {
+                       get { return drop_down_button_entered; }
+                       private set {
+                               if (drop_down_button_entered == value)
+                                       return;
+                               drop_down_button_entered = value;
+                               if (ThemeEngine.Current.ComboBoxDropDownButtonHasHotElementStyle (this))
+                                       Invalidate (button_area);
+                       }
                }
 
                internal void DropDownListBox ()
                {
+                       DropDownButtonEntered = false;
+
                        if (DropDownStyle == ComboBoxStyle.Simple)
-                               return;                 
+                               return;
                        
                        if (listbox_ctrl == null)
-                               CreateComboListBox ();
+                               CreateComboListBox ();
 
                        listbox_ctrl.Location = PointToScreen (new Point (text_area.X, text_area.Y + text_area.Height));
-                                               
-                       if (listbox_ctrl.ShowWindow ())                                 
-                               dropped_down = true;                                    
-                       
-                       button_state = ButtonState.Pushed;                              
-                       if (dropdown_style == ComboBoxStyle.DropDownList)
-                               Invalidate (text_area);
+
+                       FindMatchOrSetIndex(SelectedIndex);
+
+                       if (listbox_ctrl.ShowWindow ())
+                               dropped_down = true;
+
+                       button_state = ButtonState.Pushed;
+                       if (dropdown_style == ComboBoxStyle.DropDownList)
+                               Invalidate (text_area);
                }
                
                internal void DropDownListBoxFinished ()
                {
                        if (DropDownStyle == ComboBoxStyle.Simple)
-                               return;                 
+                               return;
                                
                        button_state = ButtonState.Normal;
                        Invalidate (button_area);
@@ -1443,16 +1533,27 @@ namespace System.Windows.Forms
 #if NET_2_0
                        OnDropDownClosed (EventArgs.Empty);
 #endif
+                       /*
+                        * Apples X11 looses override-redirect when doing a Unmap/Map on a previously mapped window
+                        * this causes the popup to appear under the main form.  This is horrible but necessary
+                        */
+                        
+                        // If the user opens a new form in an event, it will close our dropdown,
+                        // so we need a null check here
+                        if (listbox_ctrl != null) {
+                               listbox_ctrl.Dispose ();
+                               listbox_ctrl = null;
+                       }
                }
                
                private int FindStringCaseInsensitive (string search)
-               {                       
+               {
                        if (search.Length == 0) {
                                return -1;
                        }
                        
                        for (int i = 0; i < Items.Count; i++) 
-                       {                               
+                       {
                                if (String.Compare (GetItemText (Items[i]), 0, search, 0, search.Length, true) == 0)
                                        return i;
                        }
@@ -1460,11 +1561,16 @@ namespace System.Windows.Forms
                        return -1;
                }
 
+               // Search in the list for the substring, starting the search at the list 
+               // position specified, the search wraps thus covering all the list.
                internal int FindStringCaseInsensitive (string search, int start_index)
                {
                        if (search.Length == 0) {
                                return -1;
                        }
+                       // Accept from first item to after last item. i.e. all cases of (SelectedIndex+1).
+                       if (start_index < 0 || start_index > Items.Count)
+                               throw new ArgumentOutOfRangeException("start_index");
 
                        for (int i = 0; i < Items.Count; i++) {
                                int index = (i + start_index) % Items.Count;
@@ -1475,38 +1581,130 @@ namespace System.Windows.Forms
                        return -1;
                }
 
+               internal override bool IsInputCharInternal (char charCode)
+               {
+                       return true;
+               }
+
+               internal override ContextMenu ContextMenuInternal {
+                       get {
+                               return base.ContextMenuInternal;
+                       }
+                       set {
+                               base.ContextMenuInternal = value;
+                               if (textbox_ctrl != null) {
+                                       textbox_ctrl.ContextMenu = value;
+                               }
+                       }
+               }
+
+               internal void RestoreContextMenu ()
+               {
+                       textbox_ctrl.RestoreContextMenu ();
+               }
+
                private void OnKeyDownCB(object sender, KeyEventArgs e)
                {
                        if (Items.Count == 0)
                                return;
 
+                       int offset;
                        switch (e.KeyCode) 
-                       {                       
+                       {
                                case Keys.Up:
-                                       SelectedIndex = Math.Max(SelectedIndex-1, 0);
-                                       break;                          
+                                       FindMatchOrSetIndex(Math.Max(SelectedIndex - 1, 0));
+
+                                       if (DroppedDown)
+                                               if (SelectedIndex < listbox_ctrl.FirstVisibleItem ())
+                                                       listbox_ctrl.Scroll (SelectedIndex - listbox_ctrl.FirstVisibleItem ());
+                                       break;
        
                                case Keys.Down:
-                                       SelectedIndex = Math.Min(SelectedIndex+1, Items.Count-1);
+                                       if ((e.Modifiers & Keys.Alt) == Keys.Alt)
+                                               DropDownListBox ();
+                                       else
+                                               FindMatchOrSetIndex(Math.Min(SelectedIndex + 1, Items.Count - 1));
+                                               
+                                       if (DroppedDown)
+                                               if (SelectedIndex >= listbox_ctrl.LastVisibleItem ())
+                                                       listbox_ctrl.Scroll (SelectedIndex - listbox_ctrl.LastVisibleItem () + 1);
                                        break;
                                
                                case Keys.PageUp:
-                                       if (listbox_ctrl != null)
-                                               SelectedIndex = Math.Max(SelectedIndex- (listbox_ctrl.page_size-1), 0);
-                                       break;                          
+                                       offset = listbox_ctrl == null ? MaxDropDownItems - 1 : listbox_ctrl.page_size - 1;
+                                       if (offset < 1)
+                                               offset = 1;
+
+                                       SelectedIndex = Math.Max (SelectedIndex - offset, 0);
+
+                                       if (DroppedDown)
+                                               if (SelectedIndex < listbox_ctrl.FirstVisibleItem ())
+                                                       listbox_ctrl.Scroll (SelectedIndex - listbox_ctrl.FirstVisibleItem ());
+                                       break;
        
-                               case Keys.PageDown:             
-                                       if (listbox_ctrl != null)               
-                                               SelectedIndex = Math.Min(SelectedIndex+(listbox_ctrl.page_size-1), Items.Count-1);
+                               case Keys.PageDown:
+                                       if (SelectedIndex == -1) {
+                                               SelectedIndex = 0;
+                                               if (dropdown_style != ComboBoxStyle.Simple)
+                                                       return;
+                                       }
+
+                                       offset = listbox_ctrl == null ? MaxDropDownItems - 1 : listbox_ctrl.page_size - 1;
+                                       if (offset < 1)
+                                               offset = 1;
+
+                                       SelectedIndex = Math.Min (SelectedIndex + offset, Items.Count - 1);
+
+                                       if (DroppedDown)
+                                               if (SelectedIndex >= listbox_ctrl.LastVisibleItem ())
+                                                       listbox_ctrl.Scroll (SelectedIndex - listbox_ctrl.LastVisibleItem () + 1);
+                                       break;
+                                       
+                               case Keys.Escape:
+                                       DropDownListBoxFinished ();
+                                       break;
+                                       
+                               case Keys.Home:
+                                       if (dropdown_style == ComboBoxStyle.DropDownList) {
+                                               SelectedIndex = 0;
+
+                                               if (DroppedDown)
+                                                       if (SelectedIndex < listbox_ctrl.FirstVisibleItem ())
+                                                               listbox_ctrl.Scroll (SelectedIndex - listbox_ctrl.FirstVisibleItem ());
+                                       }
+                                       
+                                       break;
+                               case Keys.End:
+                                       if (dropdown_style == ComboBoxStyle.DropDownList) {
+                                               SelectedIndex = Items.Count - 1;
+
+                                               if (DroppedDown)
+                                                       if (SelectedIndex >= listbox_ctrl.LastVisibleItem ())
+                                                               listbox_ctrl.Scroll (SelectedIndex - listbox_ctrl.LastVisibleItem () + 1);
+                                       }
+                                       
                                        break;
-                               
                                default:
                                        break;
                        }
                }
+
+               // If no item is currently selected, and an item is found matching the text 
+               // in the textbox, then selected that item.  Otherwise the item at the given 
+               // index is selected.
+               private void FindMatchOrSetIndex(int index)
+               {
+                       int match = -1;
+                       if (SelectedIndex == -1 && Text.Length != 0)
+                               match = FindStringCaseInsensitive(Text);
+                       if (match != -1)
+                               SelectedIndex = match;
+                       else
+                               SelectedIndex = index;
+               }
                
                void OnMouseDownCB (object sender, MouseEventArgs e)
-               {
+               {
                        Rectangle area;
                        if (DropDownStyle == ComboBoxStyle.DropDownList)
                                area = ClientRectangle;
@@ -1514,15 +1712,30 @@ namespace System.Windows.Forms
                                area = button_area;
 
                        if (area.Contains (e.X, e.Y)) {
-                               DropDownListBox ();                                     
-                               Invalidate (button_area);
+                               if (Items.Count > 0)
+                                       DropDownListBox ();
+                               else {
+                                       button_state = ButtonState.Pushed;
+                                       OnDropDown (EventArgs.Empty);
+                               }
+                               
+                               Invalidate (button_area);
                                Update ();
-                       }
+                       }
                        Capture = true;
-               }
+               }
+
+               void OnMouseLeave (object sender, EventArgs e)
+               {
+                       if (show_dropdown_button)
+                               DropDownButtonEntered = false;
+               }
+
+               void OnMouseMoveCB (object sender, MouseEventArgs e)
+               {
+                       if (show_dropdown_button && !dropped_down)
+                               DropDownButtonEntered = button_area.Contains (e.Location);
 
-               void OnMouseMoveCB (object sender, MouseEventArgs e)
-               {                       
                        if (DropDownStyle == ComboBoxStyle.Simple)
                                return;
 
@@ -1531,16 +1744,20 @@ namespace System.Windows.Forms
                                if (listbox_ctrl.ClientRectangle.Contains (location))
                                        listbox_ctrl.Capture = true;
                        }
-               }
+               }
 
-               void OnMouseUpCB (object sender, MouseEventArgs e)
-               {
+               void OnMouseUpCB (object sender, MouseEventArgs e)
+               {
                        Capture = false;
+                       
+                       button_state = ButtonState.Normal;
+                       Invalidate (button_area);
+
                        OnClick (EventArgs.Empty);
 
                        if (dropped_down)
                                listbox_ctrl.Capture = true;
-               }
+               }
 
                private void OnMouseWheelCB (object sender, MouseEventArgs me)
                {
@@ -1564,9 +1781,9 @@ namespace System.Windows.Forms
                internal override void OnPaintInternal (PaintEventArgs pevent)
                {
                        if (suspend_ctrlupdate)
-                               return;
-                               
-                       Draw (ClientRectangle, pevent.Graphics);                        
+                               return;
+
+                       Draw (ClientRectangle, pevent.Graphics);
                }
                
                private void OnTextBoxClick (object sender, EventArgs e)
@@ -1578,7 +1795,7 @@ namespace System.Windows.Forms
                {
                        if (process_textchanged_event == false)
                                return; 
-                               
+
                        OnTextChanged (EventArgs.Empty);
 
                        int item = FindStringCaseInsensitive (textbox_ctrl.Text);
@@ -1597,13 +1814,19 @@ namespace System.Windows.Forms
 
                        base.Text = textbox_ctrl.Text;
                }
-               
+
+               private void OnTextKeyPress (object sender, KeyPressEventArgs e)
+               {
+                       selected_index = -1;
+               }
+
                internal void SetControlText (string s)
-               {               
+               {
                        process_textchanged_event = false;
-                       textbox_ctrl.Text = s;
-                       process_textchanged_event = true;
-               }
+                       textbox_ctrl.Text = s;
+                       textbox_ctrl.SelectAll ();
+                       process_textchanged_event = true;
+               }
                
                void UpdateComboBoxBounds ()
                {
@@ -1612,7 +1835,7 @@ namespace System.Windows.Forms
 
                        // Save the requested height since set bounds can destroy it
                        int save_height = requested_height;
-                       SetBounds (0, 0, 0, requested_height, BoundsSpecified.Height);
+                       SetBounds (bounds.X, bounds.Y, bounds.Width, requested_height, BoundsSpecified.Height);
                        requested_height = save_height;
                }
 
@@ -1653,13 +1876,13 @@ namespace System.Windows.Forms
                        public virtual object this [int index] {
                                get {
                                        if (index < 0 || index >= Count)
-                                               throw new ArgumentOutOfRangeException ("Index of out range");
+                                               throw new ArgumentOutOfRangeException ("index");
 
                                        return object_items[index];
                                }
                                set {
                                        if (index < 0 || index >= Count)
-                                               throw new ArgumentOutOfRangeException ("Index of out range");
+                                               throw new ArgumentOutOfRangeException ("index");
                                        if (value == null)
                                                throw new ArgumentNullException ("value");
 
@@ -1718,15 +1941,26 @@ namespace System.Windows.Forms
                                owner.Refresh ();
                        }
                        
-                       public bool Contains (object obj)
+                       public bool Contains (object value)
                        {
-                               if (obj == null)
-                                       throw new ArgumentNullException ("obj");
+                               if (value == null)
+                                       throw new ArgumentNullException ("value");
 
-                               return object_items.Contains (obj);
+                               return object_items.Contains (value);
                        }
 
-                       public void CopyTo (object[] dest, int arrayIndex)
+#if NET_2_0
+                       public void CopyTo (object [] destination, int arrayIndex)
+                       {
+                               object_items.CopyTo (destination, arrayIndex);
+                       }
+
+                       void ICollection.CopyTo (Array destination, int index)
+                       {
+                               object_items.CopyTo (destination, index);
+                       }
+#else
+                       public void CopyTo (object [] dest, int arrayIndex)
                        {
                                object_items.CopyTo (dest, arrayIndex);
                        }
@@ -1735,6 +1969,7 @@ namespace System.Windows.Forms
                        {
                                object_items.CopyTo (dest, index);
                        }
+#endif
 
                        public IEnumerator GetEnumerator ()
                        {
@@ -1757,7 +1992,7 @@ namespace System.Windows.Forms
                        public void Insert (int index,  object item)
                        {
                                if (index < 0 || index > Count)
-                                       throw new ArgumentOutOfRangeException ("Index of out range");                                   
+                                       throw new ArgumentOutOfRangeException ("index");
                                if (item == null)
                                        throw new ArgumentNullException ("item");
                                
@@ -1767,25 +2002,25 @@ namespace System.Windows.Forms
                                        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.SelectedIndex = -1;
                                
-                               RemoveAt (IndexOf (value));                             
+                               RemoveAt (IndexOf (value));
                        }
 
                        public void RemoveAt (int index)
                        {
                                if (index < 0 || index >= Count)
-                                       throw new ArgumentOutOfRangeException ("Index of out range");
+                                       throw new ArgumentOutOfRangeException ("index");
                                        
                                if (index == owner.SelectedIndex)
                                        owner.SelectedIndex = -1;
@@ -1806,6 +2041,13 @@ namespace System.Windows.Forms
                                        foreach (object o in object_items) {
                                                if (String.Compare (item.ToString (), o.ToString ()) < 0) {
                                                        object_items.Insert (index, item);
+                                                       
+                                                       // If we added the new item before the selectedindex
+                                                       // bump the selectedindex by one, behavior differs if
+                                                       // Handle has not been created.
+                                                       if (index <= owner.selected_index && owner.IsHandleCreated)
+                                                               owner.selected_index++;
+                                                               
                                                        return index;
                                                }
                                                index++;
@@ -1819,7 +2061,7 @@ namespace System.Windows.Forms
                        {
                                foreach (object mi in items)
                                        AddItem (mi);
-                                                                               
+                               
                                owner.UpdatedItems ();
                        }
 
@@ -1839,6 +2081,7 @@ namespace System.Windows.Forms
                        {
                                this.owner = owner;
                                ShowSelection = false;
+                               HideSelection = false;
                        }
 
                        internal void SetSelectable (bool selectable)
@@ -1870,12 +2113,20 @@ namespace System.Windows.Forms
                        protected override void OnLostFocus (EventArgs e)
                        {
                                owner.Select (false, true);
-                       }                       
+                       }
+
+                       public override bool Focused {
+                               get {
+                                       return owner.Focused;
+                               }
+                       }
+                       
+                       internal override bool ActivateOnShow { get { return false; } }
                }
 
                internal class ComboListBox : Control
                {
-                       private ComboBox owner;                 
+                       private ComboBox owner;
                        private VScrollBarLB vscrollbar_ctrl;
                        private int top_item;                   /* First item that we show the in the current page */
                        private int last_item;                  /* Last visible item */
@@ -1895,7 +2146,7 @@ namespace System.Windows.Forms
                        class VScrollBarLB : VScrollBar
                        {
                                public VScrollBarLB ()
-                               {                                       
+                               {
                                }
                                
                                internal override bool InternalCapture {
@@ -1910,7 +2161,7 @@ namespace System.Windows.Forms
 
                                        e = TranslateEvent (e);
                                        OnMouseDown (e);
-                               }       
+                               }
                                
                                public void FireMouseUp (MouseEventArgs e) 
                                {
@@ -1928,18 +2179,18 @@ namespace System.Windows.Forms
 
                                        e = TranslateEvent (e);
                                        OnMouseMove (e);
-                               }                       
+                               }
                                
                                MouseEventArgs TranslateEvent (MouseEventArgs e)
                                {
                                        Point loc = PointToClient (Control.MousePosition);
-                                       return new MouseEventArgs (e.Button, e.Clicks, loc.X, loc.Y, e.Delta);
+                                       return new MouseEventArgs (e.Button, e.Clicks, loc.X, loc.Y, e.Delta);
                                }
                        }
 
                        public ComboListBox (ComboBox owner)
-                       {                                       
-                               this.owner = owner;                                                             
+                       {
+                               this.owner = owner;
                                top_item = 0;
                                last_item = 0;
                                page_size = 0;
@@ -1950,7 +2201,6 @@ namespace System.Windows.Forms
                                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;
@@ -1961,22 +2211,18 @@ namespace System.Windows.Forms
                        protected override CreateParams CreateParams
                        {
                                get {
-                                       CreateParams cp = base.CreateParams;                                    
+                                       CreateParams cp = base.CreateParams;
                                        if (owner == null || owner.DropDownStyle == ComboBoxStyle.Simple)
                                                return cp;
 
-                                       cp.Style ^= (int) WindowStyles.WS_CHILD;
-                                       cp.Style |= (int) WindowStyles.WS_POPUP;
+                                       cp.Style ^= (int)WindowStyles.WS_CHILD;
+                                       cp.Style ^= (int)WindowStyles.WS_VISIBLE;
+                                       cp.Style |= (int)WindowStyles.WS_POPUP;
                                        cp.ExStyle |= (int) WindowExStyles.WS_EX_TOOLWINDOW | (int) WindowExStyles.WS_EX_TOPMOST;
                                        return cp;
                                }
                        }
 
-                       protected override void Select (bool directed, bool forward)
-                       {
-                               // Do nothing, we never want to be selected
-                       }
-
                        internal override bool InternalCapture {
                                get {
                                        return Capture;
@@ -1986,35 +2232,30 @@ namespace System.Windows.Forms
                                }
                        }
 
-                       int BorderWidth {
-                               get {
-                                       switch (border_style) {
-                                       case BorderStyle.Fixed3D:
-                                               return ThemeEngine.Current.Border3DSize.Width;
-                                       default:
-                                               return ThemeEngine.Current.BorderSize.Width;
-                                       }
-                               }
-                       }
+                       internal override bool ActivateOnShow { get { return false; } }
+                       #region Private Methods
 
-                       #region Private Methods                 
                        // Calcs the listbox area
                        internal void CalcListBoxArea ()
-                       {                               
+                       {
                                int width, height;
                                bool show_scrollbar = false;
-                               
+
                                if (owner.DropDownStyle == ComboBoxStyle.Simple) {
                                        Rectangle area = owner.listbox_area;
                                        width = area.Width;
                                        height = area.Height;
+
+                                       // No calculation needed
+                                       if (height <= 0 || width <= 0)
+                                               return;
                                }
                                else { // DropDown or DropDownList
                                        
                                        width = owner.DropDownWidth;
-                                       int count = (owner.Items.Count <= owner.MaxDropDownItems) ? owner.Items.Count : owner.MaxDropDownItems;                         
+                                       int count = (owner.Items.Count <= owner.MaxDropDownItems) ? owner.Items.Count : owner.MaxDropDownItems;
                                        
-                                       if (owner.DrawMode == DrawMode.OwnerDrawVariable) {                                             
+                                       if (owner.DrawMode == DrawMode.OwnerDrawVariable) {
                                                height = 0;
                                                for (int i = 0; i < count; i++) {
                                                        height += owner.GetItemHeight (i);
@@ -2029,12 +2270,17 @@ namespace System.Windows.Forms
                                        }
                                }
                                
-                               page_size = height / owner.ItemHeight;
+                               page_size = Math.Max (height / owner.ItemHeight, 1);
+
+                               ComboBoxStyle dropdown_style = owner.DropDownStyle;
+                               if ((dropdown_style != ComboBoxStyle.Simple && owner.Items.Count <= owner.MaxDropDownItems)
+                                       || (dropdown_style == ComboBoxStyle.Simple && owner.Items.Count * owner.ItemHeight < height)) {
 
-                               if (owner.Items.Count <= owner.MaxDropDownItems) {                                      
                                        if (vscrollbar_ctrl != null)
                                                vscrollbar_ctrl.Visible = false;
-                               } else {                                        
+                                       if (dropdown_style != ComboBoxStyle.Simple)
+                                               height = owner.ItemHeight * owner.items.Count;
+                               } else {
                                        /* Need vertical scrollbar */
                                        if (vscrollbar_ctrl == null) {
                                                vscrollbar_ctrl = new VScrollBarLB ();
@@ -2046,14 +2292,16 @@ namespace System.Windows.Forms
                                                Controls.AddImplicit (vscrollbar_ctrl);
                                        }
                                        
-                                       vscrollbar_ctrl.Height = height - 2 * BorderWidth;
-                                                       
-                                       vscrollbar_ctrl.Location = new Point (width - vscrollbar_ctrl.Width - BorderWidth - 1, 0);
+                                       vscrollbar_ctrl.Dock = DockStyle.Right;
 
-                                       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.Maximum = owner.Items.Count - 1;
+#if NET_2_0
+                                       int large = page_size;
+#else
+                                       int large = (dropdown_style == ComboBoxStyle.Simple ? page_size : owner.maxdrop_items) - 1;
+#endif
+                                       if (large < 1)
+                                               large = 1;
                                        vscrollbar_ctrl.LargeChange = large;
                                        show_scrollbar = vscrollbar_ctrl.Visible = true;
 
@@ -2067,16 +2315,16 @@ namespace System.Windows.Forms
                                Size = new Size (width, height);
                                textarea_drawable = ClientRectangle;
                                textarea_drawable.Width = width;
-                               textarea_drawable.Height = height;                              
+                               textarea_drawable.Height = height;
                                
                                if (vscrollbar_ctrl != null && show_scrollbar)
                                        textarea_drawable.Width -= vscrollbar_ctrl.Width;
 
                                last_item = LastVisibleItem ();
-                       }                       
+                       }
 
                        private void Draw (Rectangle clip, Graphics dc)
-                       {       
+                       {
                                dc.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (owner.BackColor), clip);
 
                                if (owner.Items.Count > 0) {
@@ -2094,9 +2342,9 @@ namespace System.Windows.Forms
                                                        
                                                        if (owner.DropDownStyle == ComboBoxStyle.DropDownList) {
                                                                state |= DrawItemState.Focus;
-                                                       }                                                       
+                                                       }
                                                }
-                                                       
+                                               
                                                owner.OnDrawItem (new DrawItemEventArgs (dc, owner.Font, item_rect,
                                                        i, state, owner.ForeColor, owner.BackColor));
                                        }
@@ -2114,7 +2362,7 @@ namespace System.Windows.Forms
                                        if (highlighted_index != -1 && highlighted_index < this.owner.Items.Count)
                                                Invalidate (GetItemDisplayRectangle (highlighted_index, top_item));
                                        highlighted_index = value;
-                                       if (highlighted_index != -1)
+                                       if (highlighted_index != -1)
                                                Invalidate (GetItemDisplayRectangle (highlighted_index, top_item));
                                }
                        }
@@ -2152,7 +2400,7 @@ namespace System.Windows.Forms
 
                        private int IndexFromPointDisplayRectangle (int x, int y)
                        {
-                               for (int i = top_item; i <= last_item; i++) {
+                               for (int i = top_item; i <= last_item; i++) {
                                        if (GetItemDisplayRectangle (i, top_item).Contains (x, y) == true)
                                                return i;
                                }
@@ -2166,14 +2414,14 @@ namespace System.Windows.Forms
                                        Invalidate (GetItemDisplayRectangle (index, top_item));
                        }
 
-                       private int LastVisibleItem ()
+                       public int LastVisibleItem ()
                        {
                                Rectangle item_rect;
                                int top_y = textarea_drawable.Y + textarea_drawable.Height;
-                               int i = 0;                              
+                               int i = 0;
                                
                                for (i = top_item; i < owner.Items.Count; i++) {
-                                       item_rect = GetItemDisplayRectangle (i, top_item);                              
+                                       item_rect = GetItemDisplayRectangle (i, top_item);
                                        if (item_rect.Y + item_rect.Height > top_y) {
                                                return i;
                                        }
@@ -2188,8 +2436,13 @@ namespace System.Windows.Forms
                                top_item = item;
                                UpdateLastVisibleItem ();
                                Invalidate ();
-                       }                       
+                       }
 
+                       public int FirstVisibleItem ()
+                       {
+                               return top_item;
+                       }
+                       
                        bool scrollbar_grabbed = false;
 
                        bool InScrollBar {
@@ -2210,7 +2463,7 @@ namespace System.Windows.Forms
                        }
 
                        protected override void OnMouseMove (MouseEventArgs e)
-                       {                                               
+                       {
                                if (owner.DropDownStyle == ComboBoxStyle.Simple)
                                        return;
 
@@ -2222,13 +2475,13 @@ namespace System.Windows.Forms
                                Point pt = PointToClient (Control.MousePosition);
                                int index = IndexFromPointDisplayRectangle (pt.X, pt.Y);
 
-                               if (index != -1)
+                               if (index != -1)
                                        HighlightedIndex = index;
                        }
                        
                        protected override void OnMouseUp (MouseEventArgs e)
                        {
-                               int index = IndexFromPointDisplayRectangle (e.X, e.Y);
+                               int index = IndexFromPointDisplayRectangle (e.X, e.Y);
 
                                if (scrollbar_grabbed) {
                                        vscrollbar_ctrl.FireMouseUp (e);
@@ -2238,8 +2491,8 @@ namespace System.Windows.Forms
                                        return;
                                }
 
-                               if (index == -1) {                                      
-                                       HideWindow ();
+                               if (index == -1) {
+                                       HideWindow ();
                                        return;
                                }
 
@@ -2249,7 +2502,7 @@ namespace System.Windows.Forms
                        }
 
                        internal override void OnPaintInternal (PaintEventArgs pevent)
-                       {                               
+                       {
                                Draw (pevent.ClipRectangle,pevent.Graphics);
                        }
 
@@ -2260,7 +2513,7 @@ namespace System.Windows.Forms
 
                                HighlightedIndex = owner.SelectedIndex;
 
-                               CalcListBoxArea ();                             
+                               CalcListBoxArea ();
                                Show ();
 
                                Refresh ();
@@ -2278,7 +2531,7 @@ namespace System.Windows.Forms
                                if (delta == 0 || vscrollbar_ctrl == null || !vscrollbar_ctrl.Visible)
                                        return;
 
-                               int max = owner.Items.Count - page_size;
+                               int max = vscrollbar_ctrl.Maximum - page_size + 1;
 
                                int val = vscrollbar_ctrl.Value + delta;
                                if (val > max)
@@ -2299,20 +2552,18 @@ namespace System.Windows.Forms
 
                        // Value Changed
                        private void VerticalScrollEvent (object sender, EventArgs e)
-                       {                               
+                       {
                                if (top_item == vscrollbar_ctrl.Value)
                                        return;
 
                                top_item =  vscrollbar_ctrl.Value;
                                UpdateLastVisibleItem ();
                                Invalidate ();
-                       }                       
+                       }
                        
                        protected override void WndProc(ref Message m) {
                                if (m.Msg == (int)Msg.WM_SETFOCUS) {
-                                       if (m.WParam != IntPtr.Zero) {
-                                               XplatUI.SetFocus(m.WParam);
-                                       }
+                                       owner.Select (false, true);
                                }
                                base.WndProc (ref m);
                        }
@@ -2321,5 +2572,3 @@ namespace System.Windows.Forms
                }
        }
 }
-
-