// 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 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 {
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;
}
}
+ 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; }
}
public override int SelectedIndex {
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;
SetControlText (GetItemText (Items [value]));
}
- OnSelectedValueChanged (new EventArgs ());
- OnSelectedIndexChanged (new EventArgs ());
- OnSelectedItemChanged (new EventArgs ());
if (DropDownStyle == ComboBoxStyle.DropDownList)
Invalidate ();
if (listbox_ctrl != null)
listbox_ctrl.HighlightedIndex = value;
+
+ OnSelectedValueChanged (new EventArgs ());
+ OnSelectedIndexChanged (new EventArgs ());
+ OnSelectedItemChanged (new EventArgs ());
}
}
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)
SelectedIndex = -1;
if (sorted) {
Items.Sort ();
- Layout ();
+ 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 (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)
{
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 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)
#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 {}
}
- void Layout ()
+ void LayoutComboBox ()
{
int border = ThemeEngine.Current.Border3DSize.Width;
button_state = ButtonState.Pushed;
if (dropdown_style == ComboBoxStyle.DropDownList)
Invalidate (text_area);
-
- OnDropDown (EventArgs.Empty);
}
internal void DropDownListBoxFinished ()
process_textchanged_event = true;
}
- void UpdateBounds ()
+ void UpdateComboBoxBounds ()
{
- if (requested_height != -1)
- SetBounds (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 ()
if (owner.Sorted) {
int index = 0;
- foreach (string s in object_items) {
- if (String.Compare (item as String, s) < 0) {
+ foreach (object o in object_items) {
+ if (String.Compare (item.ToString (), o.ToString ()) < 0) {
object_items.Insert (index, item);
return index;
}
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)
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
}
}
+ 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)
if (highlighted_index == value)
return;
- if (highlighted_index != -1)
+ if (highlighted_index != -1 && highlighted_index < this.owner.Items.Count)
Invalidate (GetItemDisplayRectangle (highlighted_index, top_item));
highlighted_index = value;
if (highlighted_index != -1)
Invalidate ();
}
+ 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));
+ }
+ }
+
protected override void OnMouseDown (MouseEventArgs e)
{
- if (vscrollbar_ctrl != null)
+ 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);
}
protected override void OnMouseUp (MouseEventArgs e)
{
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) {
- if (vscrollbar_ctrl == null || !vscrollbar_ctrl.FireMouseDown (e))
- HideWindow ();
- } else {
- owner.OnSelectionChangeCommitted (new EventArgs ());
- owner.SelectedIndex = index;
- HideWindow ();
+ 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 (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)
}
}
+