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
);
422 if (IsHandleCreated
== true)
423 Controls
.AddImplicit (textbox_ctrl
);
427 OnDropDownStyleChanged (EventArgs
.Empty
);
430 UpdateComboBoxBounds ();
435 public int DropDownWidth
{
437 if (dropdown_width
== -1)
440 return dropdown_width
;
443 if (dropdown_width
== value)
448 throw new ArgumentOutOfRangeException ("DropDownWidth",
449 "The DropDownWidth value is less than one.");
451 throw new ArgumentException ("The DropDownWidth value is less than one.");
454 dropdown_width
= value;
459 [DesignerSerializationVisibility (DesignerSerializationVisibility
.Hidden
)]
460 public bool DroppedDown
{
462 if (dropdown_style
== ComboBoxStyle
.Simple
)
468 if (dropdown_style
== ComboBoxStyle
.Simple
|| dropped_down
== value)
474 listbox_ctrl
.Hide ();
479 [DefaultValue (FlatStyle
.Standard
)]
481 public FlatStyle FlatStyle
{
482 get { return flat_style; }
484 if (!Enum
.IsDefined (typeof (FlatStyle
), value))
485 throw new InvalidEnumArgumentException ("FlatStyle", (int) value, typeof (FlatStyle
));
494 public override bool Focused
{
495 get { return base.Focused; }
498 public override Color ForeColor
{
499 get { return base.ForeColor; }
501 if (base.ForeColor
== value)
503 base.ForeColor
= value;
508 [DefaultValue (true)]
510 public bool IntegralHeight
{
511 get { return integral_height; }
513 if (integral_height
== value)
515 integral_height
= value;
516 UpdateComboBoxBounds ();
522 public int ItemHeight
{
524 if (item_height
== -1) {
525 SizeF sz
= DeviceContext
.MeasureString ("The quick brown Fox", Font
);
526 item_height
= (int) sz
.Height
;
533 throw new ArgumentOutOfRangeException ("ItemHeight",
534 "The item height value is less than one.");
536 throw new ArgumentException ("The item height value is less than one.");
539 item_height_specified
= true;
542 UpdateComboBoxBounds ();
548 [DesignerSerializationVisibility (DesignerSerializationVisibility
.Content
)]
550 [Editor ("System.Windows.Forms.Design.ListControlStringCollectionEditor, " + Consts
.AssemblySystem_Design
, typeof (System
.Drawing
.Design
.UITypeEditor
))]
552 [MergableProperty (false)]
554 public ComboBox
.ObjectCollection Items
{
555 get { return items; }
560 public int MaxDropDownItems
{
561 get { return maxdrop_items; }
563 if (maxdrop_items
== value)
565 maxdrop_items
= value;
570 public override Size MaximumSize
{
571 get { return base.MaximumSize; }
573 base.MaximumSize
= new Size (value.Width
, 0);
580 public int MaxLength
{
581 get { return max_length; }
583 if (max_length
== value)
588 if (dropdown_style
!= ComboBoxStyle
.DropDownList
) {
592 textbox_ctrl
.MaxLength
= value;
598 public override Size MinimumSize
{
599 get { return base.MinimumSize; }
601 base.MinimumSize
= new Size (value.Width
, 0);
605 [DesignerSerializationVisibility (DesignerSerializationVisibility
.Hidden
)]
606 [EditorBrowsable (EditorBrowsableState
.Never
)]
608 public new Padding Padding
{
609 get { return base.Padding; }
610 set { base.Padding = value; }
614 [DesignerSerializationVisibility (DesignerSerializationVisibility
.Hidden
)]
616 public int PreferredHeight
{
618 return ItemHeight
+ 5;
623 [DesignerSerializationVisibility (DesignerSerializationVisibility
.Hidden
)]
624 public override int SelectedIndex
{
625 get { return selected_index; }
627 if (selected_index
== value)
630 if (value <= -2 || value >= Items
.Count
)
631 throw new ArgumentOutOfRangeException ("Index of out range");
632 selected_index
= value;
634 if (dropdown_style
!= ComboBoxStyle
.DropDownList
) {
638 SetControlText (GetItemText (Items
[value]));
641 if (DropDownStyle
== ComboBoxStyle
.DropDownList
)
644 if (listbox_ctrl
!= null)
645 listbox_ctrl
.HighlightedIndex
= value;
647 OnSelectedValueChanged (new EventArgs ());
648 OnSelectedIndexChanged (new EventArgs ());
649 OnSelectedItemChanged (new EventArgs ());
654 [DesignerSerializationVisibility (DesignerSerializationVisibility
.Hidden
)]
656 public object SelectedItem
{
657 get { return selected_index == -1 ? null : Items [selected_index]; }
659 object item
= selected_index
== -1 ? null : Items
[selected_index
];
662 SelectedIndex
= Items
.IndexOf (value);
667 [DesignerSerializationVisibility (DesignerSerializationVisibility
.Hidden
)]
668 public string SelectedText
{
670 if (dropdown_style
== ComboBoxStyle
.DropDownList
)
673 return textbox_ctrl
.SelectedText
;
676 if (dropdown_style
== ComboBoxStyle
.DropDownList
)
678 textbox_ctrl
.SelectedText
= value;
683 [DesignerSerializationVisibility (DesignerSerializationVisibility
.Hidden
)]
684 public int SelectionLength
{
686 if (dropdown_style
== ComboBoxStyle
.DropDownList
)
689 int result
= textbox_ctrl
.SelectionLength
;
690 return result
== -1 ? 0 : result
;
693 if (dropdown_style
== ComboBoxStyle
.DropDownList
)
695 if (textbox_ctrl
.SelectionLength
== value)
697 textbox_ctrl
.SelectionLength
= value;
702 [DesignerSerializationVisibility (DesignerSerializationVisibility
.Hidden
)]
703 public int SelectionStart
{
705 if (dropdown_style
== ComboBoxStyle
.DropDownList
)
707 return textbox_ctrl
.SelectionStart
;
710 if (dropdown_style
== ComboBoxStyle
.DropDownList
)
712 if (textbox_ctrl
.SelectionStart
== value)
714 textbox_ctrl
.SelectionStart
= value;
718 [DefaultValue (false)]
720 get { return sorted; }
735 public override string Text
{
737 if (dropdown_style
!= ComboBoxStyle
.DropDownList
) {
738 if (textbox_ctrl
!= null) {
739 return textbox_ctrl
.Text
;
743 if (SelectedItem
!= null)
744 return GetItemText (SelectedItem
);
750 if (SelectedIndex
== -1) {
751 if (dropdown_style
!= ComboBoxStyle
.DropDownList
)
759 // do nothing if value exactly matches text of selected item
760 if (SelectedItem
!= null && string.Compare (value, GetItemText (SelectedItem
), false, CultureInfo
.CurrentCulture
) == 0)
763 // find exact match using case-sensitive comparison, and if does
764 // not result in any match then use case-insensitive comparison
765 int index
= FindStringExact (value, -1, false);
767 index
= FindStringExact (value, -1, true);
770 SelectedIndex
= index
;
774 if (dropdown_style
!= ComboBoxStyle
.DropDownList
)
775 textbox_ctrl
.Text
= GetItemText (value);
779 #endregion Public Properties
781 #region Public Methods
783 [Obsolete ("This method has been deprecated")]
785 protected virtual void AddItemsCore (object[] value)
790 public void BeginUpdate ()
792 suspend_ctrlupdate
= true;
796 protected override AccessibleObject
CreateAccessibilityInstance ()
798 return base.CreateAccessibilityInstance ();
801 protected override void CreateHandle ()
803 base.CreateHandle ();
807 protected override void Dispose (bool disposing
)
810 if (listbox_ctrl
!= null) {
811 listbox_ctrl
.Dispose ();
812 Controls
.RemoveImplicit (listbox_ctrl
);
816 if (textbox_ctrl
!= null) {
817 Controls
.RemoveImplicit (textbox_ctrl
);
818 textbox_ctrl
.Dispose ();
823 base.Dispose (disposing
);
826 public void EndUpdate ()
828 suspend_ctrlupdate
= false;
833 public int FindString (string s
)
835 return FindString (s
, -1);
838 public int FindString (string s
, int startIndex
)
840 if (s
== null || Items
.Count
== 0)
844 if (startIndex
< -1 || startIndex
>= Items
.Count
)
846 if (startIndex
< -1 || startIndex
>= Items
.Count
- 1)
848 throw new ArgumentOutOfRangeException ("startIndex");
852 if (i
== (Items
.Count
- 1))
857 if (string.Compare (s
, 0, GetItemText (Items
[i
]), 0, s
.Length
, true) == 0)
859 if (i
== (Items
.Count
- 1))
861 } while (i
!= startIndex
);
866 public int FindStringExact (string s
)
868 return FindStringExact (s
, -1);
871 public int FindStringExact (string s
, int startIndex
)
873 return FindStringExact (s
, startIndex
, true);
876 private int FindStringExact (string s
, int startIndex
, bool ignoreCase
)
878 if (s
== null || Items
.Count
== 0)
882 if (startIndex
< -1 || startIndex
>= Items
.Count
)
884 if (startIndex
< -1 || startIndex
>= Items
.Count
- 1)
886 throw new ArgumentOutOfRangeException ("startIndex");
890 if (i
== (Items
.Count
- 1))
895 if (string.Compare (s
, GetItemText (Items
[i
]), ignoreCase
, CultureInfo
.CurrentCulture
) == 0)
897 if (i
== (Items
.Count
- 1))
899 } while (i
!= startIndex
);
904 public int GetItemHeight (int index
)
906 if (DrawMode
== DrawMode
.OwnerDrawVariable
&& IsHandleCreated
) {
908 if (index
< 0 || index
>= Items
.Count
)
909 throw new ArgumentOutOfRangeException ("The item height value is less than zero");
911 object item
= Items
[index
];
912 if (item_heights
.Contains (item
))
913 return (int) item_heights
[item
];
915 MeasureItemEventArgs args
= new MeasureItemEventArgs (DeviceContext
, index
, ItemHeight
);
916 OnMeasureItem (args
);
917 item_heights
[item
] = args
.ItemHeight
;
918 return args
.ItemHeight
;
924 protected override bool IsInputKey (Keys keyData
)
940 protected override void OnBackColorChanged (EventArgs e
)
942 base.OnBackColorChanged (e
);
945 protected override void OnDataSourceChanged (EventArgs e
)
947 base.OnDataSourceChanged (e
);
950 if (DataSource
== null || DataManager
== null) {
954 SelectedIndex
= DataManager
.Position
;
958 protected override void OnDisplayMemberChanged (EventArgs e
)
960 base.OnDisplayMemberChanged (e
);
962 if (DataManager
== null || !IsHandleCreated
)
966 SelectedIndex
= DataManager
.Position
;
969 protected virtual void OnDrawItem (DrawItemEventArgs e
)
972 case DrawMode
.OwnerDrawFixed
:
973 case DrawMode
.OwnerDrawVariable
:
974 DrawItemEventHandler eh
= (DrawItemEventHandler
)(Events
[DrawItemEvent
]);
979 ThemeEngine
.Current
.DrawComboBoxItem (this, e
);
984 protected virtual void OnDropDown (EventArgs e
)
986 EventHandler eh
= (EventHandler
)(Events
[DropDownEvent
]);
992 protected virtual void OnDropDownClosed (EventArgs e
)
994 EventHandler eh
= (EventHandler
) Events
[DropDownClosedEvent
];
1000 protected virtual void OnDropDownStyleChanged (EventArgs e
)
1002 EventHandler eh
= (EventHandler
)(Events
[DropDownStyleChangedEvent
]);
1007 protected override void OnFontChanged (EventArgs e
)
1009 base.OnFontChanged (e
);
1011 if (textbox_ctrl
!= null)
1012 textbox_ctrl
.Font
= Font
;
1014 if (!item_height_specified
) {
1015 SizeF sz
= DeviceContext
.MeasureString ("The quick brown Fox", Font
);
1016 item_height
= (int) sz
.Height
;
1020 UpdateComboBoxBounds ();
1025 protected override void OnForeColorChanged (EventArgs e
)
1027 base.OnForeColorChanged (e
);
1030 [EditorBrowsable(EditorBrowsableState
.Advanced
)]
1031 protected override void OnGotFocus (EventArgs e
)
1033 if (dropdown_style
== ComboBoxStyle
.DropDownList
) {
1034 // We draw DDL styles manually, so they require a
1035 // refresh to have their selection drawn
1039 if (textbox_ctrl
!= null) {
1040 textbox_ctrl
.SetSelectable (false);
1041 textbox_ctrl
.ShowSelection
= true;
1042 textbox_ctrl
.ActivateCaret (true);
1043 textbox_ctrl
.SelectAll ();
1046 base.OnGotFocus (e
);
1049 [EditorBrowsable(EditorBrowsableState
.Advanced
)]
1050 protected override void OnLostFocus (EventArgs e
)
1052 if (dropdown_style
== ComboBoxStyle
.DropDownList
) {
1053 // We draw DDL styles manually, so they require a
1054 // refresh to have their selection drawn
1058 if (listbox_ctrl
!= null && dropped_down
) {
1059 listbox_ctrl
.HideWindow ();
1062 if (textbox_ctrl
!= null) {
1063 textbox_ctrl
.SetSelectable (true);
1064 textbox_ctrl
.ActivateCaret (false);
1065 textbox_ctrl
.ShowSelection
= false;
1068 base.OnLostFocus (e
);
1071 protected override void OnHandleCreated (EventArgs e
)
1073 base.OnHandleCreated (e
);
1075 if (listbox_ctrl
!= null) {
1076 Controls
.AddImplicit (listbox_ctrl
);
1077 listbox_ctrl
.Visible
= true;
1080 if (textbox_ctrl
!= null)
1081 Controls
.AddImplicit (textbox_ctrl
);
1086 protected override void OnHandleDestroyed (EventArgs e
)
1088 base.OnHandleDestroyed (e
);
1091 protected override void OnKeyPress (KeyPressEventArgs e
)
1093 // int index = FindStringCaseInsensitive (e.KeyChar.ToString (), SelectedIndex);
1095 // SelectedIndex = index;
1097 base.OnKeyPress (e
);
1100 protected virtual void OnMeasureItem (MeasureItemEventArgs e
)
1102 MeasureItemEventHandler eh
= (MeasureItemEventHandler
)(Events
[MeasureItemEvent
]);
1107 protected override void OnParentBackColorChanged (EventArgs e
)
1109 base.OnParentBackColorChanged (e
);
1112 protected override void OnResize (EventArgs e
)
1115 if (listbox_ctrl
!= null)
1116 listbox_ctrl
.CalcListBoxArea ();
1119 protected override void OnSelectedIndexChanged (EventArgs e
)
1121 base.OnSelectedIndexChanged (e
);
1123 EventHandler eh
= (EventHandler
)(Events
[SelectedIndexChangedEvent
]);
1128 protected virtual void OnSelectedItemChanged (EventArgs e
)
1132 protected override void OnSelectedValueChanged (EventArgs e
)
1134 base.OnSelectedValueChanged (e
);
1137 protected virtual void OnSelectionChangeCommitted (EventArgs e
)
1139 EventHandler eh
= (EventHandler
)(Events
[SelectionChangeCommittedEvent
]);
1144 protected override void RefreshItem (int index
)
1146 if (index
< 0 || index
>= Items
.Count
)
1147 throw new ArgumentOutOfRangeException ("Index of out range");
1149 if (draw_mode
== DrawMode
.OwnerDrawVariable
)
1150 item_heights
.Remove (Items
[index
]);
1154 public override void ResetText ()
1156 Text
= String
.Empty
;
1159 protected override bool ProcessKeyEventArgs (ref Message m
)
1161 return base.ProcessKeyEventArgs (ref m
);
1164 [EditorBrowsable (EditorBrowsableState
.Advanced
)]
1165 protected override void OnKeyDown (KeyEventArgs e
)
1170 [EditorBrowsable (EditorBrowsableState
.Advanced
)]
1171 protected override void OnValidating (CancelEventArgs e
)
1173 base.OnValidating (e
);
1176 [EditorBrowsable (EditorBrowsableState
.Advanced
)]
1177 protected override void OnTextChanged (EventArgs e
)
1179 base.OnTextChanged (e
);
1183 protected virtual void OnTextUpdate (EventArgs e
)
1185 EventHandler eh
= (EventHandler
) Events
[TextUpdateEvent
];
1190 protected override void OnMouseLeave (EventArgs e
)
1193 if (flat_style
== FlatStyle
.Popup
)
1196 base.OnMouseLeave (e
);
1199 protected override void OnMouseEnter (EventArgs e
)
1202 if (flat_style
== FlatStyle
.Popup
)
1205 base.OnMouseEnter (e
);
1209 public void Select (int start
, int length
)
1212 throw new ArgumentException ("Start cannot be less than zero");
1215 throw new ArgumentException ("length cannot be less than zero");
1217 if (dropdown_style
== ComboBoxStyle
.DropDownList
)
1220 textbox_ctrl
.Select (start
, length
);
1223 public void SelectAll ()
1225 if (dropdown_style
== ComboBoxStyle
.DropDownList
)
1228 if (textbox_ctrl
!= null) {
1229 textbox_ctrl
.ShowSelection
= true;
1230 textbox_ctrl
.SelectAll ();
1234 protected override void SetBoundsCore (int x
, int y
, int width
, int height
, BoundsSpecified specified
)
1236 if ((specified
& BoundsSpecified
.Height
) != 0) {
1237 requested_height
= height
;
1239 if (DropDownStyle
== ComboBoxStyle
.Simple
&& height
> PreferredHeight
) {
1240 if (IntegralHeight
) {
1241 int border
= ThemeEngine
.Current
.Border3DSize
.Height
;
1242 int lb_height
= height
- PreferredHeight
- 2;
1243 if (lb_height
- 2 * border
> ItemHeight
) {
1244 int partial = (lb_height
- 2 * border
) % ItemHeight
;
1247 height
= PreferredHeight
;
1250 height
= PreferredHeight
;
1253 base.SetBoundsCore (x
, y
, width
, height
, specified
);
1256 protected override void SetItemCore (int index
, object value)
1258 if (index
< 0 || index
>= Items
.Count
)
1261 Items
[index
] = value;
1264 protected override void SetItemsCore (IList
value)
1269 Items
.AddRange (value);
1275 public override string ToString ()
1277 return base.ToString () + ", Items.Count:" + Items
.Count
;
1280 protected override void WndProc (ref Message m
)
1282 switch ((Msg
) m
.Msg
) {
1284 case Msg
.WM_KEYDOWN
:
1285 Keys keys
= (Keys
) m
.WParam
.ToInt32 ();
1286 if (keys
== Keys
.Up
|| keys
== Keys
.Down
)
1288 goto case Msg
.WM_CHAR
;
1290 if (textbox_ctrl
!= null)
1291 XplatUI
.SendMessage (textbox_ctrl
.Handle
, (Msg
) m
.Msg
, m
.WParam
, m
.LParam
);
1293 case Msg
.WM_MOUSELEAVE
:
1294 Point location
= PointToClient (Control
.MousePosition
);
1295 if (ClientRectangle
.Contains (location
))
1301 base.WndProc (ref m
);
1304 #endregion Public Methods
1306 #region Private Methods
1308 void OnAutoCompleteCustomSourceChanged(object sender
, CollectionChangeEventArgs e
) {
1309 if(auto_complete_source
== AutoCompleteSource
.CustomSource
) {
1310 //FIXME: handle add, remove and refresh events in AutoComplete algorithm.
1315 internal override bool InternalCapture
{
1316 get { return Capture; }
1320 void LayoutComboBox ()
1322 int border
= ThemeEngine
.Current
.Border3DSize
.Width
;
1324 text_area
= ClientRectangle
;
1325 text_area
.Height
= PreferredHeight
;
1327 listbox_area
= ClientRectangle
;
1328 listbox_area
.Y
= text_area
.Bottom
+ 3;
1329 listbox_area
.Height
-= (text_area
.Height
+ 2);
1331 Rectangle prev_button_area
= button_area
;
1333 if (DropDownStyle
== ComboBoxStyle
.Simple
)
1334 button_area
= Rectangle
.Empty
;
1336 button_area
= text_area
;
1337 button_area
.X
= text_area
.Right
- button_width
- border
;
1338 button_area
.Y
= text_area
.Y
+ border
;
1339 button_area
.Width
= button_width
;
1340 button_area
.Height
= text_area
.Height
- 2 * border
;
1342 if (flat_style
== FlatStyle
.Popup
|| flat_style
== FlatStyle
.Flat
) {
1343 button_area
.Inflate (1, 1);
1345 button_area
.Width
-= 2;
1350 if (button_area
!= prev_button_area
) {
1351 prev_button_area
.Y
-= border
;
1352 prev_button_area
.Width
+= border
;
1353 prev_button_area
.Height
+= 2 * border
;
1354 Invalidate (prev_button_area
);
1355 Invalidate (button_area
);
1358 if (textbox_ctrl
!= null) {
1359 textbox_ctrl
.Location
= new Point (text_area
.X
+ border
, text_area
.Y
+ border
);
1360 textbox_ctrl
.Width
= text_area
.Width
- button_area
.Width
- border
* 2;
1361 textbox_ctrl
.Height
= text_area
.Height
- border
* 2;
1364 if (listbox_ctrl
!= null && dropdown_style
== ComboBoxStyle
.Simple
) {
1365 listbox_ctrl
.Location
= listbox_area
.Location
;
1366 listbox_ctrl
.CalcListBoxArea ();
1370 private void CreateComboListBox ()
1372 listbox_ctrl
= new ComboListBox (this);
1373 listbox_ctrl
.HighlightedIndex
= SelectedIndex
;
1376 internal void Draw (Rectangle clip
, Graphics dc
)
1378 Theme theme
= ThemeEngine
.Current
;
1379 FlatStyle style
= FlatStyle
.Standard
;
1380 bool is_flat
= false;
1383 style
= this.FlatStyle
;
1384 is_flat
= style
== FlatStyle
.Flat
|| style
== FlatStyle
.Popup
;
1387 if (DropDownStyle
== ComboBoxStyle
.Simple
)
1388 dc
.FillRectangle (theme
.ResPool
.GetSolidBrush (Parent
.BackColor
), ClientRectangle
);
1390 if (style
== FlatStyle
.Popup
&& (is_entered
|| Focused
)) {
1391 Rectangle area
= text_area
;
1394 dc
.DrawRectangle (theme
.ResPool
.GetPen (SystemColors
.ControlDark
), area
);
1395 dc
.DrawLine (theme
.ResPool
.GetPen (SystemColors
.ControlDark
), button_area
.X
- 1, button_area
.Top
, button_area
.X
- 1, button_area
.Bottom
);
1397 if (!is_flat
&& clip
.IntersectsWith (text_area
))
1398 ControlPaint
.DrawBorder3D (dc
, text_area
, Border3DStyle
.Sunken
);
1400 int border
= theme
.Border3DSize
.Width
;
1402 // No edit control, we paint the edit ourselves
1403 if (dropdown_style
== ComboBoxStyle
.DropDownList
) {
1404 DrawItemState state
= DrawItemState
.None
;
1405 Rectangle item_rect
= text_area
;
1406 item_rect
.X
+= border
;
1407 item_rect
.Y
+= border
;
1408 item_rect
.Width
-= (button_area
.Width
+ 2 * border
);
1409 item_rect
.Height
-= 2 * border
;
1412 state
= DrawItemState
.Selected
;
1413 state
|= DrawItemState
.Focus
;
1416 state
|= DrawItemState
.ComboBoxEdit
;
1417 OnDrawItem (new DrawItemEventArgs (dc
, Font
, item_rect
, SelectedIndex
, state
, ForeColor
, BackColor
));
1420 if (show_dropdown_button
) {
1421 dc
.FillRectangle (theme
.ResPool
.GetSolidBrush (theme
.ColorControl
), button_area
);
1424 button_state
= ButtonState
.Inactive
;
1427 theme
.DrawFlatStyleComboButton (dc
, button_area
, button_state
);
1429 theme
.CPDrawComboButton (dc
, button_area
, button_state
);
1434 internal void DropDownListBox ()
1436 if (DropDownStyle
== ComboBoxStyle
.Simple
)
1439 if (listbox_ctrl
== null)
1440 CreateComboListBox ();
1442 listbox_ctrl
.Location
= PointToScreen (new Point (text_area
.X
, text_area
.Y
+ text_area
.Height
));
1444 if (listbox_ctrl
.ShowWindow ())
1445 dropped_down
= true;
1447 button_state
= ButtonState
.Pushed
;
1448 if (dropdown_style
== ComboBoxStyle
.DropDownList
)
1449 Invalidate (text_area
);
1452 internal void DropDownListBoxFinished ()
1454 if (DropDownStyle
== ComboBoxStyle
.Simple
)
1457 button_state
= ButtonState
.Normal
;
1458 Invalidate (button_area
);
1459 dropped_down
= false;
1461 OnDropDownClosed (EventArgs
.Empty
);
1465 private int FindStringCaseInsensitive (string search
)
1467 if (search
.Length
== 0) {
1471 for (int i
= 0; i
< Items
.Count
; i
++)
1473 if (String
.Compare (GetItemText (Items
[i
]), 0, search
, 0, search
.Length
, true) == 0)
1480 internal int FindStringCaseInsensitive (string search
, int start_index
)
1482 if (search
.Length
== 0) {
1486 for (int i
= 0; i
< Items
.Count
; i
++) {
1487 int index
= (i
+ start_index
) % Items
.Count
;
1488 if (String
.Compare (GetItemText (Items
[index
]), 0, search
, 0, search
.Length
, true) == 0)
1495 private void OnKeyDownCB(object sender
, KeyEventArgs e
)
1497 if (Items
.Count
== 0)
1503 SelectedIndex
= Math
.Max(SelectedIndex
-1, 0);
1507 SelectedIndex
= Math
.Min(SelectedIndex
+1, Items
.Count
-1);
1511 if (listbox_ctrl
!= null)
1512 SelectedIndex
= Math
.Max(SelectedIndex
- (listbox_ctrl
.page_size
-1), 0);
1516 if (listbox_ctrl
!= null)
1517 SelectedIndex
= Math
.Min(SelectedIndex
+(listbox_ctrl
.page_size
-1), Items
.Count
-1);
1525 void OnMouseDownCB (object sender
, MouseEventArgs e
)
1528 if (DropDownStyle
== ComboBoxStyle
.DropDownList
)
1529 area
= ClientRectangle
;
1533 if (area
.Contains (e
.X
, e
.Y
)) {
1535 Invalidate (button_area
);
1541 void OnMouseMoveCB (object sender
, MouseEventArgs e
)
1543 if (DropDownStyle
== ComboBoxStyle
.Simple
)
1546 if (listbox_ctrl
!= null && listbox_ctrl
.Visible
) {
1547 Point location
= listbox_ctrl
.PointToClient (Control
.MousePosition
);
1548 if (listbox_ctrl
.ClientRectangle
.Contains (location
))
1549 listbox_ctrl
.Capture
= true;
1553 void OnMouseUpCB (object sender
, MouseEventArgs e
)
1556 OnClick (EventArgs
.Empty
);
1559 listbox_ctrl
.Capture
= true;
1562 private void OnMouseWheelCB (object sender
, MouseEventArgs me
)
1564 if (Items
.Count
== 0)
1567 if (listbox_ctrl
!= null && listbox_ctrl
.Visible
) {
1568 int lines
= me
.Delta
/ 120 * SystemInformation
.MouseWheelScrollLines
;
1569 listbox_ctrl
.Scroll (-lines
);
1571 int lines
= me
.Delta
/ 120;
1572 int index
= SelectedIndex
- lines
;
1575 else if (index
>= Items
.Count
)
1576 index
= Items
.Count
- 1;
1577 SelectedIndex
= index
;
1581 internal override void OnPaintInternal (PaintEventArgs pevent
)
1583 if (suspend_ctrlupdate
)
1586 Draw (ClientRectangle
, pevent
.Graphics
);
1589 private void OnTextBoxClick (object sender
, EventArgs e
)
1594 private void OnTextChangedEdit (object sender
, EventArgs e
)
1596 if (process_textchanged_event
== false)
1599 OnTextChanged (EventArgs
.Empty
);
1601 int item
= FindStringCaseInsensitive (textbox_ctrl
.Text
);
1606 // TODO: THIS IS BROKEN-ISH
1607 // I don't think we should hilight, and setting the top item does weirdness
1608 // when there is no scrollbar
1610 if (listbox_ctrl
!= null) {
1611 listbox_ctrl
.SetTopItem (item
);
1612 listbox_ctrl
.HighlightedIndex
= item
;
1615 base.Text
= textbox_ctrl
.Text
;
1618 internal void SetControlText (string s
)
1620 process_textchanged_event
= false;
1621 textbox_ctrl
.Text
= s
;
1622 process_textchanged_event
= true;
1625 void UpdateComboBoxBounds ()
1627 if (requested_height
== -1)
1630 // Save the requested height since set bounds can destroy it
1631 int save_height
= requested_height
;
1632 SetBounds (0, 0, 0, requested_height
, BoundsSpecified
.Height
);
1633 requested_height
= save_height
;
1636 private void UpdatedItems ()
1638 if (listbox_ctrl
!= null) {
1639 listbox_ctrl
.UpdateLastVisibleItem ();
1640 listbox_ctrl
.CalcListBoxArea ();
1641 listbox_ctrl
.Refresh ();
1645 #endregion Private Methods
1647 [ListBindableAttribute (false)]
1648 public class ObjectCollection
: IList
, ICollection
, IEnumerable
1651 private ComboBox owner
;
1652 internal ArrayList object_items
= new ArrayList ();
1654 public ObjectCollection (ComboBox owner
)
1659 #region Public Properties
1661 get { return object_items.Count; }
1664 public bool IsReadOnly
{
1665 get { return false; }
1669 [DesignerSerializationVisibility(DesignerSerializationVisibility
.Hidden
)]
1670 public virtual object this [int index
] {
1672 if (index
< 0 || index
>= Count
)
1673 throw new ArgumentOutOfRangeException ("Index of out range");
1675 return object_items
[index
];
1678 if (index
< 0 || index
>= Count
)
1679 throw new ArgumentOutOfRangeException ("Index of out range");
1681 throw new ArgumentNullException ("value");
1683 object_items
[index
] = value;
1684 if (owner
.listbox_ctrl
!= null)
1685 owner
.listbox_ctrl
.InvalidateItem (index
);
1686 if (index
== owner
.SelectedIndex
) {
1687 if (owner
.textbox_ctrl
== null)
1690 owner
.textbox_ctrl
.SelectedText
= value.ToString ();
1695 bool ICollection
.IsSynchronized
{
1696 get { return false; }
1699 object ICollection
.SyncRoot
{
1700 get { return this; }
1703 bool IList
.IsFixedSize
{
1704 get { return false; }
1707 #endregion Public Properties
1709 #region Public Methods
1710 public int Add (object item
)
1714 idx
= AddItem (item
);
1715 owner
.UpdatedItems ();
1719 public void AddRange (object[] items
)
1722 throw new ArgumentNullException ("items");
1724 foreach (object mi
in items
)
1727 owner
.UpdatedItems ();
1730 public void Clear ()
1732 owner
.selected_index
= -1;
1733 object_items
.Clear ();
1734 owner
.UpdatedItems ();
1738 public bool Contains (object value)
1741 throw new ArgumentNullException ("value");
1743 return object_items
.Contains (value);
1746 public void CopyTo (object[] dest
, int arrayIndex
)
1748 object_items
.CopyTo (dest
, arrayIndex
);
1751 void ICollection
.CopyTo (Array dest
, int index
)
1753 object_items
.CopyTo (dest
, index
);
1756 public IEnumerator
GetEnumerator ()
1758 return object_items
.GetEnumerator ();
1761 int IList
.Add (object item
)
1766 public int IndexOf (object value)
1769 throw new ArgumentNullException ("value");
1771 return object_items
.IndexOf (value);
1774 public void Insert (int index
, object item
)
1776 if (index
< 0 || index
> Count
)
1777 throw new ArgumentOutOfRangeException ("Index of out range");
1779 throw new ArgumentNullException ("item");
1781 owner
.BeginUpdate ();
1786 object_items
.Insert (index
, item
);
1788 owner
.EndUpdate (); // Calls UpdatedItems
1791 public void Remove (object value)
1796 if (IndexOf (value) == owner
.SelectedIndex
)
1797 owner
.SelectedIndex
= -1;
1799 RemoveAt (IndexOf (value));
1802 public void RemoveAt (int index
)
1804 if (index
< 0 || index
>= Count
)
1805 throw new ArgumentOutOfRangeException ("Index of out range");
1807 if (index
== owner
.SelectedIndex
)
1808 owner
.SelectedIndex
= -1;
1810 object_items
.RemoveAt (index
);
1811 owner
.UpdatedItems ();
1813 #endregion Public Methods
1815 #region Private Methods
1816 private int AddItem (object item
)
1819 throw new ArgumentNullException ("item");
1823 foreach (object o
in object_items
) {
1824 if (String
.Compare (item
.ToString (), o
.ToString ()) < 0) {
1825 object_items
.Insert (index
, item
);
1831 object_items
.Add (item
);
1832 return object_items
.Count
- 1;
1835 internal void AddRange (IList items
)
1837 foreach (object mi
in items
)
1840 owner
.UpdatedItems ();
1843 internal void Sort ()
1845 object_items
.Sort ();
1848 #endregion Private Methods
1851 internal class ComboTextBox
: TextBox
{
1853 private ComboBox owner
;
1855 public ComboTextBox (ComboBox owner
)
1858 ShowSelection
= false;
1861 internal void SetSelectable (bool selectable
)
1863 SetStyle (ControlStyles
.Selectable
, selectable
);
1866 internal void ActivateCaret (bool active
)
1869 document
.CaretHasFocus ();
1871 document
.CaretLostFocus ();
1875 internal override void OnTextUpdate ()
1877 base.OnTextUpdate ();
1878 owner
.OnTextUpdate (EventArgs
.Empty
);
1882 protected override void OnGotFocus (EventArgs e
)
1884 owner
.Select (false, true);
1887 protected override void OnLostFocus (EventArgs e
)
1889 owner
.Select (false, true);
1893 internal class ComboListBox
: Control
1895 private ComboBox owner
;
1896 private VScrollBarLB vscrollbar_ctrl
;
1897 private int top_item
; /* First item that we show the in the current page */
1898 private int last_item
; /* Last visible item */
1899 internal int page_size
; /* Number of listbox items per page */
1900 private Rectangle textarea_drawable
; /* Rectangle of the drawable text area */
1902 internal enum ItemNavigation
1912 class VScrollBarLB
: VScrollBar
1914 public VScrollBarLB ()
1918 internal override bool InternalCapture
{
1919 get { return Capture; }
1923 public void FireMouseDown (MouseEventArgs e
)
1928 e
= TranslateEvent (e
);
1932 public void FireMouseUp (MouseEventArgs e
)
1937 e
= TranslateEvent (e
);
1941 public void FireMouseMove (MouseEventArgs e
)
1946 e
= TranslateEvent (e
);
1950 MouseEventArgs
TranslateEvent (MouseEventArgs e
)
1952 Point loc
= PointToClient (Control
.MousePosition
);
1953 return new MouseEventArgs (e
.Button
, e
.Clicks
, loc
.X
, loc
.Y
, e
.Delta
);
1957 public ComboListBox (ComboBox owner
)
1964 MouseWheel
+= new MouseEventHandler (OnMouseWheelCLB
);
1966 SetStyle (ControlStyles
.UserPaint
| ControlStyles
.AllPaintingInWmPaint
, true);
1967 SetStyle (ControlStyles
.ResizeRedraw
| ControlStyles
.Opaque
, true);
1969 this.is_visible
= false;
1971 if (owner
.DropDownStyle
== ComboBoxStyle
.Simple
)
1972 InternalBorderStyle
= BorderStyle
.Fixed3D
;
1974 InternalBorderStyle
= BorderStyle
.FixedSingle
;
1977 protected override CreateParams CreateParams
1980 CreateParams cp
= base.CreateParams
;
1981 if (owner
== null || owner
.DropDownStyle
== ComboBoxStyle
.Simple
)
1984 cp
.Style ^
= (int) WindowStyles
.WS_CHILD
;
1985 cp
.Style
|= (int) WindowStyles
.WS_POPUP
;
1986 cp
.ExStyle
|= (int) WindowExStyles
.WS_EX_TOOLWINDOW
| (int) WindowExStyles
.WS_EX_TOPMOST
;
1991 protected override void Select (bool directed
, bool forward
)
1993 // Do nothing, we never want to be selected
1996 internal override bool InternalCapture
{
2005 internal override bool ActivateOnShow { get { return false; }
}
2006 #region Private Methods
2008 // Calcs the listbox area
2009 internal void CalcListBoxArea ()
2012 bool show_scrollbar
= false;
2014 if (owner
.DropDownStyle
== ComboBoxStyle
.Simple
) {
2015 Rectangle area
= owner
.listbox_area
;
2017 height
= area
.Height
;
2019 else { // DropDown or DropDownList
2021 width
= owner
.DropDownWidth
;
2022 int count
= (owner
.Items
.Count
<= owner
.MaxDropDownItems
) ? owner
.Items
.Count
: owner
.MaxDropDownItems
;
2024 if (owner
.DrawMode
== DrawMode
.OwnerDrawVariable
) {
2026 for (int i
= 0; i
< count
; i
++) {
2027 height
+= owner
.GetItemHeight (i
);
2032 height
= owner
.DropDownHeight
;
2034 height
= owner
.ItemHeight
* count
;
2039 page_size
= height
/ owner
.ItemHeight
;
2041 if (owner
.Items
.Count
<= owner
.MaxDropDownItems
) {
2042 if (vscrollbar_ctrl
!= null)
2043 vscrollbar_ctrl
.Visible
= false;
2045 /* Need vertical scrollbar */
2046 if (vscrollbar_ctrl
== null) {
2047 vscrollbar_ctrl
= new VScrollBarLB ();
2048 vscrollbar_ctrl
.Minimum
= 0;
2049 vscrollbar_ctrl
.SmallChange
= 1;
2050 vscrollbar_ctrl
.LargeChange
= 1;
2051 vscrollbar_ctrl
.Maximum
= 0;
2052 vscrollbar_ctrl
.ValueChanged
+= new EventHandler (VerticalScrollEvent
);
2053 Controls
.AddImplicit (vscrollbar_ctrl
);
2056 vscrollbar_ctrl
.Dock
= DockStyle
.Right
;
2058 vscrollbar_ctrl
.Maximum
= owner
.Items
.Count
- 2;
2059 int large
= (owner
.DropDownStyle
== ComboBoxStyle
.Simple
? page_size
: owner
.maxdrop_items
) - 1;
2062 vscrollbar_ctrl
.LargeChange
= large
;
2063 show_scrollbar
= vscrollbar_ctrl
.Visible
= true;
2065 int hli
= HighlightedIndex
;
2067 hli
= Math
.Min (hli
, vscrollbar_ctrl
.Maximum
);
2068 vscrollbar_ctrl
.Value
= hli
;
2072 Size
= new Size (width
, height
);
2073 textarea_drawable
= ClientRectangle
;
2074 textarea_drawable
.Width
= width
;
2075 textarea_drawable
.Height
= height
;
2077 if (vscrollbar_ctrl
!= null && show_scrollbar
)
2078 textarea_drawable
.Width
-= vscrollbar_ctrl
.Width
;
2080 last_item
= LastVisibleItem ();
2083 private void Draw (Rectangle clip
, Graphics dc
)
2085 dc
.FillRectangle (ThemeEngine
.Current
.ResPool
.GetSolidBrush (owner
.BackColor
), clip
);
2087 if (owner
.Items
.Count
> 0) {
2089 for (int i
= top_item
; i
<= last_item
; i
++) {
2090 Rectangle item_rect
= GetItemDisplayRectangle (i
, top_item
);
2092 if (!clip
.IntersectsWith (item_rect
))
2095 DrawItemState state
= DrawItemState
.None
;
2097 if (i
== HighlightedIndex
) {
2098 state
|= DrawItemState
.Selected
;
2100 if (owner
.DropDownStyle
== ComboBoxStyle
.DropDownList
) {
2101 state
|= DrawItemState
.Focus
;
2105 owner
.OnDrawItem (new DrawItemEventArgs (dc
, owner
.Font
, item_rect
,
2106 i
, state
, owner
.ForeColor
, owner
.BackColor
));
2111 int highlighted_index
= -1;
2113 public int HighlightedIndex
{
2114 get { return highlighted_index; }
2116 if (highlighted_index
== value)
2119 if (highlighted_index
!= -1 && highlighted_index
< this.owner
.Items
.Count
)
2120 Invalidate (GetItemDisplayRectangle (highlighted_index
, top_item
));
2121 highlighted_index
= value;
2122 if (highlighted_index
!= -1)
2123 Invalidate (GetItemDisplayRectangle (highlighted_index
, top_item
));
2127 private Rectangle
GetItemDisplayRectangle (int index
, int top_index
)
2129 if (index
< 0 || index
>= owner
.Items
.Count
)
2130 throw new ArgumentOutOfRangeException ("GetItemRectangle index out of range.");
2132 Rectangle item_rect
= new Rectangle ();
2133 int height
= owner
.GetItemHeight (index
);
2136 item_rect
.Width
= textarea_drawable
.Width
;
2137 if (owner
.DrawMode
== DrawMode
.OwnerDrawVariable
) {
2139 for (int i
= top_index
; i
< index
; i
++)
2140 item_rect
.Y
+= owner
.GetItemHeight (i
);
2142 item_rect
.Y
= height
* (index
- top_index
);
2144 item_rect
.Height
= height
;
2148 public void HideWindow ()
2150 if (owner
.DropDownStyle
== ComboBoxStyle
.Simple
)
2155 owner
.DropDownListBoxFinished ();
2158 private int IndexFromPointDisplayRectangle (int x
, int y
)
2160 for (int i
= top_item
; i
<= last_item
; i
++) {
2161 if (GetItemDisplayRectangle (i
, top_item
).Contains (x
, y
) == true)
2168 public void InvalidateItem (int index
)
2171 Invalidate (GetItemDisplayRectangle (index
, top_item
));
2174 private int LastVisibleItem ()
2176 Rectangle item_rect
;
2177 int top_y
= textarea_drawable
.Y
+ textarea_drawable
.Height
;
2180 for (i
= top_item
; i
< owner
.Items
.Count
; i
++) {
2181 item_rect
= GetItemDisplayRectangle (i
, top_item
);
2182 if (item_rect
.Y
+ item_rect
.Height
> top_y
) {
2189 public void SetTopItem (int item
)
2191 if (top_item
== item
)
2194 UpdateLastVisibleItem ();
2198 bool scrollbar_grabbed
= false;
2202 if (vscrollbar_ctrl
== null || !vscrollbar_ctrl
.is_visible
)
2205 return vscrollbar_ctrl
.Bounds
.Contains (PointToClient (Control
.MousePosition
));
2209 protected override void OnMouseDown (MouseEventArgs e
)
2212 vscrollbar_ctrl
.FireMouseDown (e
);
2213 scrollbar_grabbed
= true;
2217 protected override void OnMouseMove (MouseEventArgs e
)
2219 if (owner
.DropDownStyle
== ComboBoxStyle
.Simple
)
2222 if (scrollbar_grabbed
|| (!Capture
&& InScrollBar
)) {
2223 vscrollbar_ctrl
.FireMouseMove (e
);
2227 Point pt
= PointToClient (Control
.MousePosition
);
2228 int index
= IndexFromPointDisplayRectangle (pt
.X
, pt
.Y
);
2231 HighlightedIndex
= index
;
2234 protected override void OnMouseUp (MouseEventArgs e
)
2236 int index
= IndexFromPointDisplayRectangle (e
.X
, e
.Y
);
2238 if (scrollbar_grabbed
) {
2239 vscrollbar_ctrl
.FireMouseUp (e
);
2240 scrollbar_grabbed
= false;
2242 HighlightedIndex
= index
;
2251 owner
.SelectedIndex
= index
;
2252 owner
.OnSelectionChangeCommitted (new EventArgs ());
2256 internal override void OnPaintInternal (PaintEventArgs pevent
)
2258 Draw (pevent
.ClipRectangle
,pevent
.Graphics
);
2261 public bool ShowWindow ()
2263 if (owner
.DropDownStyle
== ComboBoxStyle
.Simple
&& owner
.Items
.Count
== 0)
2266 HighlightedIndex
= owner
.SelectedIndex
;
2272 owner
.OnDropDown (EventArgs
.Empty
);
2276 public void UpdateLastVisibleItem ()
2278 last_item
= LastVisibleItem ();
2281 public void Scroll (int delta
)
2283 if (delta
== 0 || vscrollbar_ctrl
== null || !vscrollbar_ctrl
.Visible
)
2286 int max
= owner
.Items
.Count
- page_size
;
2288 int val
= vscrollbar_ctrl
.Value
+ delta
;
2291 else if (val
< vscrollbar_ctrl
.Minimum
)
2292 val
= vscrollbar_ctrl
.Minimum
;
2293 vscrollbar_ctrl
.Value
= val
;
2296 private void OnMouseWheelCLB (object sender
, MouseEventArgs me
)
2298 if (owner
.Items
.Count
== 0)
2301 int lines
= me
.Delta
/ 120 * SystemInformation
.MouseWheelScrollLines
;
2306 private void VerticalScrollEvent (object sender
, EventArgs e
)
2308 if (top_item
== vscrollbar_ctrl
.Value
)
2311 top_item
= vscrollbar_ctrl
.Value
;
2312 UpdateLastVisibleItem ();
2316 protected override void WndProc(ref Message m
) {
2317 if (m
.Msg
== (int)Msg
.WM_SETFOCUS
) {
2318 if (m
.WParam
!= IntPtr
.Zero
) {
2319 XplatUI
.SetFocus(m
.WParam
);
2322 base.WndProc (ref m
);
2325 #endregion Private Methods