Fixed bug where using ResXResourceWriter filename ctor caused corrupted output
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / TextBox.cs
index 5c592244d01b4c178933bccd59f6c5ce9e75dc38..d7c548ca0a2aa00a52e785e6e8ff86c1fcaeb61c 100644 (file)
 // NOT COMPLETE
 
 using System;
+using System.Collections;
 using System.ComponentModel;
 using System.ComponentModel.Design;
 using System.Drawing;
-#if NET_2_0
+using System.Collections.Generic;
 using System.Runtime.InteropServices;
-#endif
 
 namespace System.Windows.Forms {
 
-#if NET_2_0
        [ComVisible(true)]
        [ClassInterface (ClassInterfaceType.AutoDispatch)]
        [Designer ("System.Windows.Forms.Design.TextBoxDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
-#endif
        public class TextBox : TextBoxBase {
                #region Variables
                private ContextMenu     menu;
@@ -51,12 +49,15 @@ namespace System.Windows.Forms {
                private MenuItem        delete;
                private MenuItem        select_all;
 
-#if NET_2_0
-               private bool use_system_password_char = false;
-               private AutoCompleteStringCollection auto_complete_custom_source = null;
+               private bool use_system_password_char;
+               private AutoCompleteStringCollection auto_complete_custom_source;
                private AutoCompleteMode auto_complete_mode = AutoCompleteMode.None;
                private AutoCompleteSource auto_complete_source = AutoCompleteSource.None;
-#endif
+               private AutoCompleteListBox auto_complete_listbox;
+               private string auto_complete_original_text;
+               private int auto_complete_selected_index = -1;
+               private List<string> auto_complete_matches;
+               private ComboBox auto_complete_cb_source;
                #endregion      // Variables
 
                #region Public Constructors
@@ -66,6 +67,7 @@ namespace System.Windows.Forms {
                        alignment = HorizontalAlignment.Left;
                        this.LostFocus +=new EventHandler(TextBox_LostFocus);
                        this.RightToLeftChanged += new EventHandler (TextBox_RightToLeftChanged);
+                       MouseWheel += new MouseEventHandler (TextBox_MouseWheel);
 
                        BackColor = SystemColors.Window;
                        ForeColor = SystemColors.WindowText;
@@ -104,9 +106,217 @@ namespace System.Windows.Forms {
                        UpdateAlignment ();
                }
 
-               private void TextBox_LostFocus(object sender, EventArgs e) {
+               private void TextBox_LostFocus (object sender, EventArgs e) {
                        if (hide_selection)
                                document.InvalidateSelectionArea ();
+                       if (auto_complete_listbox != null && auto_complete_listbox.Visible)
+                               auto_complete_listbox.HideListBox (false);
+               }
+
+               private void TextBox_MouseWheel (object o, MouseEventArgs args)
+               {
+                       if (auto_complete_listbox == null || !auto_complete_listbox.Visible)
+                               return;
+
+                       int lines = args.Delta / 120;
+                       auto_complete_listbox.Scroll (-lines);
+               }
+
+               // Receives either WM_KEYDOWN or WM_CHAR that will likely need the generation/lookup
+               // of new matches
+               private void ProcessAutoCompleteInput (ref Message m, bool deleting_chars)
+               {
+                       // Need to call base.WndProc before to have access to
+                       // the updated Text property value
+                       base.WndProc (ref m);
+                       auto_complete_original_text = Text;
+                       ShowAutoCompleteListBox (deleting_chars);
+               }
+
+               private void ShowAutoCompleteListBox (bool deleting_chars)
+               {
+                       // 
+                       // We only support CustomSource by now
+                       //
+
+                       IList source = auto_complete_cb_source == null ? auto_complete_custom_source : (IList)auto_complete_cb_source.Items;
+
+                       bool append = auto_complete_mode == AutoCompleteMode.Append || auto_complete_mode == AutoCompleteMode.SuggestAppend;
+                       bool suggest = auto_complete_mode == AutoCompleteMode.Suggest || auto_complete_mode == AutoCompleteMode.SuggestAppend;
+
+                       if (Text.Length == 0) {
+                               if (auto_complete_listbox != null)
+                                       auto_complete_listbox.HideListBox (false);
+                               return;
+                       }
+
+                       if (auto_complete_matches == null)
+                               auto_complete_matches = new List<string> ();
+
+                       string text = Text;
+                       auto_complete_matches.Clear ();
+
+                       for (int i = 0; i < source.Count; i++) {
+                               string item_text = auto_complete_cb_source == null ? auto_complete_custom_source [i] :
+                                       auto_complete_cb_source.GetItemText (auto_complete_cb_source.Items [i]);
+                               if (item_text.StartsWith (text, StringComparison.CurrentCultureIgnoreCase))
+                                       auto_complete_matches.Add (item_text);
+                       }
+
+                       auto_complete_matches.Sort ();
+
+                       // Return if we have a single exact match
+                       if ((auto_complete_matches.Count == 0) || (auto_complete_matches.Count == 1 && 
+                                               auto_complete_matches [0].Equals (text, StringComparison.CurrentCultureIgnoreCase))) {
+
+                               if (auto_complete_listbox != null && auto_complete_listbox.Visible)
+                                       auto_complete_listbox.HideListBox (false);
+                               return;
+                       }
+
+                       auto_complete_selected_index = suggest ? -1 : 0;
+
+                       if (suggest) {
+                               if (auto_complete_listbox == null)
+                                       auto_complete_listbox = new AutoCompleteListBox (this);
+
+                               // Show or update auto complete listbox contents
+                               auto_complete_listbox.Location = PointToScreen (new Point (0, Height));
+                               auto_complete_listbox.ShowListBox ();
+                       }
+
+                       if (append && !deleting_chars)
+                               AppendAutoCompleteMatch (0);
+
+                       document.MoveCaret (CaretDirection.End);
+               }
+
+               internal void HideAutoCompleteList ()
+               {
+                       if (auto_complete_listbox != null)
+                               auto_complete_listbox.HideListBox (false);
+               }
+
+               internal bool IsAutoCompleteAvailable {
+                       get {
+                               if (auto_complete_source == AutoCompleteSource.None || auto_complete_mode == AutoCompleteMode.None)
+                                       return false;
+
+                               // We only support CustomSource by now, as well as an internal custom source used by ComboBox
+                               if (auto_complete_source != AutoCompleteSource.CustomSource)
+                                       return false;
+                               IList custom_source = auto_complete_cb_source == null ? auto_complete_custom_source : (IList)auto_complete_cb_source.Items;
+                               if (custom_source == null || custom_source.Count == 0)
+                                       return false;
+
+                               return true;
+                       }
+               }
+
+               internal ComboBox AutoCompleteInternalSource {
+                       get {
+                               return auto_complete_cb_source;
+                       }
+                       set {
+                               auto_complete_cb_source = value;
+                       }
+               }
+
+               internal bool CanNavigateAutoCompleteList {
+                       get {
+                               if (auto_complete_mode == AutoCompleteMode.None)
+                                       return false;
+                               if (auto_complete_matches == null || auto_complete_matches.Count == 0)
+                                       return false;
+
+                               bool suggest_window_visible = auto_complete_listbox != null && auto_complete_listbox.Visible;
+                               if (auto_complete_mode == AutoCompleteMode.Suggest && !suggest_window_visible)
+                                       return false;
+
+                               return true;
+                       }
+               }
+
+               bool NavigateAutoCompleteList (Keys key)
+               {
+                       if (auto_complete_matches == null || auto_complete_matches.Count == 0)
+                               return false;
+
+                       bool suggest_window_visible = auto_complete_listbox != null && auto_complete_listbox.Visible;
+                       if (!suggest_window_visible && auto_complete_mode == AutoCompleteMode.Suggest)
+                               return false;
+
+                       int index = auto_complete_selected_index;
+
+                       switch (key) {
+                               case Keys.Up:
+                                       index -= 1;
+                                       if (index < -1)
+                                               index = auto_complete_matches.Count - 1;
+                                       break;
+                               case Keys.Down:
+                                       index += 1;
+                                       if (index >= auto_complete_matches.Count)
+                                               index = -1;
+                                       break;
+                               case Keys.PageUp:
+                                       if (auto_complete_mode == AutoCompleteMode.Append || !suggest_window_visible)
+                                               goto case Keys.Up;
+
+                                       if (index == -1)
+                                               index = auto_complete_matches.Count - 1;
+                                       else if (index == 0)
+                                               index = -1;
+                                       else {
+                                               index -= auto_complete_listbox.page_size - 1;
+                                               if (index < 0)
+                                                       index = 0;
+                                       }
+                                       break;
+                               case Keys.PageDown:
+                                       if (auto_complete_mode == AutoCompleteMode.Append || !suggest_window_visible)
+                                               goto case Keys.Down;
+
+                                       if (index == -1)
+                                               index = 0;
+                                       else if (index == auto_complete_matches.Count - 1)
+                                               index = -1;
+                                       else {
+                                               index += auto_complete_listbox.page_size - 1;
+                                               if (index >= auto_complete_matches.Count)
+                                                       index = auto_complete_matches.Count - 1;
+                                       }
+                                       break;
+                               default:
+                                       break;
+                       }
+
+                       // In SuggestAppend mode the navigation mode depends on the visibility of the suggest lb.
+                       bool suggest = auto_complete_mode == AutoCompleteMode.Suggest || auto_complete_mode == AutoCompleteMode.SuggestAppend;
+                       if (suggest && suggest_window_visible) {
+                               Text = index == -1 ? auto_complete_original_text : auto_complete_matches [index];
+                               auto_complete_listbox.HighlightedIndex = index;
+                       } else
+                               // Append only, not suggest at all
+                               AppendAutoCompleteMatch (index < 0 ? 0 : index);
+                               
+                       auto_complete_selected_index = index;
+                       document.MoveCaret (CaretDirection.End);
+
+                       return true;
+               }
+
+               void AppendAutoCompleteMatch (int index)
+               {
+                       Text = auto_complete_original_text + auto_complete_matches [index].Substring (auto_complete_original_text.Length);
+                       SelectionStart = auto_complete_original_text.Length;
+                       SelectionLength = auto_complete_matches [index].Length - auto_complete_original_text.Length;
+               }
+
+               // this is called when the user selects a value from the autocomplete list
+               // *with* the mouse
+               internal virtual void OnAutoCompleteValueSelected (EventArgs args)
+               {
                }
 
                private void UpdateAlignment ()
@@ -144,28 +354,23 @@ namespace System.Windows.Forms {
                internal override Color ChangeBackColor (Color backColor)
                {
                        if (backColor == Color.Empty) {
-#if NET_2_0
                                if (!ReadOnly)
                                        backColor = SystemColors.Window;
-#else
-                               backColor = SystemColors.Window;
-#endif
+
                                backcolor_set = false;
                        }
+
                        return backColor;
                }
 
-#if NET_2_0
                void OnAutoCompleteCustomSourceChanged(object sender, CollectionChangeEventArgs e) {
                        if(auto_complete_source == AutoCompleteSource.CustomSource) {
                                //FIXME: handle add, remove and refresh events in AutoComplete algorithm.
                        }
                }
-#endif
                #endregion      // Private & Internal Methods
 
                #region Public Instance Properties
-#if NET_2_0
                [MonoTODO("AutoCompletion algorithm is currently not implemented.")]
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
                [Browsable (true)]
@@ -244,11 +449,11 @@ namespace System.Windows.Forms {
                                        if (!Multiline)
                                                document.PasswordChar = PasswordChar.ToString ();
                                        else
-                                               document.PasswordChar = "";
+                                               document.PasswordChar = string.Empty;
+                                       Invalidate ();
                                }
                        }
                }
-#endif
 
                [DefaultValue(false)]
                [MWFCategory("Behavior")]
@@ -260,7 +465,7 @@ namespace System.Windows.Forms {
                        set {
                                if (value != accepts_return) {
                                        accepts_return = value;
-                               }       
+                               }
                        }
                }
 
@@ -281,16 +486,12 @@ namespace System.Windows.Forms {
                [Localizable(true)]
                [DefaultValue('\0')]
                [MWFCategory("Behavior")]
-#if NET_2_0
                [RefreshProperties (RefreshProperties.Repaint)]
-#endif
                public char PasswordChar {
                        get {
-#if NET_2_0
                                if (use_system_password_char) {
                                        return '*';
                                }
-#endif
                                return password_char;
                        }
 
@@ -300,7 +501,7 @@ namespace System.Windows.Forms {
                                        if (!Multiline) {
                                                document.PasswordChar = PasswordChar.ToString ();
                                        } else {
-                                               document.PasswordChar = "";
+                                               document.PasswordChar = string.Empty;
                                        }
                                        this.CalculateDocument();
                                }
@@ -327,19 +528,6 @@ namespace System.Windows.Forms {
                        }
                }
 
-#if ONLY_1_1
-               [Browsable(false)]
-               [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
-               public override int SelectionLength {
-                       get {
-                               return base.SelectionLength;
-                       }
-                       set {
-                               base.SelectionLength = value;
-                       }
-               }
-#endif
-
                public override string Text {
                        get {
                                return base.Text;
@@ -370,7 +558,6 @@ namespace System.Windows.Forms {
                }
                #endregion      // Public Instance Properties
 
-#if NET_2_0
                public void Paste (string text)
                {
                        document.ReplaceSelection (CaseAdjust (text), false);
@@ -378,7 +565,6 @@ namespace System.Windows.Forms {
                        ScrollToCaret();
                        OnTextChanged(EventArgs.Empty);
                }
-#endif
                #region Protected Instance Methods
                protected override CreateParams CreateParams {
                        get {
@@ -386,49 +572,81 @@ namespace System.Windows.Forms {
                        }
                }
 
-#if ONLY_1_1
-               protected override ImeMode DefaultImeMode {
-                       get {
-                               return base.DefaultImeMode;
-                       }
-               }
-#endif
-#if NET_2_0
                protected override void Dispose (bool disposing)
                {
                        base.Dispose (disposing);
                }
-#endif
 
-               protected override bool IsInputKey(Keys keyData) {
+               protected override bool IsInputKey (Keys keyData)
+               {
                        return base.IsInputKey (keyData);
                }
 
-               protected override void OnGotFocus(EventArgs e) {
+               protected override void OnGotFocus (EventArgs e)
+               {
                        base.OnGotFocus (e);
                        if (selection_length == -1 && !has_been_focused)
                                SelectAllNoScroll ();
                        has_been_focused = true;
                }
 
-               protected override void OnHandleCreated(EventArgs e) {
+               protected override void OnHandleCreated (EventArgs e)
+               {
                        base.OnHandleCreated (e);
                }
 
-#if ONLY_1_1
-               protected override void OnMouseUp(MouseEventArgs e) {
-                       base.OnMouseUp (e);
-               }
-#endif
-
-               protected virtual void OnTextAlignChanged(EventArgs e) {
+               protected virtual void OnTextAlignChanged (EventArgs e)
+               {
                        EventHandler eh = (EventHandler)(Events [TextAlignChangedEvent]);
                        if (eh != null)
                                eh (this, e);
                }
 
-               protected override void WndProc(ref Message m) {
+               protected override void WndProc (ref Message m)
+               {
                        switch ((Msg)m.Msg) {
+                               case Msg.WM_KEYDOWN:
+                                       if (!IsAutoCompleteAvailable)
+                                               break;
+
+                                       Keys key_data = (Keys)m.WParam.ToInt32 ();
+                                       switch (key_data) {
+                                               case Keys.Down:
+                                               case Keys.Up:
+                                               case Keys.PageDown:
+                                               case Keys.PageUp:
+                                                       if (NavigateAutoCompleteList (key_data)) {
+                                                               m.Result = IntPtr.Zero;
+                                                               return;
+                                                       }
+                                                       break;
+                                               case Keys.Enter:
+                                                       if (auto_complete_listbox != null && auto_complete_listbox.Visible)
+                                                               auto_complete_listbox.HideListBox (false);
+                                                       SelectAll ();
+                                                       break;
+                                               case Keys.Escape:
+                                                       if (auto_complete_listbox != null && auto_complete_listbox.Visible)
+                                                               auto_complete_listbox.HideListBox (false);
+                                                       break;
+                                               case Keys.Delete:
+                                                       ProcessAutoCompleteInput (ref m, true);
+                                                       return;
+                                               default:
+                                                       break;
+                                       }
+                                       break;
+                               case Msg.WM_CHAR:
+                                       if (!IsAutoCompleteAvailable)
+                                               break;
+
+                                       // Don't handle either Enter or Esc - they are handled in the WM_KEYDOWN case
+                                       int char_value = m.WParam.ToInt32 ();
+                                       if (char_value == 13 || char_value == 27)
+                                               break;
+
+                                       ProcessAutoCompleteInput (ref m, char_value == 8);
+                                       return;
                                case Msg.WM_LBUTTONDOWN:
                                        // When the textbox gets focus by LBUTTON (but not by middle or right)
                                        // it does not do the select all / scroll thing.
@@ -464,6 +682,11 @@ namespace System.Windows.Forms {
                        }
                }
 
+               internal void RestoreContextMenu ()
+               {
+                       ContextMenuInternal = menu;
+               }
+
                private void menu_Popup(object sender, EventArgs e) {
                        if (SelectionLength == 0) {
                                cut.Enabled = false;
@@ -507,7 +730,7 @@ namespace System.Windows.Forms {
                }
 
                private void delete_Click(object sender, EventArgs e) {
-                       SelectedText = "";
+                       SelectedText = string.Empty;
                }
 
                private void select_all_Click(object sender, EventArgs e) {
@@ -515,7 +738,6 @@ namespace System.Windows.Forms {
                }
                #endregion      // Private Methods
 
-#if NET_2_0
                public override bool Multiline {
                        get {
                                return base.Multiline;
@@ -540,12 +762,291 @@ namespace System.Windows.Forms {
                {
                        base.OnHandleDestroyed (e);
                }
-#endif
+
+               class AutoCompleteListBox : Control
+               {
+                       TextBox owner;
+                       VScrollBar vscroll;
+                       int top_item;
+                       int last_item;
+                       internal int page_size;
+                       int item_height;
+                       int highlighted_index = -1;
+                       bool user_defined_size;
+                       bool resizing;
+                       Rectangle resizer_bounds;
+
+                       const int DefaultDropDownItems = 7;
+
+                       public AutoCompleteListBox (TextBox tb)
+                       {
+                               owner = tb;
+                               item_height = FontHeight + 2;
+
+                               vscroll = new VScrollBar ();
+                               vscroll.ValueChanged += VScrollValueChanged;
+                               Controls.Add (vscroll);
+
+                               is_visible = false;
+                               InternalBorderStyle = BorderStyle.FixedSingle;
+                       }
+
+                       protected override CreateParams CreateParams {
+                               get {
+                                       CreateParams cp = base.CreateParams;
+
+                                       cp.Style ^= (int)WindowStyles.WS_CHILD;
+                                       cp.Style ^= (int)WindowStyles.WS_VISIBLE;
+                                       cp.Style |= (int)WindowStyles.WS_POPUP;
+                                       cp.ExStyle |= (int)WindowExStyles.WS_EX_TOPMOST | (int)WindowExStyles.WS_EX_TOOLWINDOW;
+                                       return cp;
+                               }
+                       }
+
+                       public int HighlightedIndex {
+                               get {
+                                       return highlighted_index;
+                               }
+                               set {
+                                       if (value == highlighted_index)
+                                               return;
+
+                                       if (highlighted_index != -1)
+                                               Invalidate (GetItemBounds (highlighted_index));
+                                       highlighted_index = value;
+                                       if (highlighted_index != -1)
+                                               Invalidate (GetItemBounds (highlighted_index));
+
+                                       if (highlighted_index != -1)
+                                               EnsureVisible (highlighted_index);
+                               }
+                       }
+
+                       public void Scroll (int lines)
+                       {
+                               int max = vscroll.Maximum - page_size + 1;
+                               int val = vscroll.Value + lines;
+                               if (val > max)
+                                       val = max;
+                               else if (val < vscroll.Minimum)
+                                       val = vscroll.Minimum;
+
+                               vscroll.Value = val;
+                       }
+
+                       public void EnsureVisible (int index)
+                       {
+                               if (index < top_item) {
+                                       vscroll.Value = index;
+                               } else {
+                                       int max = vscroll.Maximum - page_size + 1;
+                                       int rows = Height / item_height;
+                                       if (index > top_item + rows - 1) {
+                                               index = index - rows + 1;
+                                               vscroll.Value = index > max ? max : index;
+                                       }
+                               }
+                       }
+
+                       internal override bool ActivateOnShow {
+                               get {
+                                       return false;
+                               }
+                       }
+
+                       void VScrollValueChanged (object o, EventArgs args)
+                       {
+                               if (top_item == vscroll.Value)
+                                       return;
+
+                               top_item = vscroll.Value;
+                               last_item = GetLastVisibleItem ();
+                               Invalidate ();
+                       }
+
+                       int GetLastVisibleItem ()
+                       {
+                               int top_y = Height;
+
+                               for (int i = top_item; i < owner.auto_complete_matches.Count; i++) {
+                                       int pos = i - top_item; // relative to visible area
+                                       if ((pos * item_height) + item_height >= top_y)
+                                               return i;
+                               }
+
+                               return owner.auto_complete_matches.Count - 1;
+                       }
+
+                       Rectangle GetItemBounds (int index)
+                       {
+                               int pos = index - top_item;
+                               Rectangle bounds = new Rectangle (0, pos * item_height, Width, item_height);
+                               if (vscroll.Visible)
+                                       bounds.Width -= vscroll.Width;
+
+                               return bounds;
+                       }
+
+                       int GetItemAt (Point loc)
+                       {
+                               if (loc.Y > (last_item - top_item) * item_height + item_height)
+                                       return -1;
+
+                               int retval = loc.Y / item_height;
+                               retval += top_item;
+
+                               return retval;
+                       }
+
+                       void LayoutListBox ()
+                       {
+                               int total_height = owner.auto_complete_matches.Count * item_height;
+                               page_size = Math.Max (Height / item_height, 1);
+                               last_item = GetLastVisibleItem ();
+
+                               if (Height < total_height) {
+                                       vscroll.Visible = true;
+                                       vscroll.Maximum = owner.auto_complete_matches.Count - 1;
+                                       vscroll.LargeChange = page_size;
+                                       vscroll.Location = new Point (Width - vscroll.Width, 0);
+                                       vscroll.Height = Height - item_height;
+                               } else
+                                       vscroll.Visible = false;
+
+                               resizer_bounds = new Rectangle (Width - item_height, Height - item_height,
+                                               item_height, item_height);
+                       }
+
+                       public void HideListBox (bool set_text)
+                       {
+                               if (set_text)
+                                       owner.Text = owner.auto_complete_matches [HighlightedIndex];
+
+                               Capture = false;
+                               Hide ();
+                       }
+
+                       public void ShowListBox ()
+                       {
+                               if (!user_defined_size) {
+                                       // This should call the Layout routine for us
+                                       int height = owner.auto_complete_matches.Count > DefaultDropDownItems ? 
+                                               DefaultDropDownItems * item_height : (owner.auto_complete_matches.Count + 1) * item_height;
+                                       Size = new Size (owner.Width, height);
+                               } else
+                                       LayoutListBox ();
+
+                               vscroll.Value = 0;
+                               HighlightedIndex = -1;
+
+                               Show ();
+                               // make sure we are on top - call the raw routine, since we are parentless
+                               XplatUI.SetZOrder (Handle, IntPtr.Zero, true, false);
+                               Invalidate ();
+                       }
+
+                       protected override void OnResize (EventArgs args)
+                       {
+                               base.OnResize (args);
+
+                               LayoutListBox ();
+                               Refresh ();
+                       }
+
+                       protected override void OnMouseDown (MouseEventArgs args)
+                       {
+                               base.OnMouseDown (args);
+
+                               if (!resizer_bounds.Contains (args.Location))
+                                       return;
+
+                               user_defined_size = true;
+                               resizing = true;
+                               Capture = true;
+                       }
+
+                       protected override void OnMouseMove (MouseEventArgs args)
+                       {
+                               base.OnMouseMove (args);
+
+                               if (resizing) {
+                                       Point mouse_loc = Control.MousePosition;
+                                       Point ctrl_loc = PointToScreen (Point.Empty);
+
+                                       Size new_size = new Size (mouse_loc.X - ctrl_loc.X, mouse_loc.Y - ctrl_loc.Y);
+                                       if (new_size.Height < item_height)
+                                               new_size.Height = item_height;
+                                       if (new_size.Width < item_height)
+                                               new_size.Width = item_height;
+
+                                       Size = new_size;
+                                       return;
+                               }
+
+                               Cursor = resizer_bounds.Contains (args.Location) ? Cursors.SizeNWSE : Cursors.Default;
+
+                               int item_idx = GetItemAt (args.Location);
+                               if (item_idx != -1)
+                                       HighlightedIndex = item_idx;
+                       }
+
+                       protected override void OnMouseUp (MouseEventArgs args)
+                       {
+                               base.OnMouseUp (args);
+
+                               int item_idx = GetItemAt (args.Location);
+                               if (item_idx != -1 && !resizing)
+                                       HideListBox (true);
+
+                               owner.OnAutoCompleteValueSelected (EventArgs.Empty); // internal
+                               resizing = false;
+                               Capture = false;
+                       }
+
+                       internal override void OnPaintInternal (PaintEventArgs args)
+                       {
+                               Graphics g = args.Graphics;
+                               Brush brush = ThemeEngine.Current.ResPool.GetSolidBrush (ForeColor);
+
+                               int highlighted_idx = HighlightedIndex;
+
+                               int y = 0;
+                               int last = GetLastVisibleItem ();
+                               for (int i = top_item; i <= last; i++) {
+                                       Rectangle item_bounds = GetItemBounds (i);
+                                       if (!item_bounds.IntersectsWith (args.ClipRectangle))
+                                               continue;
+
+                                       if (i == highlighted_idx) {
+                                               g.FillRectangle (SystemBrushes.Highlight, item_bounds);
+                                               g.DrawString (owner.auto_complete_matches [i], Font, SystemBrushes.HighlightText, item_bounds);
+                                       } else 
+                                               g.DrawString (owner.auto_complete_matches [i], Font, brush, item_bounds);
+
+                                       y += item_height;
+                               }
+
+                               ThemeEngine.Current.CPDrawSizeGrip (g, SystemColors.Control, resizer_bounds);
+                       }
+               }
        }
        
-#if NET_2_0
-       internal class TextBoxAutoCompleteSourceConverter : TypeConverter
+       internal class TextBoxAutoCompleteSourceConverter : EnumConverter
        {
+               public TextBoxAutoCompleteSourceConverter(Type type)
+                       : base(type)
+               { }
+
+               public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
+               {
+                       StandardValuesCollection stdv = base.GetStandardValues(context);
+                       AutoCompleteSource[] arr = new AutoCompleteSource[stdv.Count];
+                       stdv.CopyTo(arr, 0);
+                       AutoCompleteSource[] arr2 = Array.FindAll(arr, delegate (AutoCompleteSource value) {
+                               // No "ListItems" in a TextBox.
+                               return value != AutoCompleteSource.ListItems;
+                       });
+                       return new StandardValuesCollection(arr2);
+               }
        }
-#endif
 }