Merge pull request #943 from ermshiperete/bug-novell-325669
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / ComboBox.cs
index 3d038b35706b08e11fd360b916a7238ca9e5e6a5..fad6981b745964226a9ff363374068cfde4946ef 100644 (file)
@@ -33,6 +33,7 @@ using System.Drawing;
 using System.Globalization;
 using System.Reflection;
 using System.Runtime.InteropServices;
+using System.Diagnostics;
 
 namespace System.Windows.Forms
 {
@@ -746,22 +747,22 @@ namespace System.Windows.Forms
                                        return;
                                }
 
-                               // 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;
+                               // don't set the index if value exactly matches text of selected item
+                               if (SelectedItem == null || string.Compare (value, GetItemText (SelectedItem), false, CultureInfo.CurrentCulture) != 0)
+                               {
+                                       // 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;
+                                       }
                                }
 
-                               // set directly the passed value, since we already know it's not matching any item
+                               // set directly the passed value
                                if (dropdown_style != ComboBoxStyle.DropDownList)
                                        textbox_ctrl.Text = value;
                        }
@@ -949,6 +950,29 @@ namespace System.Windows.Forms
                        base.OnDataSourceChanged (e);
                        BindDataItems ();
                        
+                       /** 
+                        ** This 'Debugger.IsAttached' hack is here because of
+                        ** Xamarin Bug #2234, which noted that when changing
+                        ** the DataSource, in Windows exceptions are eaten
+                        ** when SelectedIndexChanged is fired.  However, when
+                        ** the debugger is running (i.e. in MonoDevelop), we
+                        ** want to be alerted of exceptions.
+                        **/
+
+                       if (Debugger.IsAttached) {
+                               SetSelectedIndex ();
+                       } else {
+                               try {
+                                       SetSelectedIndex ();
+                               } catch {
+                                       //ignore exceptions here per 
+                                       //bug 2234
+                               }
+                       }
+               }
+
+               private void SetSelectedIndex ()
+               {
                        if (DataSource == null || DataManager == null) {
                                SelectedIndex = -1;
                        } 
@@ -1976,8 +2000,10 @@ namespace System.Windows.Forms
                                        if (index == owner.SelectedIndex) {
                                                if (owner.textbox_ctrl == null)
                                                        owner.Refresh ();
-                                               else
-                                                       owner.textbox_ctrl.SelectedText = value.ToString ();
+                                               else {
+                                                       owner.textbox_ctrl.Text = value.ToString ();
+                                                       owner.textbox_ctrl.SelectAll ();
+                                               }
                                        }
                                }
                        }
@@ -2091,11 +2117,9 @@ namespace System.Windows.Forms
                        {
                                if (value == null)
                                        return;
-
-                               if (IndexOf (value) == owner.SelectedIndex)
-                                       owner.SelectedIndex = -1;
-                               
-                               RemoveAt (IndexOf (value));
+                               int index = IndexOf (value);
+                               if (index >= 0)
+                                       RemoveAt (index);
                        }
 
                        public void RemoveAt (int index)
@@ -2103,7 +2127,9 @@ namespace System.Windows.Forms
                                if (index < 0 || index >= Count)
                                        throw new ArgumentOutOfRangeException ("index");
                                        
-                               if (index == owner.SelectedIndex)
+                               if (index < owner.SelectedIndex)
+                                       --owner.SelectedIndex;
+                               else if (index == owner.SelectedIndex)
                                        owner.SelectedIndex = -1;
 
                                object removed = object_items [index];
@@ -2289,7 +2315,16 @@ namespace System.Windows.Forms
                                        return owner.Focused;
                                }
                        }
-                       
+                       protected override void Dispose(bool disposing)
+                       {
+                               if (disposing ) {
+                                       // Prevents corruption of combobox text by disposed object
+                                       owner.EnabledChanged -= OwnerEnabledChangedHandler;
+                                       owner.LostFocus -= OwnerLostFocusHandler;
+                               }
+                               base.Dispose(disposing);
+                       }
+
                        internal override bool ActivateOnShow { get { return false; } }
                }
 
@@ -2498,12 +2533,14 @@ namespace System.Windows.Forms
                                                vscrollbar_ctrl.Value = hli;
                                        }
                                }
-                               
-                               Size = new Size (width, height);
-                               textarea_drawable = ClientRectangle;
-                               textarea_drawable.Width = width;
-                               textarea_drawable.Height = height;
-                               
+
+                               var borderWidth = Hwnd.GetBorderWidth (CreateParams);
+                               var borderAdjustment = dropdown_style == ComboBoxStyle.Simple ? new Size (0, 0) :
+                                       new Size (borderWidth.top + borderWidth.bottom, borderWidth.left + borderWidth.right);
+                               Size = new Size (width, height + borderAdjustment.Height);
+                               textarea_drawable = new Rectangle (ClientRectangle.Location,
+                                       new Size (width - borderAdjustment.Width, height));
+
                                if (vscrollbar_ctrl != null && show_scrollbar)
                                        textarea_drawable.Width -= vscrollbar_ctrl.Width;
 
@@ -2731,6 +2768,10 @@ namespace System.Windows.Forms
                                HighlightedIndex = owner.SelectedIndex;
 
                                CalcListBoxArea ();
+                               // If the listbox would extend below the screen, move it above the textbox.
+                               Rectangle scrn_rect = Screen.FromControl (owner).Bounds;
+                               if (this.Location.Y + this.Height >= scrn_rect.Bottom)
+                                       this.Location = new Point (this.Location.X, this.Location.Y - (this.Height + owner.TextArea.Height));
                                Show ();
 
                                Refresh ();