// Authors:
// Jordi Mas i Hernandez, jordi@ximian.com
// Mike Kestner <mkestner@novell.com>
-//
-// NOT COMPLETE
+// Daniel Nauck (dna(at)mono-project(dot)de)
using System;
using System.Drawing;
namespace System.Windows.Forms
{
-
[DefaultProperty("Items")]
[DefaultEvent("SelectedIndexChanged")]
[Designer ("System.Windows.Forms.Design.ComboBoxDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
+#if NET_2_0
+ [DefaultBindingProperty ("Text")]
+ [ClassInterface (ClassInterfaceType.AutoDispatch)]
+ [ComVisible(true)]
+#endif
public class ComboBox : ListControl
{
private DrawMode draw_mode = DrawMode.Normal;
private ComboBoxStyle dropdown_style = (ComboBoxStyle)(-1);
private int dropdown_width = -1;
- private object selected_item = null;
+ private int selected_index = -1;
internal ObjectCollection items = null;
private bool suspend_ctrlupdate;
private int maxdrop_items = 8;
private bool sorted;
private int max_length;
private ComboListBox listbox_ctrl;
- private TextBox textbox_ctrl;
+ private ComboTextBox textbox_ctrl;
private bool process_textchanged_event = true;
private bool item_height_specified = false;
private int item_height;
private Rectangle button_area;
private Rectangle listbox_area;
private const int button_width = 16;
+#if NET_2_0
+ private AutoCompleteStringCollection auto_complete_custom_source = null;
+ private AutoCompleteMode auto_complete_mode = AutoCompleteMode.None;
+ private AutoCompleteSource auto_complete_source = AutoCompleteSource.None;
+#endif
[ComVisible(true)]
public class ChildAccessibleObject : AccessibleObject {
- private ComboBox owner;
- private IntPtr handle;
- public ChildAccessibleObject (ComboBox owner, IntPtr handle) {
- this.owner = owner;
- this.handle = handle;
+ public ChildAccessibleObject (ComboBox owner, IntPtr handle)
+ : base (owner)
+ {
}
public override string Name {
MouseDown += new MouseEventHandler (OnMouseDownCB);
MouseUp += new MouseEventHandler (OnMouseUpCB);
MouseMove += new MouseEventHandler (OnMouseMoveCB);
+ MouseWheel += new MouseEventHandler (OnMouseWheelCB);
KeyDown +=new KeyEventHandler(OnKeyDownCB);
}
add { base.BackgroundImageChanged += value; }
remove { base.BackgroundImageChanged -= value; }
}
-
- public event DrawItemEventHandler DrawItem;
- public event EventHandler DropDown;
- public event EventHandler DropDownStyleChanged;
- public event MeasureItemEventHandler MeasureItem;
+
+ static object DrawItemEvent = new object ();
+ static object DropDownEvent = new object ();
+ static object DropDownStyleChangedEvent = new object ();
+ static object MeasureItemEvent = new object ();
+ static object SelectedIndexChangedEvent = new object ();
+ static object SelectionChangeCommittedEvent = new object ();
+
+ public event DrawItemEventHandler DrawItem {
+ add { Events.AddHandler (DrawItemEvent, value); }
+ remove { Events.RemoveHandler (DrawItemEvent, value); }
+ }
+
+ public event EventHandler DropDown {
+ add { Events.AddHandler (DropDownEvent, value); }
+ remove { Events.RemoveHandler (DropDownEvent, value); }
+ }
+
+ public event EventHandler DropDownStyleChanged {
+ add { Events.AddHandler (DropDownStyleChangedEvent, value); }
+ remove { Events.RemoveHandler (DropDownStyleChangedEvent, value); }
+ }
+
+ public event MeasureItemEventHandler MeasureItem {
+ add { Events.AddHandler (MeasureItemEvent, value); }
+ remove { Events.RemoveHandler (MeasureItemEvent, value); }
+ }
[Browsable (false)]
[EditorBrowsable (EditorBrowsableState.Never)]
remove { base.Paint -= value; }
}
- public event EventHandler SelectedIndexChanged;
- public event EventHandler SelectionChangeCommitted;
+ public event EventHandler SelectedIndexChanged {
+ add { Events.AddHandler (SelectedIndexChangedEvent, value); }
+ remove { Events.RemoveHandler (SelectedIndexChangedEvent, value); }
+ }
+
+ public event EventHandler SelectionChangeCommitted {
+ add { Events.AddHandler (SelectionChangeCommittedEvent, value); }
+ remove { Events.RemoveHandler (SelectionChangeCommittedEvent, value); }
+ }
+
#endregion Events
#region Public Properties
+#if NET_2_0
+ [MonoTODO("AutoCompletion algorithm is currently not implemented.")]
+ [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
+ [Browsable (true)]
+ [EditorBrowsable (EditorBrowsableState.Always)]
+ [Localizable (true)]
+ [Editor ("System.Windows.Forms.Design.ListControlStringCollectionEditor, " + Consts.AssemblySystem_Design,
+ "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
+ public AutoCompleteStringCollection AutoCompleteCustomSource {
+ get {
+ if(auto_complete_custom_source == null) {
+ auto_complete_custom_source = new AutoCompleteStringCollection ();
+ auto_complete_custom_source.CollectionChanged += new CollectionChangeEventHandler (OnAutoCompleteCustomSourceChanged);
+ }
+ return auto_complete_custom_source;
+ }
+ set {
+ if(auto_complete_custom_source == value)
+ return;
+
+ if(auto_complete_custom_source != null) //remove eventhandler from old collection
+ auto_complete_custom_source.CollectionChanged -= new CollectionChangeEventHandler (OnAutoCompleteCustomSourceChanged);
+
+ auto_complete_custom_source = value;
+
+ if(auto_complete_custom_source != null)
+ auto_complete_custom_source.CollectionChanged += new CollectionChangeEventHandler (OnAutoCompleteCustomSourceChanged);
+ }
+ }
+
+ [MonoTODO("AutoCompletion algorithm is currently not implemented.")]
+ [Browsable (true)]
+ [EditorBrowsable (EditorBrowsableState.Always)]
+ [DefaultValue (AutoCompleteMode.None)]
+ public AutoCompleteMode AutoCompleteMode {
+ get { return auto_complete_mode; }
+ set {
+ if(auto_complete_mode == value)
+ return;
+
+ if((value < AutoCompleteMode.None) || (value > AutoCompleteMode.SuggestAppend))
+ throw new InvalidEnumArgumentException (Locale.GetText ("Enum argument value '{0}' is not valid for AutoCompleteMode", value));
+
+ auto_complete_mode = value;
+ }
+ }
+
+ [MonoTODO("AutoCompletion algorithm is currently not implemented.")]
+ [Browsable (true)]
+ [EditorBrowsable (EditorBrowsableState.Always)]
+ [DefaultValue (AutoCompleteSource.None)]
+ public AutoCompleteSource AutoCompleteSource {
+ get { return auto_complete_source; }
+ set {
+ if(auto_complete_source == value)
+ return;
+
+ if(!Enum.IsDefined (typeof (AutoCompleteSource), value))
+ throw new InvalidEnumArgumentException (Locale.GetText ("Enum argument value '{0}' is not valid for AutoCompleteSource", value));
+
+ auto_complete_source = value;
+ }
+ }
+#endif
public override Color BackColor {
get { return base.BackColor; }
set {
if (dropdown_style == value)
return;
-
+
+ SuspendLayout ();
+
if (dropdown_style == ComboBoxStyle.Simple) {
if (listbox_ctrl != null) {
Controls.RemoveImplicit (listbox_ctrl);
CreateComboListBox ();
- if (IsHandleCreated)
+ if (IsHandleCreated) {
Controls.AddImplicit (listbox_ctrl);
+ listbox_ctrl.Visible = true;
+ }
} else {
show_dropdown_button = true;
button_state = ButtonState.Normal;
}
if (dropdown_style != ComboBoxStyle.DropDownList && textbox_ctrl == null) {
- textbox_ctrl = new FixedSizeTextBox ();
+ textbox_ctrl = new ComboTextBox (this);
+ object selected_item = SelectedItem;
if (selected_item != null)
textbox_ctrl.Text = GetItemText (selected_item);
textbox_ctrl.BorderStyle = BorderStyle.None;
textbox_ctrl.TextChanged += new EventHandler (OnTextChangedEdit);
- textbox_ctrl.KeyPress += new KeyPressEventHandler(textbox_ctrl_KeyPress);
- textbox_ctrl.KeyDown += new KeyEventHandler (OnKeyDownCB);
- textbox_ctrl.GotFocus += new EventHandler(textbox_ctrl_GotFocus);
- textbox_ctrl.LostFocus += new EventHandler(textbox_ctrl_LostFocus);
- textbox_ctrl.MouseDown += new MouseEventHandler(textbox_ctrl_MouseDown);
- textbox_ctrl.MouseMove += new MouseEventHandler(textbox_ctrl_MouseMove);
- textbox_ctrl.MouseUp += new MouseEventHandler(textbox_ctrl_MouseUp);
+ textbox_ctrl.Click += new EventHandler (OnTextBoxClick);
if (IsHandleCreated == true) {
Controls.AddImplicit (textbox_ctrl);
}
}
+ ResumeLayout ();
OnDropDownStyleChanged (EventArgs.Empty);
- Layout ();
- UpdateBounds ();
+ LayoutComboBox ();
+ UpdateComboBoxBounds ();
Refresh ();
}
}
return;
if (value < 1)
- throw new ArgumentException ("The DropDownWidth value is less than one");
+#if NET_2_0
+ throw new ArgumentOutOfRangeException ("DropDownWidth",
+ "The DropDownWidth value is less than one.");
+#else
+ throw new ArgumentException ("The DropDownWidth value is less than one.");
+#endif
- dropdown_width = value;
+ dropdown_width = value;
}
}
[Browsable (false)]
- [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
+ [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
public bool DroppedDown {
get {
- if (dropdown_style == ComboBoxStyle.Simple)
+ if (dropdown_style == ComboBoxStyle.Simple)
return true;
return dropped_down;
return;
integral_height = value;
- UpdateBounds ();
+ UpdateComboBoxBounds ();
Refresh ();
}
}
return item_height;
}
set {
- if (value < 0)
- throw new ArgumentException ("The item height value is less than zero");
+ if (value < 1)
+#if NET_2_0
+ throw new ArgumentOutOfRangeException ("ItemHeight",
+ "The item height value is less than one.");
+#else
+ throw new ArgumentException ("The item height value is less than one.");
+#endif
item_height_specified = true;
item_height = value;
if (IntegralHeight)
- UpdateBounds ();
- Layout ();
+ UpdateComboBoxBounds ();
+ LayoutComboBox ();
Refresh ();
}
}
[DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
[Localizable (true)]
- [Editor ("System.Windows.Forms.Design.ListControlStringCollectionEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
+ [Editor ("System.Windows.Forms.Design.ListControlStringCollectionEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
+#if NET_2_0
+ [MergableProperty (false)]
+#endif
public ComboBox.ObjectCollection Items {
get { return items; }
}
[Browsable (false)]
[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
public override int SelectedIndex {
- get { return Items.IndexOf (selected_item); }
+ get { return selected_index; }
set {
+ if (selected_index == value)
+ return;
+
if (value <= -2 || value >= Items.Count)
throw new ArgumentOutOfRangeException ("Index of out range");
+ selected_index = value;
- object item = null;
- if (value != -1)
- item = Items [value];
+ if (dropdown_style != ComboBoxStyle.DropDownList) {
+ if (value == -1)
+ SetControlText("");
+ else
+ SetControlText (GetItemText (Items [value]));
+ }
+
+ if (DropDownStyle == ComboBoxStyle.DropDownList)
+ Invalidate ();
- SelectedItem = item;
+ if (listbox_ctrl != null)
+ listbox_ctrl.HighlightedIndex = value;
+
+ OnSelectedValueChanged (new EventArgs ());
+ OnSelectedIndexChanged (new EventArgs ());
+ OnSelectedItemChanged (new EventArgs ());
}
}
[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
[Bindable(true)]
public object SelectedItem {
- get { return selected_item; }
+ get { return selected_index == -1 ? null : Items [selected_index]; }
set {
- if (selected_item == value)
+ object item = selected_index == -1 ? null : Items [selected_index];
+ if (item == value)
return;
- selected_item = value;
-
- if (dropdown_style != ComboBoxStyle.DropDownList) {
- if (selected_item == null)
- SetControlText("");
- else {
- SetControlText (GetItemText (selected_item));
- SelectAll ();
- }
- }
-
- OnSelectedValueChanged (new EventArgs ());
- OnSelectedIndexChanged (new EventArgs ());
- OnSelectedItemChanged (new EventArgs ());
- if (DropDownStyle == ComboBoxStyle.DropDownList)
- Refresh ();
-
- if (listbox_ctrl != null)
- listbox_ctrl.HighlightedItem = value;
+ SelectedIndex = Items.IndexOf (value);
}
}
if (dropdown_style == ComboBoxStyle.DropDownList)
return 0;
- return textbox_ctrl.SelectionLength;
+ int result = textbox_ctrl.SelectionLength;
+ return result == -1 ? 0 : result;
}
set {
if (dropdown_style == ComboBoxStyle.DropDownList)
return;
sorted = value;
+ SelectedIndex = -1;
+ if (sorted) {
+ Items.Sort ();
+ LayoutComboBox ();
+ }
}
}
#endregion Public Properties
#region Public Methods
+#if NET_2_0
+ [Obsolete ("This method has been deprecated")]
+#endif
protected virtual void AddItemsCore (object[] value)
{
switch (keyData) {
case Keys.Up:
case Keys.Down:
+ case Keys.Left:
+ case Keys.Right:
case Keys.PageUp:
case Keys.PageDown:
return true;
protected override void OnDataSourceChanged (EventArgs e)
{
base.OnDataSourceChanged (e);
- BindDataItems (items);
+ BindDataItems ();
if (DataSource == null || DataManager == null) {
SelectedIndex = -1;
if (DataManager == null || !IsHandleCreated)
return;
- BindDataItems (items);
+ BindDataItems ();
SelectedIndex = DataManager.Position;
}
switch (DrawMode) {
case DrawMode.OwnerDrawFixed:
case DrawMode.OwnerDrawVariable:
- if (DrawItem != null)
- DrawItem (this, e);
+ DrawItemEventHandler eh = (DrawItemEventHandler)(Events [DrawItemEvent]);
+ if (eh != null)
+ eh (this, e);
break;
default:
ThemeEngine.Current.DrawComboBoxItem (this, e);
protected virtual void OnDropDown (EventArgs e)
{
- if (DropDown != null)
- DropDown (this, e);
+ EventHandler eh = (EventHandler)(Events [DropDownEvent]);
+ if (eh != null)
+ eh (this, e);
}
protected virtual void OnDropDownStyleChanged (EventArgs e)
{
- if (DropDownStyleChanged != null)
- DropDownStyleChanged (this, e);
+ EventHandler eh = (EventHandler)(Events [DropDownStyleChangedEvent]);
+ if (eh != null)
+ eh (this, e);
}
protected override void OnFontChanged (EventArgs e)
}
if (IntegralHeight)
- UpdateBounds ();
+ UpdateComboBoxBounds ();
- Layout ();
+ LayoutComboBox ();
}
protected override void OnForeColorChanged (EventArgs e)
}
[EditorBrowsable(EditorBrowsableState.Advanced)]
- protected override void OnGotFocus (EventArgs e) {
- Invalidate ();
+ protected override void OnGotFocus (EventArgs e)
+ {
+ if (dropdown_style == ComboBoxStyle.DropDownList) {
+ // We draw DDL styles manually, so they require a
+ // refresh to have their selection drawn
+ Invalidate ();
+ }
+
+ if (textbox_ctrl != null) {
+ textbox_ctrl.SetSelectable (false);
+ textbox_ctrl.ActivateCaret (true);
+ textbox_ctrl.ShowSelection = true;
+ textbox_ctrl.SelectAll ();
+ }
- if (dropdown_style == ComboBoxStyle.Simple)
- listbox_ctrl.Focus ();
- else if (dropdown_style != ComboBoxStyle.DropDownList && textbox_ctrl != null)
- textbox_ctrl.Focus ();
base.OnGotFocus (e);
}
[EditorBrowsable(EditorBrowsableState.Advanced)]
- protected override void OnLostFocus (EventArgs e) {
+ protected override void OnLostFocus (EventArgs e)
+ {
+ if (dropdown_style == ComboBoxStyle.DropDownList) {
+ // We draw DDL styles manually, so they require a
+ // refresh to have their selection drawn
+ Invalidate ();
+ }
+
+ if (listbox_ctrl != null && dropped_down) {
+ listbox_ctrl.HideWindow ();
+ }
+
+ if (textbox_ctrl != null) {
+ textbox_ctrl.SetSelectable (true);
+ textbox_ctrl.ActivateCaret (false);
+ textbox_ctrl.ShowSelection = false;
+ }
+
base.OnLostFocus (e);
- }
+ }
protected override void OnHandleCreated (EventArgs e)
{
base.OnHandleCreated (e);
- if (listbox_ctrl != null)
+ if (listbox_ctrl != null) {
Controls.AddImplicit (listbox_ctrl);
-
+ listbox_ctrl.Visible = true;
+ }
+
if (textbox_ctrl != null)
Controls.AddImplicit (textbox_ctrl);
- Layout ();
+ LayoutComboBox ();
}
protected override void OnHandleDestroyed (EventArgs e)
protected override void OnKeyPress (KeyPressEventArgs e)
{
+ // int index = FindStringCaseInsensitive (e.KeyChar.ToString (), SelectedIndex);
+ //if (index != -1)
+ // SelectedIndex = index;
+
base.OnKeyPress (e);
}
protected virtual void OnMeasureItem (MeasureItemEventArgs e)
{
- if (MeasureItem != null)
- MeasureItem (this, e);
+ MeasureItemEventHandler eh = (MeasureItemEventHandler)(Events [MeasureItemEvent]);
+ if (eh != null)
+ eh (this, e);
}
protected override void OnParentBackColorChanged (EventArgs e)
protected override void OnResize (EventArgs e)
{
- Layout ();
+ LayoutComboBox ();
if (listbox_ctrl != null)
listbox_ctrl.CalcListBoxArea ();
}
{
base.OnSelectedIndexChanged (e);
- if (SelectedIndexChanged != null)
- SelectedIndexChanged (this, e);
+ EventHandler eh = (EventHandler)(Events [SelectedIndexChangedEvent]);
+ if (eh != null)
+ eh (this, e);
}
protected virtual void OnSelectedItemChanged (EventArgs e)
protected virtual void OnSelectionChangeCommitted (EventArgs e)
{
- if (SelectionChangeCommitted != null)
- SelectionChangeCommitted (this, e);
+ EventHandler eh = (EventHandler)(Events [SelectionChangeCommittedEvent]);
+ if (eh != null)
+ eh (this, e);
}
protected override void RefreshItem (int index)
item_heights.Remove (Items [index]);
}
+#if NET_2_0
+ protected override bool ProcessKeyEventArgs (ref Message m)
+ {
+ return base.ProcessKeyEventArgs (ref m);
+ }
+
+ [EditorBrowsable (EditorBrowsableState.Advanced)]
+ protected override void OnKeyDown (KeyEventArgs e)
+ {
+ base.OnKeyDown (e);
+ }
+
+ [EditorBrowsable (EditorBrowsableState.Advanced)]
+ protected override void OnValidating (CancelEventArgs e)
+ {
+ base.OnValidating (e);
+ }
+
+ [EditorBrowsable (EditorBrowsableState.Advanced)]
+ protected override void OnTextChanged (EventArgs e)
+ {
+ base.OnTextChanged (e);
+ }
+
+ protected override void OnMouseLeave (EventArgs e)
+ {
+ base.OnMouseLeave (e);
+ }
+
+ protected override void OnMouseEnter (EventArgs e)
+ {
+ base.OnMouseEnter (e);
+ }
+#endif
+
public void Select (int start, int length)
{
if (start < 0)
if (dropdown_style == ComboBoxStyle.DropDownList)
return;
-
+
textbox_ctrl.Select (start, length);
}
{
if (dropdown_style == ComboBoxStyle.DropDownList)
return;
-
- textbox_ctrl.SelectAll ();
+
+ if (textbox_ctrl != null) {
+ textbox_ctrl.ShowSelection = true;
+ textbox_ctrl.SelectAll ();
+ }
}
protected override void SetBoundsCore (int x, int y, int width, int height, BoundsSpecified specified)
Items.Clear ();
Items.AddRange (value);
} finally {
- EndUpdate ();
+ EndUpdate ();
}
}
protected override void WndProc (ref Message m)
{
switch ((Msg) m.Msg) {
+ case Msg.WM_KEYUP:
+ case Msg.WM_KEYDOWN:
+ Keys keys = (Keys) m.WParam.ToInt32 ();
+ if (keys == Keys.Up || keys == Keys.Down)
+ break;
+ goto case Msg.WM_CHAR;
+ case Msg.WM_CHAR:
+ if (textbox_ctrl != null)
+ XplatUI.SendMessage (textbox_ctrl.Handle, (Msg) m.Msg, m.WParam, m.LParam);
+ break;
case Msg.WM_MOUSE_LEAVE:
Point location = PointToClient (Control.MousePosition);
if (ClientRectangle.Contains (location))
#endregion Public Methods
#region Private Methods
+#if NET_2_0
+ void OnAutoCompleteCustomSourceChanged(object sender, CollectionChangeEventArgs e) {
+ if(auto_complete_source == AutoCompleteSource.CustomSource) {
+ //FIXME: handle add, remove and refresh events in AutoComplete algorithm.
+ }
+ }
+#endif
internal override bool InternalCapture {
get { return Capture; }
set {}
}
-
- private void textbox_ctrl_KeyPress(object sender, KeyPressEventArgs e)
- {
- OnKeyPress (e);
- }
-
- private void textbox_ctrl_GotFocus(object sender, EventArgs e )
- {
- OnGotFocus(e);
- }
-
- private void textbox_ctrl_LostFocus(object sender, EventArgs e )
- {
- OnLostFocus(e);
- }
-
- private void textbox_ctrl_MouseDown(object sender, MouseEventArgs e )
- {
- OnMouseDown(e);
- }
- private void textbox_ctrl_MouseMove(object sender, MouseEventArgs e )
- {
- OnMouseMove(e);
- }
-
- private void textbox_ctrl_MouseUp(object sender, MouseEventArgs e )
- {
- OnMouseUp(e);
- }
-
- void Layout ()
+ void LayoutComboBox ()
{
int border = ThemeEngine.Current.Border3DSize.Width;
private void CreateComboListBox ()
{
listbox_ctrl = new ComboListBox (this);
- if (selected_item != null)
- listbox_ctrl.HighlightedItem = selected_item;
+ listbox_ctrl.HighlightedIndex = SelectedIndex;
}
internal void Draw (Rectangle clip, Graphics dc)
item_rect.Width -= (button_area.Width + 2 * border);
item_rect.Height -= 2 * border;
- if (has_focus) {
+ if (Focused) {
state = DrawItemState.Selected;
state |= DrawItemState.Focus;
}
button_state = ButtonState.Pushed;
if (dropdown_style == ComboBoxStyle.DropDownList)
Invalidate (text_area);
-
- OnDropDown (EventArgs.Empty);
}
internal void DropDownListBoxFinished ()
return -1;
}
+ internal int FindStringCaseInsensitive (string search, int start_index)
+ {
+ if (search.Length == 0) {
+ return -1;
+ }
+
+ for (int i = 0; i < Items.Count; i++) {
+ int index = (i + start_index) % Items.Count;
+ if (String.Compare (GetItemText (Items [index]), 0, search, 0, search.Length, true) == 0)
+ return index;
+ }
+
+ return -1;
+ }
+
private void OnKeyDownCB(object sender, KeyEventArgs e)
{
if (Items.Count == 0)
SelectedIndex = Math.Max(SelectedIndex-1, 0);
break;
- case Keys.Down:
+ case Keys.Down:
SelectedIndex = Math.Min(SelectedIndex+1, Items.Count-1);
break;
}
void OnMouseDownCB (object sender, MouseEventArgs e)
- {
+ {
Rectangle area;
if (DropDownStyle == ComboBoxStyle.DropDownList)
area = ClientRectangle;
listbox_ctrl.Capture = true;
}
+ private void OnMouseWheelCB (object sender, MouseEventArgs me)
+ {
+ if (Items.Count == 0)
+ return;
+
+ if (listbox_ctrl != null && listbox_ctrl.Visible) {
+ int lines = me.Delta / 120 * SystemInformation.MouseWheelScrollLines;
+ listbox_ctrl.Scroll (-lines);
+ } else {
+ int lines = me.Delta / 120;
+ int index = SelectedIndex - lines;
+ if (index < 0)
+ index = 0;
+ else if (index >= Items.Count)
+ index = Items.Count - 1;
+ SelectedIndex = index;
+ }
+ }
+
internal override void OnPaintInternal (PaintEventArgs pevent)
{
if (suspend_ctrlupdate)
Draw (ClientRectangle, pevent.Graphics);
}
+ private void OnTextBoxClick (object sender, EventArgs e)
+ {
+ OnClick (e);
+ }
+
private void OnTextChangedEdit (object sender, EventArgs e)
{
if (process_textchanged_event == false)
return;
+ OnTextChanged (EventArgs.Empty);
+
int item = FindStringCaseInsensitive (textbox_ctrl.Text);
if (item == -1)
return;
+ // TODO: THIS IS BROKEN-ISH
+ // I don't think we should hilight, and setting the top item does weirdness
+ // when there is no scrollbar
+
if (listbox_ctrl != null) {
listbox_ctrl.SetTopItem (item);
- listbox_ctrl.HighlightedItem = Items [item];
+ listbox_ctrl.HighlightedIndex = item;
}
+
+ base.Text = textbox_ctrl.Text;
}
internal void SetControlText (string s)
{
- process_textchanged_event = false;
+ process_textchanged_event = false;
textbox_ctrl.Text = s;
process_textchanged_event = true;
}
- void UpdateBounds ()
+ void UpdateComboBoxBounds ()
{
- if (requested_height != -1)
- SetBoundsCore (0, 0, 0, requested_height, BoundsSpecified.Height);
+ if (requested_height == -1)
+ return;
+
+ // Save the requested height since set bounds can destroy it
+ int save_height = requested_height;
+ SetBounds (0, 0, 0, requested_height, BoundsSpecified.Height);
+ requested_height = save_height;
}
private void UpdatedItems ()
set {
if (index < 0 || index >= Count)
throw new ArgumentOutOfRangeException ("Index of out range");
+ if (value == null)
+ throw new ArgumentNullException ("value");
object_items[index] = value;
+ if (owner.listbox_ctrl != null)
+ owner.listbox_ctrl.InvalidateItem (index);
+ if (index == owner.SelectedIndex) {
+ if (owner.textbox_ctrl == null)
+ owner.Refresh ();
+ else
+ owner.textbox_ctrl.SelectedText = value.ToString ();
+ }
}
}
#endregion Public Properties
- #region Private Properties
- internal ArrayList ObjectItems {
- get { return object_items;}
- set {
- object_items = value;
- }
- }
-
- #endregion Private Properties
-
#region Public Methods
public int Add (object item)
{
public void AddRange (object[] items)
{
+ if (items == null)
+ throw new ArgumentNullException ("items");
+
foreach (object mi in items)
AddItem (mi);
public void Clear ()
{
- owner.selected_item = null;
+ owner.selected_index = -1;
object_items.Clear ();
owner.UpdatedItems ();
owner.Refresh ();
public bool Contains (object obj)
{
+ if (obj == null)
+ throw new ArgumentNullException ("obj");
+
return object_items.Contains (obj);
}
public int IndexOf (object value)
{
+ if (value == null)
+ throw new ArgumentNullException ("value");
+
return object_items.IndexOf (value);
}
{
if (index < 0 || index > Count)
throw new ArgumentOutOfRangeException ("Index of out range");
+ if (item == null)
+ throw new ArgumentNullException ("item");
owner.BeginUpdate ();
- object_items.Insert (index, item);
+ if (owner.Sorted)
+ AddItem (item);
+ else
+ object_items.Insert (index, item);
owner.EndUpdate (); // Calls UpdatedItems
}
public void Remove (object value)
{
+ if (value == null)
+ return;
+
if (IndexOf (value) == owner.SelectedIndex)
- owner.SelectedItem = null;
+ owner.SelectedIndex = -1;
RemoveAt (IndexOf (value));
-
}
public void RemoveAt (int index)
throw new ArgumentOutOfRangeException ("Index of out range");
if (index == owner.SelectedIndex)
- owner.SelectedItem = null;
+ owner.SelectedIndex = -1;
object_items.RemoveAt (index);
owner.UpdatedItems ();
#region Private Methods
private int AddItem (object item)
{
- int cnt = object_items.Count;
+ if (item == null)
+ throw new ArgumentNullException ("item");
+
+ if (owner.Sorted) {
+ int index = 0;
+ foreach (object o in object_items) {
+ if (String.Compare (item.ToString (), o.ToString ()) < 0) {
+ object_items.Insert (index, item);
+ return index;
+ }
+ index++;
+ }
+ }
object_items.Add (item);
- return cnt;
+ return object_items.Count - 1;
}
internal void AddRange (IList items)
owner.UpdatedItems ();
}
+ internal void Sort ()
+ {
+ object_items.Sort ();
+ }
+
#endregion Private Methods
}
+ internal class ComboTextBox : TextBox {
+
+ private ComboBox owner;
+
+ public ComboTextBox (ComboBox owner)
+ {
+ this.owner = owner;
+ ShowSelection = false;
+ }
+
+ internal void SetSelectable (bool selectable)
+ {
+ SetStyle (ControlStyles.Selectable, selectable);
+ }
+
+ internal void ActivateCaret (bool active)
+ {
+ if (active)
+ document.CaretHasFocus ();
+ else
+ document.CaretLostFocus ();
+ }
+
+ internal override void OnGotFocusInternal (EventArgs e)
+ {
+ owner.Select (false, true);
+ }
+
+ internal override void OnLostFocusInternal (EventArgs e)
+ {
+ owner.Select (false, true);
+ }
+ }
+
internal class ComboListBox : Control
{
private ComboBox owner;
set { }
}
- public bool FireMouseDown (MouseEventArgs e)
+ public void FireMouseDown (MouseEventArgs e)
{
- if (Visible) {
- e = TranslateEvent (e);
- if (ClientRectangle.Contains (e.X, e.Y)) {
- OnMouseDown (e);
- return true;
- }
- }
- return false;
+ if (!Visible)
+ return;
+
+ e = TranslateEvent (e);
+ OnMouseDown (e);
}
public void FireMouseUp (MouseEventArgs e)
{
- if (Visible) {
- e = TranslateEvent (e);
- if (ClientRectangle.Contains (e.X, e.Y))
- OnMouseUp (e);
- }
+ if (!Visible)
+ return;
+
+ e = TranslateEvent (e);
+ OnMouseUp (e);
}
public void FireMouseMove (MouseEventArgs e)
{
- if (Visible) {
- e = TranslateEvent (e);
- if (ClientRectangle.Contains (e.X, e.Y))
- OnMouseMove (e);
- }
+ if (!Visible)
+ return;
+
+ e = TranslateEvent (e);
+ OnMouseMove (e);
}
MouseEventArgs TranslateEvent (MouseEventArgs e)
last_item = 0;
page_size = 0;
- MouseDown += new MouseEventHandler (OnMouseDownPUW);
- MouseUp += new MouseEventHandler (OnMouseUpPUW);
- MouseMove += new MouseEventHandler (OnMouseMovePUW);
- MouseWheel += new MouseEventHandler (OnMouseWheelCLB);
- KeyDown += new KeyEventHandler (OnKeyDownPUW);
+ MouseWheel += new MouseEventHandler (OnMouseWheelCLB);
+
SetStyle (ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true);
SetStyle (ControlStyles.ResizeRedraw | ControlStyles.Opaque, true);
+ this.is_visible = false;
+ Hwnd.ObjectFromHandle (this.Handle).no_activate = true;
+
if (owner.DropDownStyle == ComboBoxStyle.Simple)
InternalBorderStyle = BorderStyle.Fixed3D;
else
}
}
+ protected override void Select (bool directed, bool forward)
+ {
+ // Do nothing, we never want to be selected
+ }
+
internal override bool InternalCapture {
get {
return Capture;
}
}
- protected override void OnLostFocus(EventArgs e) {
- if (Capture) {
- HideWindow();
- }
- base.OnLostFocus (e);
- }
-
-
int BorderWidth {
get {
switch (border_style) {
}
}
+ page_size = height / owner.ItemHeight;
+
if (owner.Items.Count <= owner.MaxDropDownItems) {
if (vscrollbar_ctrl != null)
vscrollbar_ctrl.Visible = false;
vscrollbar_ctrl.Location = new Point (width - vscrollbar_ctrl.Width - BorderWidth - 1, 0);
- vscrollbar_ctrl.Maximum = owner.Items.Count - (owner.DropDownStyle == ComboBoxStyle.Simple ? page_size : owner.maxdrop_items);
+ vscrollbar_ctrl.Maximum = owner.Items.Count - 2;
+ int large = (owner.DropDownStyle == ComboBoxStyle.Simple ? page_size : owner.maxdrop_items) - 1;
+ if (large < 0)
+ large = 0;
+ vscrollbar_ctrl.LargeChange = large;
show_scrollbar = vscrollbar_ctrl.Visible = true;
int hli = HighlightedIndex;
textarea_drawable.Width -= vscrollbar_ctrl.Width;
last_item = LastVisibleItem ();
- page_size = textarea_drawable.Height / owner.ItemHeight;
}
private void Draw (Rectangle clip, Graphics dc)
}
}
+ int highlighted_index = -1;
+
public int HighlightedIndex {
- get { return owner.Items.IndexOf (highlighted_item); }
+ get { return highlighted_index; }
set {
- object item = null;
- if (value != -1)
- item = owner.Items [value];
- HighlightedItem = item;
- }
- }
-
- object highlighted_item = null;
-
- public object HighlightedItem {
- get { return highlighted_item; }
- set {
- if (highlighted_item == value)
+ if (highlighted_index == value)
return;
-
- int index = owner.Items.IndexOf (highlighted_item);
- if (index != -1)
- Invalidate (GetItemDisplayRectangle (index, top_item));
- highlighted_item = value;
- index = owner.Items.IndexOf (highlighted_item);
- if (index != -1)
- Invalidate (GetItemDisplayRectangle (index, top_item));
+
+ if (highlighted_index != -1 && highlighted_index < this.owner.Items.Count)
+ Invalidate (GetItemDisplayRectangle (highlighted_index, top_item));
+ highlighted_index = value;
+ if (highlighted_index != -1)
+ Invalidate (GetItemDisplayRectangle (highlighted_index, top_item));
}
}
-
+
private Rectangle GetItemDisplayRectangle (int index, int top_index)
{
if (index < 0 || index >= owner.Items.Count)
return -1;
}
-
- protected override bool IsInputKey (Keys keyData)
+
+ public void InvalidateItem (int index)
{
- return owner.IsInputKey (keyData);
+ if (Visible)
+ Invalidate (GetItemDisplayRectangle (index, top_item));
}
private int LastVisibleItem ()
}
return i - 1;
}
-
- private void NavigateItemVisually (ItemNavigation navigation)
- {
- int item = -1;
-
- switch (navigation) {
- case ItemNavigation.Next:
- if (HighlightedIndex + 1 < owner.Items.Count) {
- if (HighlightedIndex + 1 > last_item) {
- top_item++;
- vscrollbar_ctrl.Value = top_item;
- }
- item = HighlightedIndex + 1;
- }
- break;
-
- case ItemNavigation.Previous:
- if (HighlightedIndex > 0) {
- if (HighlightedIndex - 1 < top_item) {
- top_item--;
- vscrollbar_ctrl.Value = top_item;
- }
- item = HighlightedIndex - 1;
- }
- break;
-
- case ItemNavigation.NextPage:
- if (HighlightedIndex + page_size - 1 >= owner.Items.Count) {
- top_item = owner.Items.Count - page_size;
- vscrollbar_ctrl.Value = top_item;
- item = owner.Items.Count - 1;
- } else {
- if (HighlightedIndex + page_size - 1 > last_item) {
- top_item = HighlightedIndex;
- vscrollbar_ctrl.Value = HighlightedIndex;
- }
- item = HighlightedIndex + page_size - 1;
- }
- break;
-
- case ItemNavigation.PreviousPage:
- if (HighlightedIndex - page_size - 1 <= 0) {
- top_item = 0;
- vscrollbar_ctrl.Value = top_item;
- item = 0;
- } else {
- if (HighlightedIndex - page_size - 1 < top_item) {
- top_item = HighlightedIndex - page_size - 1;
- vscrollbar_ctrl.Value = top_item;
- }
- item = HighlightedIndex - page_size - 1;
- }
- break;
-
- default:
- break;
- }
-
- if (item != -1) {
- HighlightedIndex = item;
- owner.OnSelectionChangeCommitted (new EventArgs ());
- if (owner.DropDownStyle == ComboBoxStyle.Simple)
- owner.SetControlText (owner.GetItemText (owner.Items[item]));
- }
- }
- private void OnKeyDownPUW (object sender, KeyEventArgs e)
- {
- switch (e.KeyCode) {
- case Keys.Up:
- NavigateItemVisually (ItemNavigation.Previous);
- break;
-
- case Keys.Down:
- NavigateItemVisually (ItemNavigation.Next);
- break;
-
- case Keys.PageUp:
- NavigateItemVisually (ItemNavigation.PreviousPage);
- break;
-
- case Keys.PageDown:
- NavigateItemVisually (ItemNavigation.NextPage);
- break;
-
- default:
- break;
- }
- }
-
public void SetTopItem (int item)
{
if (top_item == item)
return;
top_item = item;
UpdateLastVisibleItem ();
- Refresh ();
+ Invalidate ();
}
-
- private void OnMouseDownPUW (object sender, MouseEventArgs e)
- {
- int index = IndexFromPointDisplayRectangle (e.X, e.Y);
- if (index == -1) {
- if (vscrollbar_ctrl == null || !vscrollbar_ctrl.FireMouseDown (e))
- HideWindow ();
- } else {
- owner.OnSelectionChangeCommitted (new EventArgs ());
- owner.SelectedIndex = index;
- HighlightedIndex = index;
- HideWindow ();
- }
-
- if (owner.DropDownStyle == ComboBoxStyle.Simple) {
- owner.OnMouseDown (e);
- owner.textbox_ctrl.Focus ();
+ bool scrollbar_grabbed = false;
+
+ bool InScrollBar {
+ get {
+ if (vscrollbar_ctrl == null || !vscrollbar_ctrl.is_visible)
+ return false;
+
+ return vscrollbar_ctrl.Bounds.Contains (PointToClient (Control.MousePosition));
}
}
- private void OnMouseMovePUW (object sender, MouseEventArgs e)
+ protected override void OnMouseDown (MouseEventArgs e)
{
- if (owner.DropDownStyle == ComboBoxStyle.Simple) {
- owner.OnMouseMove (e);
+ if (InScrollBar) {
+ vscrollbar_ctrl.FireMouseDown (e);
+ scrollbar_grabbed = true;
+ }
+ }
+
+ protected override void OnMouseMove (MouseEventArgs e)
+ {
+ if (owner.DropDownStyle == ComboBoxStyle.Simple)
+ return;
+
+ if (scrollbar_grabbed || (!Capture && InScrollBar)) {
+ vscrollbar_ctrl.FireMouseMove (e);
return;
}
-
+
Point pt = PointToClient (Control.MousePosition);
int index = IndexFromPointDisplayRectangle (pt.X, pt.Y);
- if (index != -1) {
+ if (index != -1)
HighlightedIndex = index;
- return;
- }
-
- if (vscrollbar_ctrl != null)
- vscrollbar_ctrl.FireMouseMove (e);
}
- private void OnMouseUpPUW (object sender, MouseEventArgs e)
+ protected override void OnMouseUp (MouseEventArgs e)
{
- if (owner.DropDownStyle == ComboBoxStyle.Simple) {
- owner.OnMouseUp (e);
- return;
+ int index = IndexFromPointDisplayRectangle (e.X, e.Y);
+
+ if (scrollbar_grabbed) {
+ vscrollbar_ctrl.FireMouseUp (e);
+ scrollbar_grabbed = false;
+ if (index != -1)
+ HighlightedIndex = index;
+ return;
+ }
+
+ if (index == -1) {
+ HideWindow ();
+ return;
}
- if (vscrollbar_ctrl != null)
- vscrollbar_ctrl.FireMouseUp (e);
+ owner.SelectedIndex = index;
+ owner.OnSelectionChangeCommitted (new EventArgs ());
+ HideWindow ();
}
internal override void OnPaintInternal (PaintEventArgs pevent)
{
if (owner.DropDownStyle == ComboBoxStyle.Simple && owner.Items.Count == 0)
return false;
-
+
HighlightedIndex = owner.SelectedIndex;
CalcListBoxArea ();
last_item = LastVisibleItem ();
}
- private void Scroll (int delta)
+ public void Scroll (int delta)
{
- if (delta == 0 || !vscrollbar_ctrl.Visible)
+ if (delta == 0 || vscrollbar_ctrl == null || !vscrollbar_ctrl.Visible)
return;
- int max = vscrollbar_ctrl.Maximum;//- (page_size) + 1;
+ int max = owner.Items.Count - page_size;
int val = vscrollbar_ctrl.Value + delta;
if (val > max)
top_item = vscrollbar_ctrl.Value;
UpdateLastVisibleItem ();
- Refresh ();
+ Invalidate ();
}
+ protected override void WndProc(ref Message m) {
+ if (m.Msg == (int)Msg.WM_SETFOCUS) {
+ if (m.WParam != IntPtr.Zero) {
+ XplatUI.SetFocus(m.WParam);
+ }
+ }
+ base.WndProc (ref m);
+ }
+
#endregion Private Methods
}
}
}
+