1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 // Copyright (c) 2004-2006 Novell, Inc.
23 // Jordi Mas i Hernandez, jordi@ximian.com
24 // Mike Kestner <mkestner@novell.com>
25 // Daniel Nauck (dna(at)mono-project(dot)de)
28 using System
.Collections
;
29 using System
.ComponentModel
;
30 using System
.ComponentModel
.Design
;
31 using System
.ComponentModel
.Design
.Serialization
;
33 using System
.Globalization
;
34 using System
.Reflection
;
35 using System
.Runtime
.InteropServices
;
37 namespace System
.Windows
.Forms
39 [DefaultProperty("Items")]
40 [DefaultEvent("SelectedIndexChanged")]
41 [Designer ("System.Windows.Forms.Design.ComboBoxDesigner, " + Consts
.AssemblySystem_Design
, "System.ComponentModel.Design.IDesigner")]
43 [DefaultBindingProperty ("Text")]
44 [ClassInterface (ClassInterfaceType
.AutoDispatch
)]
47 public class ComboBox
: ListControl
49 private DrawMode draw_mode
= DrawMode
.Normal
;
50 private ComboBoxStyle dropdown_style
;
51 private int dropdown_width
= -1;
52 private int selected_index
= -1;
53 private ObjectCollection items
;
54 private bool suspend_ctrlupdate
;
55 private int maxdrop_items
= 8;
56 private bool integral_height
= true;
58 private int max_length
;
59 private ComboListBox listbox_ctrl
;
60 private ComboTextBox textbox_ctrl
;
61 private bool process_textchanged_event
= true;
62 private bool item_height_specified
;
63 private int item_height
;
64 private int requested_height
= -1;
65 private Hashtable item_heights
;
66 private bool show_dropdown_button
;
67 private ButtonState button_state
= ButtonState
.Normal
;
68 private bool dropped_down
;
69 private Rectangle text_area
;
70 private Rectangle button_area
;
71 private Rectangle listbox_area
;
72 private const int button_width
= 16;
74 private AutoCompleteStringCollection auto_complete_custom_source
= null;
75 private AutoCompleteMode auto_complete_mode
= AutoCompleteMode
.None
;
76 private AutoCompleteSource auto_complete_source
= AutoCompleteSource
.None
;
77 private int drop_down_height
;
78 private FlatStyle flat_style
;
82 public class ChildAccessibleObject
: AccessibleObject
{
84 public ChildAccessibleObject (ComboBox owner
, IntPtr handle
)
89 public override string Name
{
98 items
= new ObjectCollection (this);
99 DropDownStyle
= ComboBoxStyle
.DropDown
;
100 item_height
= FontHeight
+ 2;
101 BackColor
= ThemeEngine
.Current
.ColorWindow
;
102 border_style
= BorderStyle
.None
;
105 drop_down_height
= 106;
106 flat_style
= FlatStyle
.Standard
;
110 MouseDown
+= new MouseEventHandler (OnMouseDownCB
);
111 MouseUp
+= new MouseEventHandler (OnMouseUpCB
);
112 MouseMove
+= new MouseEventHandler (OnMouseMoveCB
);
113 MouseWheel
+= new MouseEventHandler (OnMouseWheelCB
);
114 KeyDown
+=new KeyEventHandler(OnKeyDownCB
);
120 [EditorBrowsable (EditorBrowsableState
.Never
)]
121 public new event EventHandler BackgroundImageChanged
{
122 add { base.BackgroundImageChanged += value; }
123 remove { base.BackgroundImageChanged -= value; }
129 [EditorBrowsable (EditorBrowsableState
.Never
)]
130 public new event EventHandler BackgroundImageLayoutChanged
132 add { base.BackgroundImageLayoutChanged += value; }
133 remove { base.BackgroundImageLayoutChanged -= value; }
137 [EditorBrowsable (EditorBrowsableState
.Never
)]
138 public new event EventHandler DoubleClick
140 add { base.DoubleClick += value; }
141 remove { base.DoubleClick -= value; }
145 static object DrawItemEvent
= new object ();
146 static object DropDownEvent
= new object ();
147 static object DropDownStyleChangedEvent
= new object ();
148 static object MeasureItemEvent
= new object ();
149 static object SelectedIndexChangedEvent
= new object ();
150 static object SelectionChangeCommittedEvent
= new object ();
152 static object DropDownClosedEvent
= new object ();
153 static object TextUpdateEvent
= new object ();
156 public event DrawItemEventHandler DrawItem
{
157 add { Events.AddHandler (DrawItemEvent, value); }
158 remove { Events.RemoveHandler (DrawItemEvent, value); }
161 public event EventHandler DropDown
{
162 add { Events.AddHandler (DropDownEvent, value); }
163 remove { Events.RemoveHandler (DropDownEvent, value); }
166 public event EventHandler DropDownClosed
168 add { Events.AddHandler (DropDownClosedEvent, value); }
169 remove { Events.RemoveHandler (DropDownClosedEvent, value); }
173 public event EventHandler DropDownStyleChanged
{
174 add { Events.AddHandler (DropDownStyleChangedEvent, value); }
175 remove { Events.RemoveHandler (DropDownStyleChangedEvent, value); }
178 public event MeasureItemEventHandler MeasureItem
{
179 add { Events.AddHandler (MeasureItemEvent, value); }
180 remove { Events.RemoveHandler (MeasureItemEvent, value); }
184 [EditorBrowsable (EditorBrowsableState
.Never
)]
185 public new event EventHandler PaddingChanged
187 add { base.PaddingChanged += value; }
188 remove { base.PaddingChanged -= value; }
193 [EditorBrowsable (EditorBrowsableState
.Never
)]
194 public new event PaintEventHandler Paint
{
195 add { base.Paint += value; }
196 remove { base.Paint -= value; }
199 public event EventHandler SelectedIndexChanged
{
200 add { Events.AddHandler (SelectedIndexChangedEvent, value); }
201 remove { Events.RemoveHandler (SelectedIndexChangedEvent, value); }
204 public event EventHandler SelectionChangeCommitted
{
205 add { Events.AddHandler (SelectionChangeCommittedEvent, value); }
206 remove { Events.RemoveHandler (SelectionChangeCommittedEvent, value); }
209 public event EventHandler TextUpdate
211 add { Events.AddHandler (TextUpdateEvent, value); }
212 remove { Events.RemoveHandler (TextUpdateEvent, value); }
218 #region Public Properties
220 [MonoTODO("AutoCompletion algorithm is currently not implemented.")]
221 [DesignerSerializationVisibility (DesignerSerializationVisibility
.Content
)]
223 [EditorBrowsable (EditorBrowsableState
.Always
)]
225 [Editor ("System.Windows.Forms.Design.ListControlStringCollectionEditor, " + Consts
.AssemblySystem_Design
,
226 "System.Drawing.Design.UITypeEditor, " + Consts
.AssemblySystem_Drawing
)]
227 public AutoCompleteStringCollection AutoCompleteCustomSource
{
229 if(auto_complete_custom_source
== null) {
230 auto_complete_custom_source
= new AutoCompleteStringCollection ();
231 auto_complete_custom_source
.CollectionChanged
+= new CollectionChangeEventHandler (OnAutoCompleteCustomSourceChanged
);
233 return auto_complete_custom_source
;
236 if(auto_complete_custom_source
== value)
239 if(auto_complete_custom_source
!= null) //remove eventhandler from old collection
240 auto_complete_custom_source
.CollectionChanged
-= new CollectionChangeEventHandler (OnAutoCompleteCustomSourceChanged
);
242 auto_complete_custom_source
= value;
244 if(auto_complete_custom_source
!= null)
245 auto_complete_custom_source
.CollectionChanged
+= new CollectionChangeEventHandler (OnAutoCompleteCustomSourceChanged
);
249 [MonoTODO("AutoCompletion algorithm is currently not implemented.")]
251 [EditorBrowsable (EditorBrowsableState
.Always
)]
252 [DefaultValue (AutoCompleteMode
.None
)]
253 public AutoCompleteMode AutoCompleteMode
{
254 get { return auto_complete_mode; }
256 if(auto_complete_mode
== value)
259 if((value < AutoCompleteMode
.None
) || (value > AutoCompleteMode
.SuggestAppend
))
260 throw new InvalidEnumArgumentException (Locale
.GetText ("Enum argument value '{0}' is not valid for AutoCompleteMode", value));
262 auto_complete_mode
= value;
266 [MonoTODO("AutoCompletion algorithm is currently not implemented.")]
268 [EditorBrowsable (EditorBrowsableState
.Always
)]
269 [DefaultValue (AutoCompleteSource
.None
)]
270 public AutoCompleteSource AutoCompleteSource
{
271 get { return auto_complete_source; }
273 if(auto_complete_source
== value)
276 if(!Enum
.IsDefined (typeof (AutoCompleteSource
), value))
277 throw new InvalidEnumArgumentException (Locale
.GetText ("Enum argument value '{0}' is not valid for AutoCompleteSource", value));
279 auto_complete_source
= value;
283 public override Color BackColor
{
284 get { return base.BackColor; }
286 if (base.BackColor
== value)
288 base.BackColor
= value;
294 [EditorBrowsable (EditorBrowsableState
.Never
)]
295 public override Image BackgroundImage
{
296 get { return base.BackgroundImage; }
298 if (base.BackgroundImage
== value)
300 base.BackgroundImage
= value;
307 [EditorBrowsable (EditorBrowsableState
.Never
)]
308 public override ImageLayout BackgroundImageLayout
{
309 get { return base.BackgroundImageLayout; }
310 set { base.BackgroundImageLayout = value; }
314 protected override CreateParams CreateParams
{
315 get { return base.CreateParams;}
319 [DefaultValue ((string)null)]
320 [AttributeProvider (typeof (IListSource
))]
321 [RefreshProperties (RefreshProperties
.Repaint
)]
322 public new object DataSource
{
323 get { return base.DataSource; }
324 set { base.DataSource = value; }
328 protected override Size DefaultSize
{
329 get { return new Size (121, 21); }
332 [RefreshProperties(RefreshProperties
.Repaint
)]
333 [DefaultValue (DrawMode
.Normal
)]
334 public DrawMode DrawMode
{
335 get { return draw_mode; }
337 if (!Enum
.IsDefined (typeof (DrawMode
), value))
338 throw new InvalidEnumArgumentException (string.Format("Enum argument value '{0}' is not valid for DrawMode", value));
340 if (draw_mode
== value)
343 if (draw_mode
== DrawMode
.OwnerDrawVariable
)
346 if (draw_mode
== DrawMode
.OwnerDrawVariable
)
347 item_heights
= new Hashtable ();
355 [EditorBrowsable (EditorBrowsableState
.Always
)]
356 public int DropDownHeight
{
358 return drop_down_height
;
362 throw new ArgumentOutOfRangeException ("DropDownHeight", "DropDownHeight must be greater than 0.");
364 drop_down_height
= value;
365 IntegralHeight
= false;
370 [DefaultValue (ComboBoxStyle
.DropDown
)]
371 [RefreshProperties(RefreshProperties
.Repaint
)]
372 public ComboBoxStyle DropDownStyle
{
373 get { return dropdown_style; }
375 if (!Enum
.IsDefined (typeof (ComboBoxStyle
), value))
376 throw new InvalidEnumArgumentException (string.Format("Enum argument value '{0}' is not valid for ComboBoxStyle", value));
378 if (dropdown_style
== value)
383 if (dropdown_style
== ComboBoxStyle
.Simple
) {
384 if (listbox_ctrl
!= null) {
385 Controls
.RemoveImplicit (listbox_ctrl
);
386 listbox_ctrl
.Dispose ();
391 dropdown_style
= value;
393 if (dropdown_style
== ComboBoxStyle
.DropDownList
&& textbox_ctrl
!= null) {
394 Controls
.RemoveImplicit (textbox_ctrl
);
395 textbox_ctrl
.Dispose ();
399 if (dropdown_style
== ComboBoxStyle
.Simple
) {
400 show_dropdown_button
= false;
402 CreateComboListBox ();
404 if (IsHandleCreated
) {
405 Controls
.AddImplicit (listbox_ctrl
);
406 listbox_ctrl
.Visible
= true;
409 show_dropdown_button
= true;
410 button_state
= ButtonState
.Normal
;
413 if (dropdown_style
!= ComboBoxStyle
.DropDownList
&& textbox_ctrl
== null) {
414 textbox_ctrl
= new ComboTextBox (this);
415 object selected_item
= SelectedItem
;
416 if (selected_item
!= null)
417 textbox_ctrl
.Text
= GetItemText (selected_item
);
418 textbox_ctrl
.BorderStyle
= BorderStyle
.None
;
419 textbox_ctrl
.TextChanged
+= new EventHandler (OnTextChangedEdit
);
420 textbox_ctrl
.Click
+= new EventHandler (OnTextBoxClick
);
421 textbox_ctrl
.ContextMenu
= ContextMenu
;
423 if (IsHandleCreated
== true)
424 Controls
.AddImplicit (textbox_ctrl
);
428 OnDropDownStyleChanged (EventArgs
.Empty
);
431 UpdateComboBoxBounds ();
436 public int DropDownWidth
{
438 if (dropdown_width
== -1)
441 return dropdown_width
;
444 if (dropdown_width
== value)
449 throw new ArgumentOutOfRangeException ("DropDownWidth",
450 "The DropDownWidth value is less than one.");
452 throw new ArgumentException ("The DropDownWidth value is less than one.");
455 dropdown_width
= value;
460 [DesignerSerializationVisibility (DesignerSerializationVisibility
.Hidden
)]
461 public bool DroppedDown
{
463 if (dropdown_style
== ComboBoxStyle
.Simple
)
469 if (dropdown_style
== ComboBoxStyle
.Simple
|| dropped_down
== value)
475 listbox_ctrl
.Hide ();
480 [DefaultValue (FlatStyle
.Standard
)]
482 public FlatStyle FlatStyle
{
483 get { return flat_style; }
485 if (!Enum
.IsDefined (typeof (FlatStyle
), value))
486 throw new InvalidEnumArgumentException ("FlatStyle", (int) value, typeof (FlatStyle
));
495 public override bool Focused
{
496 get { return base.Focused; }
499 public override Color ForeColor
{
500 get { return base.ForeColor; }
502 if (base.ForeColor
== value)
504 base.ForeColor
= value;
509 [DefaultValue (true)]
511 public bool IntegralHeight
{
512 get { return integral_height; }
514 if (integral_height
== value)
516 integral_height
= value;
517 UpdateComboBoxBounds ();
523 public int ItemHeight
{
525 if (item_height
== -1) {
526 SizeF sz
= DeviceContext
.MeasureString ("The quick brown Fox", Font
);
527 item_height
= (int) sz
.Height
;
534 throw new ArgumentOutOfRangeException ("ItemHeight",
535 "The item height value is less than one.");
537 throw new ArgumentException ("The item height value is less than one.");
540 item_height_specified
= true;
543 UpdateComboBoxBounds ();
549 [DesignerSerializationVisibility (DesignerSerializationVisibility
.Content
)]
551 [Editor ("System.Windows.Forms.Design.ListControlStringCollectionEditor, " + Consts
.AssemblySystem_Design
, typeof (System
.Drawing
.Design
.UITypeEditor
))]
553 [MergableProperty (false)]
555 public ComboBox
.ObjectCollection Items
{
556 get { return items; }
561 public int MaxDropDownItems
{
562 get { return maxdrop_items; }
564 if (maxdrop_items
== value)
566 maxdrop_items
= value;
571 public override Size MaximumSize
{
572 get { return base.MaximumSize; }
574 base.MaximumSize
= new Size (value.Width
, 0);
581 public int MaxLength
{
582 get { return max_length; }
584 if (max_length
== value)
589 if (dropdown_style
!= ComboBoxStyle
.DropDownList
) {
593 textbox_ctrl
.MaxLength
= value;
599 public override Size MinimumSize
{
600 get { return base.MinimumSize; }
602 base.MinimumSize
= new Size (value.Width
, 0);
606 [DesignerSerializationVisibility (DesignerSerializationVisibility
.Hidden
)]
607 [EditorBrowsable (EditorBrowsableState
.Never
)]
609 public new Padding Padding
{
610 get { return base.Padding; }
611 set { base.Padding = value; }
615 [DesignerSerializationVisibility (DesignerSerializationVisibility
.Hidden
)]
617 public int PreferredHeight
{
619 return ItemHeight
+ 6;
624 [DesignerSerializationVisibility (DesignerSerializationVisibility
.Hidden
)]
625 public override int SelectedIndex
{
626 get { return selected_index; }
628 if (selected_index
== value)
631 if (value <= -2 || value >= Items
.Count
)
632 throw new ArgumentOutOfRangeException ("SelectedIndex");
633 selected_index
= value;
635 if (dropdown_style
!= ComboBoxStyle
.DropDownList
) {
639 SetControlText (GetItemText (Items
[value]));
642 if (DropDownStyle
== ComboBoxStyle
.DropDownList
)
645 if (listbox_ctrl
!= null)
646 listbox_ctrl
.HighlightedIndex
= value;
648 OnSelectedValueChanged (new EventArgs ());
649 OnSelectedIndexChanged (new EventArgs ());
650 OnSelectedItemChanged (new EventArgs ());
655 [DesignerSerializationVisibility (DesignerSerializationVisibility
.Hidden
)]
657 public object SelectedItem
{
658 get { return selected_index == -1 ? null : Items [selected_index]; }
660 object item
= selected_index
== -1 ? null : Items
[selected_index
];
663 SelectedIndex
= Items
.IndexOf (value);
668 [DesignerSerializationVisibility (DesignerSerializationVisibility
.Hidden
)]
669 public string SelectedText
{
671 if (dropdown_style
== ComboBoxStyle
.DropDownList
)
674 return textbox_ctrl
.SelectedText
;
677 if (dropdown_style
== ComboBoxStyle
.DropDownList
)
679 textbox_ctrl
.SelectedText
= value;
684 [DesignerSerializationVisibility (DesignerSerializationVisibility
.Hidden
)]
685 public int SelectionLength
{
687 if (dropdown_style
== ComboBoxStyle
.DropDownList
)
690 int result
= textbox_ctrl
.SelectionLength
;
691 return result
== -1 ? 0 : result
;
694 if (dropdown_style
== ComboBoxStyle
.DropDownList
)
696 if (textbox_ctrl
.SelectionLength
== value)
698 textbox_ctrl
.SelectionLength
= value;
703 [DesignerSerializationVisibility (DesignerSerializationVisibility
.Hidden
)]
704 public int SelectionStart
{
706 if (dropdown_style
== ComboBoxStyle
.DropDownList
)
708 return textbox_ctrl
.SelectionStart
;
711 if (dropdown_style
== ComboBoxStyle
.DropDownList
)
713 if (textbox_ctrl
.SelectionStart
== value)
715 textbox_ctrl
.SelectionStart
= value;
719 [DefaultValue (false)]
721 get { return sorted; }
736 public override string Text
{
738 if (dropdown_style
!= ComboBoxStyle
.DropDownList
) {
739 if (textbox_ctrl
!= null) {
740 return textbox_ctrl
.Text
;
744 if (SelectedItem
!= null)
745 return GetItemText (SelectedItem
);
751 if (SelectedIndex
== -1) {
752 if (dropdown_style
!= ComboBoxStyle
.DropDownList
)
760 // do nothing if value exactly matches text of selected item
761 if (SelectedItem
!= null && string.Compare (value, GetItemText (SelectedItem
), false, CultureInfo
.CurrentCulture
) == 0)
764 // find exact match using case-sensitive comparison, and if does
765 // not result in any match then use case-insensitive comparison
766 int index
= FindStringExact (value, -1, false);
768 index
= FindStringExact (value, -1, true);
771 SelectedIndex
= index
;
775 if (dropdown_style
!= ComboBoxStyle
.DropDownList
)
776 textbox_ctrl
.Text
= GetItemText (value);
780 #endregion Public Properties
782 #region Public Methods
784 [Obsolete ("This method has been deprecated")]
786 protected virtual void AddItemsCore (object[] value)
791 public void BeginUpdate ()
793 suspend_ctrlupdate
= true;
797 protected override AccessibleObject
CreateAccessibilityInstance ()
799 return base.CreateAccessibilityInstance ();
802 protected override void CreateHandle ()
804 base.CreateHandle ();
808 protected override void Dispose (bool disposing
)
811 if (listbox_ctrl
!= null) {
812 listbox_ctrl
.Dispose ();
813 Controls
.RemoveImplicit (listbox_ctrl
);
817 if (textbox_ctrl
!= null) {
818 Controls
.RemoveImplicit (textbox_ctrl
);
819 textbox_ctrl
.Dispose ();
824 base.Dispose (disposing
);
827 public void EndUpdate ()
829 suspend_ctrlupdate
= false;
834 public int FindString (string s
)
836 return FindString (s
, -1);
839 public int FindString (string s
, int startIndex
)
841 if (s
== null || Items
.Count
== 0)
845 if (startIndex
< -1 || startIndex
>= Items
.Count
)
847 if (startIndex
< -1 || startIndex
>= Items
.Count
- 1)
849 throw new ArgumentOutOfRangeException ("startIndex");
853 if (i
== (Items
.Count
- 1))
858 if (string.Compare (s
, 0, GetItemText (Items
[i
]), 0, s
.Length
, true) == 0)
860 if (i
== (Items
.Count
- 1))
862 } while (i
!= startIndex
);
867 public int FindStringExact (string s
)
869 return FindStringExact (s
, -1);
872 public int FindStringExact (string s
, int startIndex
)
874 return FindStringExact (s
, startIndex
, true);
877 private int FindStringExact (string s
, int startIndex
, bool ignoreCase
)
879 if (s
== null || Items
.Count
== 0)
883 if (startIndex
< -1 || startIndex
>= Items
.Count
)
885 if (startIndex
< -1 || startIndex
>= Items
.Count
- 1)
887 throw new ArgumentOutOfRangeException ("startIndex");
891 if (i
== (Items
.Count
- 1))
896 if (string.Compare (s
, GetItemText (Items
[i
]), ignoreCase
, CultureInfo
.CurrentCulture
) == 0)
898 if (i
== (Items
.Count
- 1))
900 } while (i
!= startIndex
);
905 public int GetItemHeight (int index
)
907 if (DrawMode
== DrawMode
.OwnerDrawVariable
&& IsHandleCreated
) {
909 if (index
< 0 || index
>= Items
.Count
)
910 throw new ArgumentOutOfRangeException ("The item height value is less than zero");
912 object item
= Items
[index
];
913 if (item_heights
.Contains (item
))
914 return (int) item_heights
[item
];
916 MeasureItemEventArgs args
= new MeasureItemEventArgs (DeviceContext
, index
, ItemHeight
);
917 OnMeasureItem (args
);
918 item_heights
[item
] = args
.ItemHeight
;
919 return args
.ItemHeight
;
925 protected override bool IsInputKey (Keys keyData
)
927 switch (keyData
& ~Keys
.Modifiers
) {
943 protected override void OnBackColorChanged (EventArgs e
)
945 base.OnBackColorChanged (e
);
947 if (textbox_ctrl
!= null)
948 textbox_ctrl
.BackColor
= BackColor
;
951 protected override void OnDataSourceChanged (EventArgs e
)
953 base.OnDataSourceChanged (e
);
956 if (DataSource
== null || DataManager
== null) {
960 SelectedIndex
= DataManager
.Position
;
964 protected override void OnDisplayMemberChanged (EventArgs e
)
966 base.OnDisplayMemberChanged (e
);
968 if (DataManager
== null || !IsHandleCreated
)
972 SelectedIndex
= DataManager
.Position
;
975 protected virtual void OnDrawItem (DrawItemEventArgs e
)
978 case DrawMode
.OwnerDrawFixed
:
979 case DrawMode
.OwnerDrawVariable
:
980 DrawItemEventHandler eh
= (DrawItemEventHandler
)(Events
[DrawItemEvent
]);
985 ThemeEngine
.Current
.DrawComboBoxItem (this, e
);
990 protected virtual void OnDropDown (EventArgs e
)
992 EventHandler eh
= (EventHandler
)(Events
[DropDownEvent
]);
998 protected virtual void OnDropDownClosed (EventArgs e
)
1000 EventHandler eh
= (EventHandler
) Events
[DropDownClosedEvent
];
1006 protected virtual void OnDropDownStyleChanged (EventArgs e
)
1008 EventHandler eh
= (EventHandler
)(Events
[DropDownStyleChangedEvent
]);
1013 protected override void OnFontChanged (EventArgs e
)
1015 base.OnFontChanged (e
);
1017 if (textbox_ctrl
!= null)
1018 textbox_ctrl
.Font
= Font
;
1020 if (!item_height_specified
) {
1021 SizeF sz
= DeviceContext
.MeasureString ("The quick brown Fox", Font
);
1022 item_height
= (int) sz
.Height
;
1026 UpdateComboBoxBounds ();
1031 protected override void OnForeColorChanged (EventArgs e
)
1033 base.OnForeColorChanged (e
);
1034 if (textbox_ctrl
!= null)
1035 textbox_ctrl
.ForeColor
= ForeColor
;
1038 [EditorBrowsable(EditorBrowsableState
.Advanced
)]
1039 protected override void OnGotFocus (EventArgs e
)
1041 if (dropdown_style
== ComboBoxStyle
.DropDownList
) {
1042 // We draw DDL styles manually, so they require a
1043 // refresh to have their selection drawn
1047 if (textbox_ctrl
!= null) {
1048 textbox_ctrl
.SetSelectable (false);
1049 textbox_ctrl
.ShowSelection
= true;
1050 textbox_ctrl
.ActivateCaret (true);
1051 textbox_ctrl
.SelectAll ();
1054 base.OnGotFocus (e
);
1057 [EditorBrowsable(EditorBrowsableState
.Advanced
)]
1058 protected override void OnLostFocus (EventArgs e
)
1060 if (dropdown_style
== ComboBoxStyle
.DropDownList
) {
1061 // We draw DDL styles manually, so they require a
1062 // refresh to have their selection drawn
1066 if (listbox_ctrl
!= null && dropped_down
) {
1067 listbox_ctrl
.HideWindow ();
1070 if (textbox_ctrl
!= null) {
1071 textbox_ctrl
.SetSelectable (true);
1072 textbox_ctrl
.ActivateCaret (false);
1073 textbox_ctrl
.ShowSelection
= false;
1076 base.OnLostFocus (e
);
1079 protected override void OnHandleCreated (EventArgs e
)
1081 base.OnHandleCreated (e
);
1083 if (listbox_ctrl
!= null) {
1084 Controls
.AddImplicit (listbox_ctrl
);
1085 listbox_ctrl
.Visible
= true;
1088 if (textbox_ctrl
!= null)
1089 Controls
.AddImplicit (textbox_ctrl
);
1094 protected override void OnHandleDestroyed (EventArgs e
)
1096 base.OnHandleDestroyed (e
);
1099 protected override void OnKeyPress (KeyPressEventArgs e
)
1101 // int index = FindStringCaseInsensitive (e.KeyChar.ToString (), SelectedIndex);
1103 // SelectedIndex = index;
1105 base.OnKeyPress (e
);
1108 protected virtual void OnMeasureItem (MeasureItemEventArgs e
)
1110 MeasureItemEventHandler eh
= (MeasureItemEventHandler
)(Events
[MeasureItemEvent
]);
1115 protected override void OnParentBackColorChanged (EventArgs e
)
1117 base.OnParentBackColorChanged (e
);
1120 protected override void OnResize (EventArgs e
)
1123 if (listbox_ctrl
!= null)
1124 listbox_ctrl
.CalcListBoxArea ();
1127 protected override void OnSelectedIndexChanged (EventArgs e
)
1129 base.OnSelectedIndexChanged (e
);
1131 EventHandler eh
= (EventHandler
)(Events
[SelectedIndexChangedEvent
]);
1136 protected virtual void OnSelectedItemChanged (EventArgs e
)
1140 protected override void OnSelectedValueChanged (EventArgs e
)
1142 base.OnSelectedValueChanged (e
);
1145 protected virtual void OnSelectionChangeCommitted (EventArgs e
)
1147 EventHandler eh
= (EventHandler
)(Events
[SelectionChangeCommittedEvent
]);
1152 protected override void RefreshItem (int index
)
1154 if (index
< 0 || index
>= Items
.Count
)
1155 throw new ArgumentOutOfRangeException ("index");
1157 if (draw_mode
== DrawMode
.OwnerDrawVariable
)
1158 item_heights
.Remove (Items
[index
]);
1162 public override void ResetText ()
1164 Text
= String
.Empty
;
1167 protected override bool ProcessKeyEventArgs (ref Message m
)
1169 return base.ProcessKeyEventArgs (ref m
);
1172 [EditorBrowsable (EditorBrowsableState
.Advanced
)]
1173 protected override void OnKeyDown (KeyEventArgs e
)
1178 [EditorBrowsable (EditorBrowsableState
.Advanced
)]
1179 protected override void OnValidating (CancelEventArgs e
)
1181 base.OnValidating (e
);
1184 [EditorBrowsable (EditorBrowsableState
.Advanced
)]
1185 protected override void OnTextChanged (EventArgs e
)
1187 base.OnTextChanged (e
);
1191 protected virtual void OnTextUpdate (EventArgs e
)
1193 EventHandler eh
= (EventHandler
) Events
[TextUpdateEvent
];
1198 protected override void OnMouseLeave (EventArgs e
)
1201 if (flat_style
== FlatStyle
.Popup
)
1204 base.OnMouseLeave (e
);
1207 protected override void OnMouseEnter (EventArgs e
)
1210 if (flat_style
== FlatStyle
.Popup
)
1213 base.OnMouseEnter (e
);
1217 public void Select (int start
, int length
)
1220 throw new ArgumentException ("Start cannot be less than zero");
1223 throw new ArgumentException ("length cannot be less than zero");
1225 if (dropdown_style
== ComboBoxStyle
.DropDownList
)
1228 textbox_ctrl
.Select (start
, length
);
1231 public void SelectAll ()
1233 if (dropdown_style
== ComboBoxStyle
.DropDownList
)
1236 if (textbox_ctrl
!= null) {
1237 textbox_ctrl
.ShowSelection
= true;
1238 textbox_ctrl
.SelectAll ();
1242 protected override void SetBoundsCore (int x
, int y
, int width
, int height
, BoundsSpecified specified
)
1244 if ((specified
& BoundsSpecified
.Height
) != 0) {
1245 requested_height
= height
;
1247 if (DropDownStyle
== ComboBoxStyle
.Simple
&& height
> PreferredHeight
) {
1248 if (IntegralHeight
) {
1249 int border
= ThemeEngine
.Current
.Border3DSize
.Height
;
1250 int lb_height
= height
- PreferredHeight
- 2;
1251 if (lb_height
- 2 * border
> ItemHeight
) {
1252 int partial = (lb_height
- 2 * border
) % ItemHeight
;
1255 height
= PreferredHeight
;
1258 height
= PreferredHeight
;
1261 base.SetBoundsCore (x
, y
, width
, height
, specified
);
1264 protected override void SetItemCore (int index
, object value)
1266 if (index
< 0 || index
>= Items
.Count
)
1269 Items
[index
] = value;
1272 protected override void SetItemsCore (IList
value)
1277 Items
.AddRange (value);
1283 public override string ToString ()
1285 return base.ToString () + ", Items.Count:" + Items
.Count
;
1288 protected override void WndProc (ref Message m
)
1290 switch ((Msg
) m
.Msg
) {
1292 case Msg
.WM_KEYDOWN
:
1293 Keys keys
= (Keys
) m
.WParam
.ToInt32 ();
1294 if (keys
== Keys
.Up
|| keys
== Keys
.Down
)
1296 goto case Msg
.WM_CHAR
;
1298 if (textbox_ctrl
!= null)
1299 XplatUI
.SendMessage (textbox_ctrl
.Handle
, (Msg
) m
.Msg
, m
.WParam
, m
.LParam
);
1301 case Msg
.WM_MOUSELEAVE
:
1302 Point location
= PointToClient (Control
.MousePosition
);
1303 if (ClientRectangle
.Contains (location
))
1309 base.WndProc (ref m
);
1312 #endregion Public Methods
1314 #region Private Methods
1316 void OnAutoCompleteCustomSourceChanged(object sender
, CollectionChangeEventArgs e
) {
1317 if(auto_complete_source
== AutoCompleteSource
.CustomSource
) {
1318 //FIXME: handle add, remove and refresh events in AutoComplete algorithm.
1323 internal override bool InternalCapture
{
1324 get { return Capture; }
1328 void LayoutComboBox ()
1330 int border
= ThemeEngine
.Current
.Border3DSize
.Width
;
1332 text_area
= ClientRectangle
;
1333 text_area
.Height
= PreferredHeight
;
1335 listbox_area
= ClientRectangle
;
1336 listbox_area
.Y
= text_area
.Bottom
+ 3;
1337 listbox_area
.Height
-= (text_area
.Height
+ 2);
1339 Rectangle prev_button_area
= button_area
;
1341 if (DropDownStyle
== ComboBoxStyle
.Simple
)
1342 button_area
= Rectangle
.Empty
;
1344 button_area
= text_area
;
1345 button_area
.X
= text_area
.Right
- button_width
- border
;
1346 button_area
.Y
= text_area
.Y
+ border
;
1347 button_area
.Width
= button_width
;
1348 button_area
.Height
= text_area
.Height
- 2 * border
;
1350 if (flat_style
== FlatStyle
.Popup
|| flat_style
== FlatStyle
.Flat
) {
1351 button_area
.Inflate (1, 1);
1353 button_area
.Width
-= 2;
1358 if (button_area
!= prev_button_area
) {
1359 prev_button_area
.Y
-= border
;
1360 prev_button_area
.Width
+= border
;
1361 prev_button_area
.Height
+= 2 * border
;
1362 Invalidate (prev_button_area
);
1363 Invalidate (button_area
);
1366 if (textbox_ctrl
!= null) {
1367 int text_border
= border
+ 1;
1368 textbox_ctrl
.Location
= new Point (text_area
.X
+ text_border
, text_area
.Y
+ text_border
);
1369 textbox_ctrl
.Width
= text_area
.Width
- button_area
.Width
- text_border
* 2;
1370 textbox_ctrl
.Height
= text_area
.Height
- text_border
* 2;
1373 if (listbox_ctrl
!= null && dropdown_style
== ComboBoxStyle
.Simple
) {
1374 listbox_ctrl
.Location
= listbox_area
.Location
;
1375 listbox_ctrl
.CalcListBoxArea ();
1379 private void CreateComboListBox ()
1381 listbox_ctrl
= new ComboListBox (this);
1382 listbox_ctrl
.HighlightedIndex
= SelectedIndex
;
1385 internal void Draw (Rectangle clip
, Graphics dc
)
1387 Theme theme
= ThemeEngine
.Current
;
1388 FlatStyle style
= FlatStyle
.Standard
;
1389 bool is_flat
= false;
1392 style
= this.FlatStyle
;
1393 is_flat
= style
== FlatStyle
.Flat
|| style
== FlatStyle
.Popup
;
1396 if (DropDownStyle
== ComboBoxStyle
.Simple
)
1397 dc
.FillRectangle (theme
.ResPool
.GetSolidBrush (Parent
.BackColor
), ClientRectangle
);
1399 if (style
== FlatStyle
.Popup
&& (is_entered
|| Focused
)) {
1400 Rectangle area
= text_area
;
1403 dc
.DrawRectangle (theme
.ResPool
.GetPen (SystemColors
.ControlDark
), area
);
1404 dc
.DrawLine (theme
.ResPool
.GetPen (SystemColors
.ControlDark
), button_area
.X
- 1, button_area
.Top
, button_area
.X
- 1, button_area
.Bottom
);
1406 if (!is_flat
&& clip
.IntersectsWith (text_area
))
1407 ControlPaint
.DrawBorder3D (dc
, text_area
, Border3DStyle
.Sunken
);
1409 int border
= theme
.Border3DSize
.Width
;
1411 // No edit control, we paint the edit ourselves
1412 if (dropdown_style
== ComboBoxStyle
.DropDownList
) {
1413 DrawItemState state
= DrawItemState
.None
;
1414 Rectangle item_rect
= text_area
;
1415 item_rect
.X
+= border
;
1416 item_rect
.Y
+= border
;
1417 item_rect
.Width
-= (button_area
.Width
+ 2 * border
);
1418 item_rect
.Height
-= 2 * border
;
1421 state
= DrawItemState
.Selected
;
1422 state
|= DrawItemState
.Focus
;
1425 state
|= DrawItemState
.ComboBoxEdit
;
1426 OnDrawItem (new DrawItemEventArgs (dc
, Font
, item_rect
, SelectedIndex
, state
, ForeColor
, BackColor
));
1429 if (show_dropdown_button
) {
1430 dc
.FillRectangle (theme
.ResPool
.GetSolidBrush (theme
.ColorControl
), button_area
);
1433 button_state
= ButtonState
.Inactive
;
1436 theme
.DrawFlatStyleComboButton (dc
, button_area
, button_state
);
1438 theme
.CPDrawComboButton (dc
, button_area
, button_state
);
1443 internal void DropDownListBox ()
1445 if (DropDownStyle
== ComboBoxStyle
.Simple
)
1448 if (listbox_ctrl
== null)
1449 CreateComboListBox ();
1451 listbox_ctrl
.Location
= PointToScreen (new Point (text_area
.X
, text_area
.Y
+ text_area
.Height
));
1453 if (listbox_ctrl
.ShowWindow ())
1454 dropped_down
= true;
1456 button_state
= ButtonState
.Pushed
;
1457 if (dropdown_style
== ComboBoxStyle
.DropDownList
)
1458 Invalidate (text_area
);
1461 internal void DropDownListBoxFinished ()
1463 if (DropDownStyle
== ComboBoxStyle
.Simple
)
1466 button_state
= ButtonState
.Normal
;
1467 Invalidate (button_area
);
1468 dropped_down
= false;
1470 OnDropDownClosed (EventArgs
.Empty
);
1474 private int FindStringCaseInsensitive (string search
)
1476 if (search
.Length
== 0) {
1480 for (int i
= 0; i
< Items
.Count
; i
++)
1482 if (String
.Compare (GetItemText (Items
[i
]), 0, search
, 0, search
.Length
, true) == 0)
1489 internal int FindStringCaseInsensitive (string search
, int start_index
)
1491 if (search
.Length
== 0) {
1495 for (int i
= 0; i
< Items
.Count
; i
++) {
1496 int index
= (i
+ start_index
) % Items
.Count
;
1497 if (String
.Compare (GetItemText (Items
[index
]), 0, search
, 0, search
.Length
, true) == 0)
1504 internal override ContextMenu ContextMenuInternal
{
1506 return base.ContextMenuInternal
;
1509 base.ContextMenuInternal
= value;
1510 if (textbox_ctrl
!= null) {
1511 textbox_ctrl
.ContextMenu
= value;
1516 private void OnKeyDownCB(object sender
, KeyEventArgs e
)
1518 if (Items
.Count
== 0)
1524 SelectedIndex
= Math
.Max(SelectedIndex
-1, 0);
1528 SelectedIndex
= Math
.Min(SelectedIndex
+1, Items
.Count
-1);
1532 if (listbox_ctrl
!= null)
1533 SelectedIndex
= Math
.Max(SelectedIndex
- (listbox_ctrl
.page_size
-1), 0);
1537 if (listbox_ctrl
!= null)
1538 SelectedIndex
= Math
.Min(SelectedIndex
+(listbox_ctrl
.page_size
-1), Items
.Count
-1);
1546 void OnMouseDownCB (object sender
, MouseEventArgs e
)
1549 if (DropDownStyle
== ComboBoxStyle
.DropDownList
)
1550 area
= ClientRectangle
;
1554 if (area
.Contains (e
.X
, e
.Y
)) {
1556 Invalidate (button_area
);
1562 void OnMouseMoveCB (object sender
, MouseEventArgs e
)
1564 if (DropDownStyle
== ComboBoxStyle
.Simple
)
1567 if (listbox_ctrl
!= null && listbox_ctrl
.Visible
) {
1568 Point location
= listbox_ctrl
.PointToClient (Control
.MousePosition
);
1569 if (listbox_ctrl
.ClientRectangle
.Contains (location
))
1570 listbox_ctrl
.Capture
= true;
1574 void OnMouseUpCB (object sender
, MouseEventArgs e
)
1577 OnClick (EventArgs
.Empty
);
1580 listbox_ctrl
.Capture
= true;
1583 private void OnMouseWheelCB (object sender
, MouseEventArgs me
)
1585 if (Items
.Count
== 0)
1588 if (listbox_ctrl
!= null && listbox_ctrl
.Visible
) {
1589 int lines
= me
.Delta
/ 120 * SystemInformation
.MouseWheelScrollLines
;
1590 listbox_ctrl
.Scroll (-lines
);
1592 int lines
= me
.Delta
/ 120;
1593 int index
= SelectedIndex
- lines
;
1596 else if (index
>= Items
.Count
)
1597 index
= Items
.Count
- 1;
1598 SelectedIndex
= index
;
1602 internal override void OnPaintInternal (PaintEventArgs pevent
)
1604 if (suspend_ctrlupdate
)
1607 Draw (ClientRectangle
, pevent
.Graphics
);
1610 private void OnTextBoxClick (object sender
, EventArgs e
)
1615 private void OnTextChangedEdit (object sender
, EventArgs e
)
1617 if (process_textchanged_event
== false)
1620 OnTextChanged (EventArgs
.Empty
);
1622 int item
= FindStringCaseInsensitive (textbox_ctrl
.Text
);
1627 // TODO: THIS IS BROKEN-ISH
1628 // I don't think we should hilight, and setting the top item does weirdness
1629 // when there is no scrollbar
1631 if (listbox_ctrl
!= null) {
1632 listbox_ctrl
.SetTopItem (item
);
1633 listbox_ctrl
.HighlightedIndex
= item
;
1636 base.Text
= textbox_ctrl
.Text
;
1639 internal void SetControlText (string s
)
1641 process_textchanged_event
= false;
1642 textbox_ctrl
.Text
= s
;
1643 process_textchanged_event
= true;
1646 void UpdateComboBoxBounds ()
1648 if (requested_height
== -1)
1651 // Save the requested height since set bounds can destroy it
1652 int save_height
= requested_height
;
1653 SetBounds (bounds
.X
, bounds
.Y
, bounds
.Width
, requested_height
, BoundsSpecified
.Height
);
1654 requested_height
= save_height
;
1657 private void UpdatedItems ()
1659 if (listbox_ctrl
!= null) {
1660 listbox_ctrl
.UpdateLastVisibleItem ();
1661 listbox_ctrl
.CalcListBoxArea ();
1662 listbox_ctrl
.Refresh ();
1666 #endregion Private Methods
1668 [ListBindableAttribute (false)]
1669 public class ObjectCollection
: IList
, ICollection
, IEnumerable
1672 private ComboBox owner
;
1673 internal ArrayList object_items
= new ArrayList ();
1675 public ObjectCollection (ComboBox owner
)
1680 #region Public Properties
1682 get { return object_items.Count; }
1685 public bool IsReadOnly
{
1686 get { return false; }
1690 [DesignerSerializationVisibility(DesignerSerializationVisibility
.Hidden
)]
1691 public virtual object this [int index
] {
1693 if (index
< 0 || index
>= Count
)
1694 throw new ArgumentOutOfRangeException ("index");
1696 return object_items
[index
];
1699 if (index
< 0 || index
>= Count
)
1700 throw new ArgumentOutOfRangeException ("index");
1702 throw new ArgumentNullException ("value");
1704 object_items
[index
] = value;
1705 if (owner
.listbox_ctrl
!= null)
1706 owner
.listbox_ctrl
.InvalidateItem (index
);
1707 if (index
== owner
.SelectedIndex
) {
1708 if (owner
.textbox_ctrl
== null)
1711 owner
.textbox_ctrl
.SelectedText
= value.ToString ();
1716 bool ICollection
.IsSynchronized
{
1717 get { return false; }
1720 object ICollection
.SyncRoot
{
1721 get { return this; }
1724 bool IList
.IsFixedSize
{
1725 get { return false; }
1728 #endregion Public Properties
1730 #region Public Methods
1731 public int Add (object item
)
1735 idx
= AddItem (item
);
1736 owner
.UpdatedItems ();
1740 public void AddRange (object[] items
)
1743 throw new ArgumentNullException ("items");
1745 foreach (object mi
in items
)
1748 owner
.UpdatedItems ();
1751 public void Clear ()
1753 owner
.selected_index
= -1;
1754 object_items
.Clear ();
1755 owner
.UpdatedItems ();
1759 public bool Contains (object value)
1762 throw new ArgumentNullException ("value");
1764 return object_items
.Contains (value);
1767 public void CopyTo (object[] dest
, int arrayIndex
)
1769 object_items
.CopyTo (dest
, arrayIndex
);
1772 void ICollection
.CopyTo (Array dest
, int index
)
1774 object_items
.CopyTo (dest
, index
);
1777 public IEnumerator
GetEnumerator ()
1779 return object_items
.GetEnumerator ();
1782 int IList
.Add (object item
)
1787 public int IndexOf (object value)
1790 throw new ArgumentNullException ("value");
1792 return object_items
.IndexOf (value);
1795 public void Insert (int index
, object item
)
1797 if (index
< 0 || index
> Count
)
1798 throw new ArgumentOutOfRangeException ("index");
1800 throw new ArgumentNullException ("item");
1802 owner
.BeginUpdate ();
1807 object_items
.Insert (index
, item
);
1809 owner
.EndUpdate (); // Calls UpdatedItems
1812 public void Remove (object value)
1817 if (IndexOf (value) == owner
.SelectedIndex
)
1818 owner
.SelectedIndex
= -1;
1820 RemoveAt (IndexOf (value));
1823 public void RemoveAt (int index
)
1825 if (index
< 0 || index
>= Count
)
1826 throw new ArgumentOutOfRangeException ("index");
1828 if (index
== owner
.SelectedIndex
)
1829 owner
.SelectedIndex
= -1;
1831 object_items
.RemoveAt (index
);
1832 owner
.UpdatedItems ();
1834 #endregion Public Methods
1836 #region Private Methods
1837 private int AddItem (object item
)
1840 throw new ArgumentNullException ("item");
1844 foreach (object o
in object_items
) {
1845 if (String
.Compare (item
.ToString (), o
.ToString ()) < 0) {
1846 object_items
.Insert (index
, item
);
1852 object_items
.Add (item
);
1853 return object_items
.Count
- 1;
1856 internal void AddRange (IList items
)
1858 foreach (object mi
in items
)
1861 owner
.UpdatedItems ();
1864 internal void Sort ()
1866 object_items
.Sort ();
1869 #endregion Private Methods
1872 internal class ComboTextBox
: TextBox
{
1874 private ComboBox owner
;
1876 public ComboTextBox (ComboBox owner
)
1879 ShowSelection
= false;
1882 internal void SetSelectable (bool selectable
)
1884 SetStyle (ControlStyles
.Selectable
, selectable
);
1887 internal void ActivateCaret (bool active
)
1890 document
.CaretHasFocus ();
1892 document
.CaretLostFocus ();
1896 internal override void OnTextUpdate ()
1898 base.OnTextUpdate ();
1899 owner
.OnTextUpdate (EventArgs
.Empty
);
1903 protected override void OnGotFocus (EventArgs e
)
1905 owner
.Select (false, true);
1908 protected override void OnLostFocus (EventArgs e
)
1910 owner
.Select (false, true);
1913 public override bool Focused
{
1915 return owner
.Focused
;
1919 internal override bool ActivateOnShow { get { return false; }
}
1922 internal class ComboListBox
: Control
1924 private ComboBox owner
;
1925 private VScrollBarLB vscrollbar_ctrl
;
1926 private int top_item
; /* First item that we show the in the current page */
1927 private int last_item
; /* Last visible item */
1928 internal int page_size
; /* Number of listbox items per page */
1929 private Rectangle textarea_drawable
; /* Rectangle of the drawable text area */
1931 internal enum ItemNavigation
1941 class VScrollBarLB
: VScrollBar
1943 public VScrollBarLB ()
1947 internal override bool InternalCapture
{
1948 get { return Capture; }
1952 public void FireMouseDown (MouseEventArgs e
)
1957 e
= TranslateEvent (e
);
1961 public void FireMouseUp (MouseEventArgs e
)
1966 e
= TranslateEvent (e
);
1970 public void FireMouseMove (MouseEventArgs e
)
1975 e
= TranslateEvent (e
);
1979 MouseEventArgs
TranslateEvent (MouseEventArgs e
)
1981 Point loc
= PointToClient (Control
.MousePosition
);
1982 return new MouseEventArgs (e
.Button
, e
.Clicks
, loc
.X
, loc
.Y
, e
.Delta
);
1986 public ComboListBox (ComboBox owner
)
1993 MouseWheel
+= new MouseEventHandler (OnMouseWheelCLB
);
1995 SetStyle (ControlStyles
.UserPaint
| ControlStyles
.AllPaintingInWmPaint
, true);
1996 SetStyle (ControlStyles
.ResizeRedraw
| ControlStyles
.Opaque
, true);
1998 this.is_visible
= false;
2000 if (owner
.DropDownStyle
== ComboBoxStyle
.Simple
)
2001 InternalBorderStyle
= BorderStyle
.Fixed3D
;
2003 InternalBorderStyle
= BorderStyle
.FixedSingle
;
2006 protected override CreateParams CreateParams
2009 CreateParams cp
= base.CreateParams
;
2010 if (owner
== null || owner
.DropDownStyle
== ComboBoxStyle
.Simple
)
2013 cp
.Style ^
= (int)WindowStyles
.WS_CHILD
;
2014 cp
.Style ^
= (int)WindowStyles
.WS_VISIBLE
;
2015 cp
.Style
|= (int)WindowStyles
.WS_POPUP
;
2016 cp
.ExStyle
|= (int) WindowExStyles
.WS_EX_TOOLWINDOW
| (int) WindowExStyles
.WS_EX_TOPMOST
;
2021 protected override void Select (bool directed
, bool forward
)
2023 // Do nothing, we never want to be selected
2026 internal override bool InternalCapture
{
2035 internal override bool ActivateOnShow { get { return false; }
}
2036 #region Private Methods
2038 // Calcs the listbox area
2039 internal void CalcListBoxArea ()
2042 bool show_scrollbar
= false;
2044 if (owner
.DropDownStyle
== ComboBoxStyle
.Simple
) {
2045 Rectangle area
= owner
.listbox_area
;
2047 height
= area
.Height
;
2049 else { // DropDown or DropDownList
2051 width
= owner
.DropDownWidth
;
2052 int count
= (owner
.Items
.Count
<= owner
.MaxDropDownItems
) ? owner
.Items
.Count
: owner
.MaxDropDownItems
;
2054 if (owner
.DrawMode
== DrawMode
.OwnerDrawVariable
) {
2056 for (int i
= 0; i
< count
; i
++) {
2057 height
+= owner
.GetItemHeight (i
);
2062 height
= owner
.DropDownHeight
;
2064 height
= owner
.ItemHeight
* count
;
2069 page_size
= height
/ owner
.ItemHeight
;
2071 if (owner
.Items
.Count
<= owner
.MaxDropDownItems
) {
2072 if (vscrollbar_ctrl
!= null)
2073 vscrollbar_ctrl
.Visible
= false;
2075 /* Need vertical scrollbar */
2076 if (vscrollbar_ctrl
== null) {
2077 vscrollbar_ctrl
= new VScrollBarLB ();
2078 vscrollbar_ctrl
.Minimum
= 0;
2079 vscrollbar_ctrl
.SmallChange
= 1;
2080 vscrollbar_ctrl
.LargeChange
= 1;
2081 vscrollbar_ctrl
.Maximum
= 0;
2082 vscrollbar_ctrl
.ValueChanged
+= new EventHandler (VerticalScrollEvent
);
2083 Controls
.AddImplicit (vscrollbar_ctrl
);
2086 vscrollbar_ctrl
.Dock
= DockStyle
.Right
;
2088 vscrollbar_ctrl
.Maximum
= owner
.Items
.Count
- 2;
2089 int large
= (owner
.DropDownStyle
== ComboBoxStyle
.Simple
? page_size
: owner
.maxdrop_items
) - 1;
2092 vscrollbar_ctrl
.LargeChange
= large
;
2093 show_scrollbar
= vscrollbar_ctrl
.Visible
= true;
2095 int hli
= HighlightedIndex
;
2097 hli
= Math
.Min (hli
, vscrollbar_ctrl
.Maximum
);
2098 vscrollbar_ctrl
.Value
= hli
;
2102 Size
= new Size (width
, height
);
2103 textarea_drawable
= ClientRectangle
;
2104 textarea_drawable
.Width
= width
;
2105 textarea_drawable
.Height
= height
;
2107 if (vscrollbar_ctrl
!= null && show_scrollbar
)
2108 textarea_drawable
.Width
-= vscrollbar_ctrl
.Width
;
2110 last_item
= LastVisibleItem ();
2113 private void Draw (Rectangle clip
, Graphics dc
)
2115 dc
.FillRectangle (ThemeEngine
.Current
.ResPool
.GetSolidBrush (owner
.BackColor
), clip
);
2117 if (owner
.Items
.Count
> 0) {
2119 for (int i
= top_item
; i
<= last_item
; i
++) {
2120 Rectangle item_rect
= GetItemDisplayRectangle (i
, top_item
);
2122 if (!clip
.IntersectsWith (item_rect
))
2125 DrawItemState state
= DrawItemState
.None
;
2127 if (i
== HighlightedIndex
) {
2128 state
|= DrawItemState
.Selected
;
2130 if (owner
.DropDownStyle
== ComboBoxStyle
.DropDownList
) {
2131 state
|= DrawItemState
.Focus
;
2135 owner
.OnDrawItem (new DrawItemEventArgs (dc
, owner
.Font
, item_rect
,
2136 i
, state
, owner
.ForeColor
, owner
.BackColor
));
2141 int highlighted_index
= -1;
2143 public int HighlightedIndex
{
2144 get { return highlighted_index; }
2146 if (highlighted_index
== value)
2149 if (highlighted_index
!= -1 && highlighted_index
< this.owner
.Items
.Count
)
2150 Invalidate (GetItemDisplayRectangle (highlighted_index
, top_item
));
2151 highlighted_index
= value;
2152 if (highlighted_index
!= -1)
2153 Invalidate (GetItemDisplayRectangle (highlighted_index
, top_item
));
2157 private Rectangle
GetItemDisplayRectangle (int index
, int top_index
)
2159 if (index
< 0 || index
>= owner
.Items
.Count
)
2160 throw new ArgumentOutOfRangeException ("GetItemRectangle index out of range.");
2162 Rectangle item_rect
= new Rectangle ();
2163 int height
= owner
.GetItemHeight (index
);
2166 item_rect
.Width
= textarea_drawable
.Width
;
2167 if (owner
.DrawMode
== DrawMode
.OwnerDrawVariable
) {
2169 for (int i
= top_index
; i
< index
; i
++)
2170 item_rect
.Y
+= owner
.GetItemHeight (i
);
2172 item_rect
.Y
= height
* (index
- top_index
);
2174 item_rect
.Height
= height
;
2178 public void HideWindow ()
2180 if (owner
.DropDownStyle
== ComboBoxStyle
.Simple
)
2185 owner
.DropDownListBoxFinished ();
2188 private int IndexFromPointDisplayRectangle (int x
, int y
)
2190 for (int i
= top_item
; i
<= last_item
; i
++) {
2191 if (GetItemDisplayRectangle (i
, top_item
).Contains (x
, y
) == true)
2198 public void InvalidateItem (int index
)
2201 Invalidate (GetItemDisplayRectangle (index
, top_item
));
2204 private int LastVisibleItem ()
2206 Rectangle item_rect
;
2207 int top_y
= textarea_drawable
.Y
+ textarea_drawable
.Height
;
2210 for (i
= top_item
; i
< owner
.Items
.Count
; i
++) {
2211 item_rect
= GetItemDisplayRectangle (i
, top_item
);
2212 if (item_rect
.Y
+ item_rect
.Height
> top_y
) {
2219 public void SetTopItem (int item
)
2221 if (top_item
== item
)
2224 UpdateLastVisibleItem ();
2228 bool scrollbar_grabbed
= false;
2232 if (vscrollbar_ctrl
== null || !vscrollbar_ctrl
.is_visible
)
2235 return vscrollbar_ctrl
.Bounds
.Contains (PointToClient (Control
.MousePosition
));
2239 protected override void OnMouseDown (MouseEventArgs e
)
2242 vscrollbar_ctrl
.FireMouseDown (e
);
2243 scrollbar_grabbed
= true;
2247 protected override void OnMouseMove (MouseEventArgs e
)
2249 if (owner
.DropDownStyle
== ComboBoxStyle
.Simple
)
2252 if (scrollbar_grabbed
|| (!Capture
&& InScrollBar
)) {
2253 vscrollbar_ctrl
.FireMouseMove (e
);
2257 Point pt
= PointToClient (Control
.MousePosition
);
2258 int index
= IndexFromPointDisplayRectangle (pt
.X
, pt
.Y
);
2261 HighlightedIndex
= index
;
2264 protected override void OnMouseUp (MouseEventArgs e
)
2266 int index
= IndexFromPointDisplayRectangle (e
.X
, e
.Y
);
2268 if (scrollbar_grabbed
) {
2269 vscrollbar_ctrl
.FireMouseUp (e
);
2270 scrollbar_grabbed
= false;
2272 HighlightedIndex
= index
;
2281 owner
.SelectedIndex
= index
;
2282 owner
.OnSelectionChangeCommitted (new EventArgs ());
2286 internal override void OnPaintInternal (PaintEventArgs pevent
)
2288 Draw (pevent
.ClipRectangle
,pevent
.Graphics
);
2291 public bool ShowWindow ()
2293 if (owner
.DropDownStyle
== ComboBoxStyle
.Simple
&& owner
.Items
.Count
== 0)
2296 HighlightedIndex
= owner
.SelectedIndex
;
2302 owner
.OnDropDown (EventArgs
.Empty
);
2306 public void UpdateLastVisibleItem ()
2308 last_item
= LastVisibleItem ();
2311 public void Scroll (int delta
)
2313 if (delta
== 0 || vscrollbar_ctrl
== null || !vscrollbar_ctrl
.Visible
)
2316 int max
= owner
.Items
.Count
- page_size
;
2318 int val
= vscrollbar_ctrl
.Value
+ delta
;
2321 else if (val
< vscrollbar_ctrl
.Minimum
)
2322 val
= vscrollbar_ctrl
.Minimum
;
2323 vscrollbar_ctrl
.Value
= val
;
2326 private void OnMouseWheelCLB (object sender
, MouseEventArgs me
)
2328 if (owner
.Items
.Count
== 0)
2331 int lines
= me
.Delta
/ 120 * SystemInformation
.MouseWheelScrollLines
;
2336 private void VerticalScrollEvent (object sender
, EventArgs e
)
2338 if (top_item
== vscrollbar_ctrl
.Value
)
2341 top_item
= vscrollbar_ctrl
.Value
;
2342 UpdateLastVisibleItem ();
2346 protected override void WndProc(ref Message m
) {
2347 if (m
.Msg
== (int)Msg
.WM_SETFOCUS
) {
2348 if (m
.WParam
!= IntPtr
.Zero
) {
2349 XplatUI
.SetFocus(m
.WParam
);
2352 base.WndProc (ref m
);
2355 #endregion Private Methods