Switch to compiler-tester
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / ComboBox.cs
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:
8 //
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
11 //
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.
19 //
20 // Copyright (c) 2004-2005 Novell, Inc.
21 //
22 // Authors:
23 //      Jordi Mas i Hernandez, jordi@ximian.com
24 //
25 //
26
27 // NOT COMPLETE
28
29 using System;
30 using System.Drawing;
31 using System.Collections;
32 using System.ComponentModel;
33 using System.Reflection;
34 using System.ComponentModel.Design;
35 using System.ComponentModel.Design.Serialization;
36 using System.Runtime.InteropServices;
37
38
39 namespace System.Windows.Forms
40 {
41
42         [DefaultProperty("Items")]
43         [DefaultEvent("SelectedIndexChanged")]
44         [Designer ("System.Windows.Forms.Design.ComboBoxDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
45         public class ComboBox : ListControl
46         {
47                 private DrawMode draw_mode;
48                 private ComboBoxStyle dropdown_style;
49                 private int dropdown_width;             
50                 private const int preferred_height = 20;
51                 private int selected_index;
52                 private object selected_item;
53                 internal ObjectCollection items = null;
54                 private bool suspend_ctrlupdate;
55                 private int maxdrop_items;
56                 private bool integral_height;
57                 private bool sorted;
58                 internal ComboBoxInfo combobox_info;
59                 private readonly int def_button_width = 16;
60                 private bool clicked;           
61                 private int max_length;
62                 private ComboListBox listbox_ctrl;              
63                 private TextBox textbox_ctrl;
64                 private bool process_textchanged_event;
65                 private bool has_focus;         
66
67                 [ComVisible(true)]
68                 public class ChildAccessibleObject : AccessibleObject {
69                         private ComboBox        owner;
70                         private IntPtr          handle;
71
72                         public ChildAccessibleObject (ComboBox owner, IntPtr handle) {
73                                 this.owner = owner;
74                                 this.handle = handle;
75                         }
76
77                         public override string Name {\r
78                                 get {\r
79                                         return base.Name;\r
80                                 }\r
81                         }\r
82
83                         
84                 }
85
86                 internal class ComboBoxInfo
87                 {
88                         internal int item_height;               /* Item's height */
89                         internal Rectangle textarea;            /* Rectangle of the editable text area  */
90                         internal Rectangle textarea_drawable;   /* Rectangle of the editable text area - decorations - button if present*/
91                         internal Rectangle button_rect;
92                         internal bool show_button;              /* Is the DropDown button shown? */
93                         internal ButtonState button_status;     /* Drop button status */
94                         internal int original_height;           /* Control's height is recalculated for not Simple Styles */
95                         internal Rectangle listbox_area;        /* ListBox area in Simple combox, not used in the rest */
96                         internal bool droppeddown;              /* Is the associated ListBox dropped down? */
97
98                         public ComboBoxInfo ()
99                         {
100                                 button_status = ButtonState.Normal;
101                                 show_button = false;
102                                 item_height = 0;
103                                 droppeddown = false;
104                                 original_height = -1;
105                         }
106                 }
107
108                 internal class ComboBoxItem
109                 {
110                         internal int Index;
111                         internal int ItemHeight;                /* Only used for OwnerDrawVariable */
112
113                         public ComboBoxItem (int index)
114                         {
115                                 Index = index;
116                                 ItemHeight = -1;
117                         }                       
118                 }
119
120                 public ComboBox ()
121                 {
122                         items = new ObjectCollection (this);
123                         listbox_ctrl = null;
124                         textbox_ctrl = null;
125                         combobox_info = new ComboBoxInfo ();
126                         combobox_info.item_height = FontHeight + 2;
127                         dropdown_style = (ComboBoxStyle)(-1);
128                         DropDownStyle = ComboBoxStyle.DropDown;
129                         BackColor = ThemeEngine.Current.ColorWindow;
130                         draw_mode = DrawMode.Normal;
131                         selected_index = -1;
132                         selected_item = null;
133                         maxdrop_items = 8;                      
134                         suspend_ctrlupdate = false;
135                         clicked = false;
136                         dropdown_width = -1;
137                         max_length = 0;
138                         integral_height = true;
139                         process_textchanged_event = true;
140                         has_focus = false;
141
142                         /* Events */
143                         MouseDown += new MouseEventHandler (OnMouseDownCB);
144                         MouseUp += new MouseEventHandler (OnMouseUpCB);
145                         MouseMove += new MouseEventHandler (OnMouseMoveCB);
146                 }
147
148                 #region events
149                 
150                 [Browsable (false)]
151                 [EditorBrowsable (EditorBrowsableState.Never)]
152                 public new event EventHandler BackgroundImageChanged;           
153                 
154                 public event DrawItemEventHandler DrawItem;             
155                 public event EventHandler DropDown;             
156                 public event EventHandler DropDownStyleChanged;         
157                 public event MeasureItemEventHandler MeasureItem;
158                 
159                 [Browsable (false)]
160                 [EditorBrowsable (EditorBrowsableState.Never)]
161                 public new event PaintEventHandler Paint;
162                 
163                 public event EventHandler SelectedIndexChanged;         
164                 public event EventHandler SelectionChangeCommitted;
165                 #endregion Events
166
167                 #region Public Properties
168                 public override Color BackColor {
169                         get { return base.BackColor; }
170                         set {
171                                 if (base.BackColor == value)
172                                         return;
173
174                                 base.BackColor = value;
175                                 Refresh ();
176                         }
177                 }
178
179                 [Browsable (false)]
180                 [EditorBrowsable (EditorBrowsableState.Never)]
181                 public override Image BackgroundImage {
182                         get { return base.BackgroundImage; }
183                         set {
184                                 if (base.BackgroundImage == value)
185                                         return;
186
187                                 base.BackgroundImage = value;
188
189                                 if (BackgroundImageChanged != null)
190                                         BackgroundImageChanged (this, EventArgs.Empty);
191
192                                 Refresh ();
193                         }
194                 }
195
196                 protected override CreateParams CreateParams {
197                         get { return base.CreateParams;}
198                 }
199
200                 protected override Size DefaultSize {
201                         get { return new Size (121, PreferredHeight); }
202                 }
203
204                 [RefreshProperties(RefreshProperties.Repaint)]
205                 [DefaultValue (DrawMode.Normal)]
206                 public DrawMode DrawMode {
207                         get { return draw_mode; }
208
209                         set {
210                                 if (!Enum.IsDefined (typeof (DrawMode), value))
211                                         throw new InvalidEnumArgumentException (string.Format("Enum argument value '{0}' is not valid for DrawMode", value));
212
213                                 if (draw_mode == value)
214                                         return;
215
216                                 draw_mode = value;
217                                 Refresh ();
218                         }
219                 }
220
221                 [DefaultValue (ComboBoxStyle.DropDown)]
222                 [RefreshProperties(RefreshProperties.Repaint)]
223                 public ComboBoxStyle DropDownStyle {
224                         get { return dropdown_style; }
225
226                         set {
227                 
228                                 if (!Enum.IsDefined (typeof (ComboBoxStyle), value))
229                                         throw new InvalidEnumArgumentException (string.Format("Enum argument value '{0}' is not valid for ComboBoxStyle", value));
230
231                                 if (dropdown_style == value)
232                                         return;                                 
233                                                                         
234                                 if (dropdown_style == ComboBoxStyle.Simple) {
235                                         if (listbox_ctrl != null) {                                             
236                                                 Controls.Remove (listbox_ctrl);
237                                                 listbox_ctrl.Dispose ();                                                
238                                                 listbox_ctrl = null;
239                                         }
240                                 }
241
242                                 if (dropdown_style != ComboBoxStyle.DropDownList && value == ComboBoxStyle.DropDownList) {
243                                         if (textbox_ctrl != null) {                                             
244                                                 Controls.Remove (textbox_ctrl);
245                                                 textbox_ctrl.Dispose ();                                                
246                                                 textbox_ctrl = null;                                            
247                                         }
248                                 }                               
249
250                                 dropdown_style = value;                                 
251                                 
252                                 if (dropdown_style == ComboBoxStyle.Simple) {
253                                         CBoxInfo.show_button = false;
254                                         
255                                         if (combobox_info.original_height != -1)
256                                                 Height = combobox_info.original_height;
257                                         
258                                         CreateComboListBox ();
259
260                                         if (IsHandleCreated == true) {
261                                                 Controls.Add (listbox_ctrl);
262                                         }
263                                 }
264                                 else {
265                                         CBoxInfo.show_button = true;
266                                         CBoxInfo.button_status = ButtonState.Normal;
267                                 }                               
268         
269                                 if (dropdown_style != ComboBoxStyle.DropDownList && textbox_ctrl == null) {
270                                         textbox_ctrl = new TextBox ();
271                                         textbox_ctrl.TextChanged += new EventHandler (OnTextChangedEdit);
272                                         textbox_ctrl.KeyPress += new KeyPressEventHandler(textbox_ctrl_KeyPress);
273
274                                         if (IsHandleCreated == true) {
275                                                 Controls.Add (textbox_ctrl);
276                                         }
277                                 }
278                                 
279                                 if (DropDownStyleChanged  != null)
280                                         DropDownStyleChanged (this, EventArgs.Empty);
281                                 
282                                 CalcTextArea ();
283                                 Refresh ();
284                         }
285                 }
286
287                 public int DropDownWidth {
288                         get { 
289                                 if (dropdown_width == -1)
290                                         return Width;
291                                         
292                                 return dropdown_width; 
293                         }
294                         set {
295                                 if (dropdown_width == value)
296                                         return;
297                                         
298                                 if (value < 1)
299                                         throw new ArgumentException ("The DropDownWidth value is less than one");
300
301                                 dropdown_width = value;                         
302                         }
303                 }
304                 
305                 [Browsable (false)]
306                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]              
307                 public bool DroppedDown {
308                         get { 
309                                 if (dropdown_style == ComboBoxStyle.Simple)                             
310                                         return true;
311                                 
312                                 return CBoxInfo.droppeddown;
313                         }
314                         set {
315                                 if (dropdown_style == ComboBoxStyle.Simple)                             
316                                         return;
317                                         
318                                         
319                                 if (value == true) {
320                                         DropDownListBox ();
321                                 }
322                                 else {
323                                         listbox_ctrl.Hide ();
324                                 }
325                                 
326                                 if (DropDown != null)
327                                         DropDown (this, EventArgs.Empty);
328                         }
329                 }               
330
331                 public override bool Focused {
332                         get { return base.Focused; }
333                 }
334
335                 public override Color ForeColor {
336                         get { return base.ForeColor; }
337                         set {
338                                 if (base.ForeColor == value)
339                                         return;
340
341                                 base.ForeColor = value;
342                                 Refresh ();
343                         }
344                 }
345
346                 [DefaultValue (true)]
347                 [Localizable (true)]            
348                 public bool IntegralHeight {
349                         get { return integral_height; }
350                         set {
351                                 if (integral_height == value)
352                                         return;
353
354                                 integral_height = value;
355                                 Refresh ();
356                         }
357                 }
358
359                 [Localizable (true)]
360                 public virtual int ItemHeight {
361                         get { return combobox_info.item_height; }
362                         set {
363                                 if (value < 0)
364                                         throw new ArgumentOutOfRangeException ("The item height value is less than zero");
365
366                                 combobox_info.item_height = value;
367                                 CalcTextArea ();
368                                 Refresh ();
369                         }
370                 }
371
372                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
373                 [Localizable (true)]
374                 [Editor ("System.Windows.Forms.Design.ListControlStringCollectionEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]                
375                 public ComboBox.ObjectCollection Items {
376                         get { return items; }
377                 }
378
379                 [DefaultValue (8)]
380                 [Localizable (true)]
381                 public int MaxDropDownItems {
382                         get { return maxdrop_items; }
383                         set {
384                                 if (maxdrop_items == value)
385                                         return;
386
387                                 maxdrop_items = value;
388                         }
389                 }
390
391                 [DefaultValue (0)]
392                 [Localizable (true)]
393                 public int MaxLength {
394                         get { return max_length; }
395                         set {
396                                 if (max_length == value)
397                                         return;
398
399                                 max_length = value;
400                                 
401                                 if (dropdown_style != ComboBoxStyle.DropDownList) {
402                                         
403                                         if (value < 0) {
404                                                 value = 0;
405                                         }
406                                         
407                                         textbox_ctrl.MaxLength = value;
408                                 }                       
409                         }
410                 }
411
412                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
413                 [Browsable (false)]             
414                 public int PreferredHeight {
415                         get { return preferred_height; }
416                 }
417                 
418                 [Browsable (false)]
419                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
420                 public override int SelectedIndex {
421                         get { return selected_index; }
422                         set {
423                                 if (value < -2 || value >= Items.Count)
424                                         throw new ArgumentOutOfRangeException ("Index of out range");
425
426                                 if (selected_index == value)
427                                         return;
428
429                                 selected_index = value;
430                                 
431                                 if (dropdown_style != ComboBoxStyle.DropDownList) {
432                                         SetControlText (GetItemText (Items[selected_index]));
433                                 }
434                                 
435                                 OnSelectedIndexChanged  (new EventArgs ());
436                                 OnSelectedValueChanged (new EventArgs ());
437                                 OnSelectedItemChanged (new EventArgs ());
438                                 Refresh ();
439                         }
440                 }
441
442                 [Browsable (false)]
443                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
444                 [Bindable(true)]
445                 public object SelectedItem {
446                         get {
447                                 if (selected_index !=-1 && Items !=null && Items.Count > 0)
448                                         return Items[selected_index];
449                                 else
450                                         return null;
451                                 }                               
452                         set {                           
453                                 int index = Items.IndexOf (value);
454
455                                 if (index == -1)
456                                         return;
457                                         
458                                 if (selected_index == index)
459                                         return;
460
461                                 selected_index = index;
462                                 
463                                 if (dropdown_style != ComboBoxStyle.DropDownList) {
464                                         SetControlText (GetItemText (Items[selected_index]));
465                                 }
466                                 
467                                 OnSelectedItemChanged  (new EventArgs ());
468                                 Refresh ();
469                         }
470                 }
471                 
472                 [Browsable (false)]
473                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
474                 public string SelectedText {
475                         get {
476                                 if (dropdown_style == ComboBoxStyle.DropDownList)
477                                         return "";
478                                         
479                                 return textbox_ctrl.SelectedText;
480                         }
481                         set {
482                                 if (dropdown_style == ComboBoxStyle.DropDownList) {
483                                         return;
484                                 }
485                                 
486                                 textbox_ctrl.SelectedText = value;
487                         }
488                 }
489
490                 [Browsable (false)]
491                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
492                 public int SelectionLength {
493                         get {
494                                 if (dropdown_style == ComboBoxStyle.DropDownList) 
495                                         return 0;
496                                 
497                                 return textbox_ctrl.SelectionLength;
498                         }
499                         set {
500                                 if (dropdown_style == ComboBoxStyle.DropDownList) 
501                                         return;
502                                         
503                                 if (textbox_ctrl.SelectionLength == value)
504                                         return;
505                                         
506                                 textbox_ctrl.SelectionLength = value;
507                         }
508                 }
509
510                 [Browsable (false)]
511                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
512                 public int SelectionStart {
513                         get { 
514                                 if (dropdown_style == ComboBoxStyle.DropDownList) 
515                                         return 0;                                       
516                                 
517                                 return textbox_ctrl.SelectionStart;                             
518                         }
519                         set {
520                                 if (dropdown_style == ComboBoxStyle.DropDownList) 
521                                         return;
522                                 
523                                 if (textbox_ctrl.SelectionStart == value)
524                                         return;                                 
525                                 
526                                 textbox_ctrl.SelectionStart = value;
527                         }
528                 }
529
530                 [DefaultValue (false)]
531                 public bool Sorted {
532                         get { return sorted; }
533
534                         set {
535                                 if (sorted == value)
536                                         return;
537
538                                 sorted = value;
539                         }
540                 }
541
542                 [Bindable (true)]
543                 [Localizable (true)]
544                 public override string Text {
545                         get {
546                                 if (dropdown_style != ComboBoxStyle.DropDownList) {
547                                         if (textbox_ctrl != null) {
548                                                 return textbox_ctrl.Text;
549                                         }
550                                 }
551
552                                 if (SelectedItem != null)  {
553                                         return GetItemText (SelectedItem);
554                                 }
555                                                                 
556                                 return base.Text;                               
557                         }
558                         set {                           
559                                 if (value == null) {
560                                         SelectedIndex = -1;
561                                         return;
562                                 }
563                                 
564                                 int index = FindString (value);
565                                 
566                                 if (index != -1) {
567                                         SelectedIndex = index;
568                                         return;                                 
569                                 }
570                                 
571                                 if (dropdown_style != ComboBoxStyle.DropDownList) {
572                                         textbox_ctrl.Text = GetItemText (value);
573                                 }                               
574                         }
575                 }
576
577                 #endregion Public Properties
578
579                 #region Private Properties
580                 internal ComboBoxInfo CBoxInfo {
581                         get { return combobox_info; }
582                 }
583
584                 #endregion Private Properties
585
586                 #region Public Methods
587                 protected virtual void AddItemsCore (object[] value)
588                 {
589                         
590                 }
591
592                 public void BeginUpdate ()
593                 {
594                         suspend_ctrlupdate = true;
595                 }
596
597                 protected override void Dispose (bool disposing)
598                 {                                               
599                         if (disposing == true) {
600                                 if (listbox_ctrl != null) {
601                                         listbox_ctrl.Dispose ();
602                                         Controls.Remove (listbox_ctrl);
603                                         listbox_ctrl = null;
604                                 }                       
605                         
606                                 if (textbox_ctrl != null) {
607                                         Controls.Remove (textbox_ctrl);
608                                         textbox_ctrl.Dispose ();
609                                         textbox_ctrl = null;
610                                 }                       
611                         }
612                         
613                         base.Dispose (disposing);
614                 }
615
616                 public void EndUpdate ()
617                 {
618                         suspend_ctrlupdate = false;
619                         UpdatedItems ();
620                 }
621
622                 public int FindString (string s)
623                 {
624                         return FindString (s, 0);
625                 }
626
627                 public int FindString (string s, int startIndex)
628                 {
629                         for (int i = startIndex; i < Items.Count; i++) {
630                                 if ((GetItemText (Items[i])).StartsWith (s))
631                                         return i;
632                         }
633
634                         return -1;
635                 }
636
637                 public int FindStringExact (string s)
638                 {
639                         return FindStringExact (s, 0);
640                 }
641
642                 public int FindStringExact (string s, int startIndex)
643                 {
644                         for (int i = startIndex; i < Items.Count; i++) {
645                                 if ((GetItemText (Items[i])).Equals (s))
646                                         return i;
647                         }
648
649                         return -1;
650                 }
651
652                 public int GetItemHeight (int index)
653                 {
654                         if (index < 0 || index >= Items.Count )
655                                 throw new ArgumentOutOfRangeException ("The item height value is less than zero");
656                                 
657                         if (DrawMode == DrawMode.OwnerDrawVariable && IsHandleCreated == true) {
658                                 
659                                 if ((Items.GetComboBoxItem (index)).ItemHeight != -1) {
660                                         return (Items.GetComboBoxItem (index)).ItemHeight;
661                                 }
662                                 
663                                 MeasureItemEventArgs args = new MeasureItemEventArgs (DeviceContext, index, ItemHeight);
664                                 OnMeasureItem (args);
665                                 (Items.GetComboBoxItem (index)).ItemHeight = args.ItemHeight;
666                                 return args.ItemHeight;
667                         }
668
669                         return ItemHeight;
670                 }
671
672                 protected override bool IsInputKey (Keys keyData)
673                 {
674                         switch (keyData) {
675                         case Keys.Up:
676                         case Keys.Down:
677                         case Keys.PageUp:
678                         case Keys.PageDown:                     
679                                 return true;
680                         
681                         default:                                        
682                                 return false;
683                         }
684                 }
685
686                 protected override void OnBackColorChanged (EventArgs e)
687                 {
688                         base.OnBackColorChanged (e);
689                 }
690
691                 protected override void OnDataSourceChanged (EventArgs e)
692                 {
693                         base.OnDataSourceChanged (e);
694                         BindDataItems (items);
695                         
696                         if (DataSource == null || DataManager == null) {
697                                 SelectedIndex = -1;
698                         } 
699                         else {
700                                 SelectedIndex = DataManager.Position;
701                         }
702                 }
703
704                 protected override void OnDisplayMemberChanged (EventArgs e)
705                 {
706                         base.OnDisplayMemberChanged (e);
707
708                         if (DataManager == null || !IsHandleCreated)
709                                return;
710
711                         BindDataItems (items);
712                         SelectedIndex = DataManager.Position;
713                 }
714
715                 protected virtual void OnDrawItem (DrawItemEventArgs e)
716                 {
717                         if (DrawItem != null && (DrawMode == DrawMode.OwnerDrawFixed || DrawMode == DrawMode.OwnerDrawVariable)) {
718                                 DrawItem (this, e);
719                                 return;
720                         }
721                         
722                         ThemeEngine.Current.DrawComboBoxItem (this, e);
723                 }               
724
725                 protected virtual void OnDropDown (EventArgs e)
726                 {
727                         if (DropDown != null)
728                                 DropDown (this, e);
729                 }
730
731                 protected virtual void OnDropDownStyleChanged (EventArgs e)
732                 {
733                         if (DropDownStyleChanged != null)
734                                 DropDownStyleChanged (this, e);
735                 }
736
737                 protected override void OnFontChanged (EventArgs e)
738                 {
739                         base.OnFontChanged (e);
740                         
741                         if (textbox_ctrl != null) {
742                                 textbox_ctrl.Font = Font;
743                         }
744                         
745                         combobox_info.item_height = FontHeight + 2;
746                         CalcTextArea ();
747                 }
748
749                 protected override void OnForeColorChanged (EventArgs e)
750                 {
751                         base.OnForeColorChanged (e);
752                 }
753
754                 [EditorBrowsable(EditorBrowsableState.Advanced)]                
755                 protected override void OnGotFocus (EventArgs e) {                      
756                         has_focus = true;
757                         Invalidate ();
758                 }
759
760                 [EditorBrowsable(EditorBrowsableState.Advanced)]                
761                 protected override void OnLostFocus (EventArgs e) {                     
762                         has_focus = false;
763                         Invalidate ();
764                 }               
765
766                 protected override void OnHandleCreated (EventArgs e)
767                 {
768                         base.OnHandleCreated (e);
769
770                         if (listbox_ctrl != null) {
771                                 Controls.Add (listbox_ctrl);
772                         }
773                         
774                         if (textbox_ctrl != null) {
775                                 Controls.Add (textbox_ctrl);
776                         }
777
778                         CalcTextArea ();
779                 }
780
781                 protected override void OnHandleDestroyed (EventArgs e)
782                 {
783                         base.OnHandleDestroyed (e);
784                 }
785
786                 protected override void OnKeyPress (KeyPressEventArgs e)
787                 {
788                         base.OnKeyPress (e);
789                 }
790
791                 protected virtual void OnMeasureItem (MeasureItemEventArgs e)
792                 {
793                         if (MeasureItem != null)
794                                 MeasureItem (this, e);
795                 }
796
797                 protected override void OnParentBackColorChanged (EventArgs e)
798                 {
799                         base.OnParentBackColorChanged (e);
800                 }
801
802                 protected override void OnResize (EventArgs e)
803                 {
804                         base.OnResize (e);
805                         AdjustHeightForDropDown ();
806                         CalcTextArea ();                        
807                 }
808
809                 protected override void OnSelectedIndexChanged (EventArgs e)
810                 {
811                         base.OnSelectedIndexChanged (e);
812
813                         if (SelectedIndexChanged != null)
814                                 SelectedIndexChanged (this, e);
815                 }
816
817                 protected virtual void OnSelectedItemChanged (EventArgs e)
818                 {
819                         
820                 }
821
822                 protected override void OnSelectedValueChanged (EventArgs e)
823                 {
824                         base.OnSelectedValueChanged (e);
825                 }
826
827                 protected virtual void OnSelectionChangeCommitted (EventArgs e)
828                 {
829                         if (SelectionChangeCommitted != null)
830                                 SelectionChangeCommitted (this, e);
831                 }
832
833                 protected override void RefreshItem (int index)
834                 {
835                         if (index < 0 || index >= Items.Count)
836                                 throw new ArgumentOutOfRangeException ("Index of out range");
837                                 
838                         if (draw_mode == DrawMode.OwnerDrawVariable) {
839                                 (Items.GetComboBoxItem (index)).ItemHeight = -1;
840                         }
841                 }
842
843                 public void Select (int start, int lenght)
844                 {
845                         if (start < 0)
846                                 throw new ArgumentException ("Start cannot be less than zero");
847                                 
848                         if (lenght < 0)
849                                 throw new ArgumentException ("Start cannot be less than zero");
850                                 
851                         if (dropdown_style == ComboBoxStyle.DropDownList)
852                                 return;
853                                 
854                         textbox_ctrl.Select (start, lenght);
855                 }
856
857                 public void SelectAll ()
858                 {
859                         if (dropdown_style == ComboBoxStyle.DropDownList)
860                                 return;
861                                 
862                         textbox_ctrl.SelectAll ();
863                 }               
864
865                 protected override void SetBoundsCore (int x, int y, int width, int height, BoundsSpecified specified)
866                 {
867                         base.SetBoundsCore (x, y, width, height, specified);
868                 }
869
870                 protected override void SetItemCore (int index, object value)
871                 {
872                         if (index < 0 || index >= Items.Count)
873                                 return;
874
875                         Items[index] = value;
876                 }
877
878                 protected override void SetItemsCore (IList value)
879                 {
880                         Items.AddRange (value);
881                 }
882
883                 public override string ToString ()
884                 {
885                         return base.ToString () + ", Items.Count:" + Items.Count;
886                 }
887
888                 protected override void WndProc (ref Message m)
889                 {
890
891                         switch ((Msg) m.Msg) {
892
893                         case Msg.WM_PAINT: {
894                                 PaintEventArgs  paint_event;
895                                 paint_event = XplatUI.PaintEventStart (Handle);
896                                 OnPaintCB (paint_event);
897                                 XplatUI.PaintEventEnd (Handle);
898                                 return;
899                         }
900
901                         case Msg.WM_ERASEBKGND:
902                                 m.Result = (IntPtr) 1;
903                                 return;
904
905                         default:
906                                 break;
907                         }
908
909                         base.WndProc (ref m);
910
911                 }
912
913                 #endregion Public Methods
914
915                 #region Private Methods
916                 
917                 private void AdjustHeightForDropDown ()
918                 {
919                         if (dropdown_style == ComboBoxStyle.Simple) 
920                                 return;
921                                 
922                         int new_height = combobox_info.item_height + ThemeEngine.Current.DrawComboBoxEditDecorationTop () +
923                                 ThemeEngine.Current.DrawComboBoxEditDecorationBottom () + 2;
924                                 
925                         if (Height == new_height)
926                                 return;         
927                                 
928                         combobox_info.original_height = Height;
929                         Height = new_height;
930                 }
931
932                 private void textbox_ctrl_KeyPress(object sender, KeyPressEventArgs e) 
933                 {\r
934                         OnKeyPress (e);\r
935                 }\r
936                 
937                 // Calcs the text area size
938                 internal void CalcTextArea ()
939                 {                       
940                         combobox_info.textarea = ClientRectangle;
941                                         
942                         /* Edit area */
943                         combobox_info.textarea.Height = ItemHeight + ThemeEngine.Current.DrawComboBoxEditDecorationTop () +
944                                         ThemeEngine.Current.DrawComboBoxEditDecorationBottom () + 2;
945                                         // TODO: Does the +2 change at different font resolutions?
946                         
947                         /* Edit area - minus decorations (text drawable area) */
948                         combobox_info.textarea_drawable = combobox_info.textarea;
949                         combobox_info.textarea_drawable.Y += ThemeEngine.Current.DrawComboBoxEditDecorationTop ();
950                         combobox_info.textarea_drawable.X += ThemeEngine.Current.DrawComboBoxEditDecorationLeft ();
951                         combobox_info.textarea_drawable.Height -= ThemeEngine.Current.DrawComboBoxEditDecorationBottom ();
952                         combobox_info.textarea_drawable.Height -= ThemeEngine.Current.DrawComboBoxEditDecorationTop();
953                         combobox_info.textarea_drawable.Width -= ThemeEngine.Current.DrawComboBoxEditDecorationRight ();
954                         combobox_info.textarea_drawable.Width -= ThemeEngine.Current.DrawComboBoxEditDecorationLeft ();
955                         
956                         /* Non-drawable area */
957                         Region area = new Region (ClientRectangle);
958                         area.Exclude (combobox_info.textarea);
959                         RectangleF bounds = area.GetBounds (DeviceContext);
960                         combobox_info.listbox_area = new Rectangle ((int)bounds.X, (int)bounds.Y, 
961                                 (int)bounds.Width, (int)bounds.Height);                         
962                         
963                         if (CBoxInfo.show_button) {
964                                 combobox_info.textarea_drawable.Width -= def_button_width;
965
966                                 combobox_info.button_rect = new Rectangle (combobox_info.textarea_drawable.X + combobox_info.textarea_drawable.Width,
967                                         combobox_info.textarea_drawable.Y, def_button_width, combobox_info.textarea_drawable.Height);                           
968                                         
969                         }
970                         
971                         if (dropdown_style != ComboBoxStyle.DropDownList) { /* There is an edit control*/
972                                 if (textbox_ctrl != null) {
973                                         textbox_ctrl.Location = new Point (combobox_info.textarea_drawable.X, combobox_info.textarea_drawable.Y);
974                                         textbox_ctrl.Size = new Size (combobox_info.textarea_drawable.Width, combobox_info.textarea_drawable.Height);                                   
975                                 }
976                         }
977                         
978                         if (listbox_ctrl != null && dropdown_style == ComboBoxStyle.Simple) {
979                                 listbox_ctrl.Location = new Point (combobox_info.textarea.X, combobox_info.textarea.Y +
980                                         combobox_info.textarea.Height);
981                                 listbox_ctrl.CalcListBoxArea ();
982                         }
983                         
984                         area.Dispose ();
985                 }
986
987                 private void CreateComboListBox ()
988                 {                       
989                         listbox_ctrl = new ComboListBox (this);                 
990                 }
991                 
992                 internal void Draw (Rectangle clip, Graphics dc)
993                 {                               
994                         // No edit control, we paint the edit ourselfs
995                         if (dropdown_style == ComboBoxStyle.DropDownList) {
996                                 DrawItemState state = DrawItemState.None;
997                                 Rectangle item_rect = combobox_info.textarea_drawable;
998                                 item_rect.Height = ItemHeight + 2;                              
999                                                                 
1000                                 if (has_focus == true) {
1001                                         state = DrawItemState.Selected;
1002                                         state |= DrawItemState.Focus;
1003                                 }
1004                                 
1005                                 OnDrawItem (new DrawItemEventArgs (dc, Font, item_rect,
1006                                                         selected_index, state, ForeColor, BackColor));
1007                         }                                               
1008                         
1009                         if (clip.IntersectsWith (combobox_info.listbox_area) == true) {
1010                                 dc.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (Parent.BackColor), 
1011                                                 combobox_info.listbox_area);
1012                         }
1013                         
1014                         if (CBoxInfo.show_button) {
1015                                 dc.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (ThemeEngine.Current.ColorButtonFace),
1016                                         combobox_info.button_rect);
1017
1018                                 ThemeEngine.Current.CPDrawComboButton (dc,
1019                                         combobox_info.button_rect, combobox_info.button_status);
1020                         }                       
1021                         
1022                         ThemeEngine.Current.DrawComboBoxEditDecorations (dc, this, combobox_info.textarea);
1023                 }
1024
1025                 internal void DropDownListBox ()
1026                 {
1027                         if (DropDownStyle == ComboBoxStyle.Simple)
1028                                 return;                 
1029                         
1030                         if (listbox_ctrl == null) {
1031                                 CreateComboListBox ();
1032                         }
1033
1034                         listbox_ctrl.Location = PointToScreen (new Point (combobox_info.textarea.X, combobox_info.textarea.Y +
1035                                 combobox_info.textarea.Height));
1036                                                 
1037                         if (listbox_ctrl.ShowWindow () == true) {                               
1038                                 CBoxInfo.droppeddown = true;                                    
1039                         }
1040                         
1041                         combobox_info.button_status = ButtonState.Pushed;                               
1042                         if (dropdown_style == ComboBoxStyle.DropDownList) {
1043                                 Invalidate (combobox_info.textarea_drawable);
1044                         }
1045                 }
1046                 
1047                 internal void DropDownListBoxFinished ()
1048                 {
1049                         if (DropDownStyle == ComboBoxStyle.Simple)
1050                                 return;                 
1051                                 
1052                         combobox_info.button_status = ButtonState.Normal;
1053                         Invalidate (combobox_info.button_rect);
1054                         CBoxInfo.droppeddown = false;
1055                         clicked = false;                        
1056                 }
1057                 
1058                 private int FindStringCaseInsensitive (string search)
1059                 {                       
1060                         for (int i = 0; i < Items.Count; i++) 
1061                         {                               
1062                                 if (String.Compare (GetItemText (Items[i]), 0, search, 0, search.Length, true) == 0)
1063                                         return i;
1064                         }
1065
1066                         return -1;
1067                 }
1068                 
1069                 internal virtual void OnMouseDownCB (object sender, MouseEventArgs e)
1070                 {                       
1071                         /* Click On button*/                            
1072                         Rectangle hit_rect;
1073                         
1074                         if (dropdown_style == ComboBoxStyle.DropDownList) {
1075                                 hit_rect = combobox_info.textarea;
1076                         } else {
1077                                 hit_rect = combobox_info.button_rect;
1078                         }                       
1079                         
1080                         if (hit_rect.Contains (e.X, e.Y)) {
1081                                 if (clicked == false) {
1082                                         clicked = true;
1083                                         DropDownListBox ();                                     
1084                                 } else {
1085                                         listbox_ctrl.Hide ();
1086                                         DropDownListBoxFinished ();
1087                                 }
1088                                 
1089                                 Invalidate (combobox_info.button_rect);
1090                         }
1091                 }
1092                 
1093                 internal virtual void OnMouseMoveCB (object sender, MouseEventArgs e)
1094                 {                       
1095                         /* When there are no items, act as a regular button */
1096                         if (clicked == true && Items.Count == 0 &&
1097                                  combobox_info.button_rect.Contains (e.X, e.Y) == false) {
1098                                 DropDownListBoxFinished ();
1099                         }
1100                 }
1101
1102                 internal virtual void OnMouseUpCB (object sender, MouseEventArgs e)
1103                 {
1104                         /* Click on button*/
1105                         if (clicked == true && combobox_info.button_rect.Contains (e.X, e.Y)) {                                 
1106                                 DropDownListBoxFinished ();
1107                         }
1108                 }
1109
1110                 private void OnPaintCB (PaintEventArgs pevent)
1111                 {
1112                         if (Width <= 0 || Height <=  0 || Visible == false || suspend_ctrlupdate == true)
1113                                 return;
1114                                 
1115                         /* Copies memory drawing buffer to screen*/
1116                         Draw (ClientRectangle, pevent.Graphics);                        
1117
1118                         if (Paint != null)
1119                                 Paint (this, pevent);
1120                 }
1121                 
1122                 private void OnTextChangedEdit (object sender, EventArgs e)
1123                 {
1124                         if (process_textchanged_event == false)
1125                                 return; 
1126                                 
1127                         int item = FindStringCaseInsensitive (textbox_ctrl.Text);
1128                         
1129                         if (item == -1)
1130                                 return;
1131                         
1132                         listbox_ctrl.SetTopItem (item);
1133                         listbox_ctrl.SetHighLightedItem (Items[item]);
1134                 }
1135                 
1136                 internal void SetControlText (string s)
1137                 {               
1138                         process_textchanged_event = false; 
1139                         textbox_ctrl.Text = s;
1140                         process_textchanged_event = true;
1141                 }
1142                 
1143                 private void UpdatedItems ()
1144                 {
1145                         if (dropdown_style != ComboBoxStyle.Simple)
1146                                 return;                         
1147                                                         
1148                         listbox_ctrl.UpdateLastVisibleItem ();
1149                         listbox_ctrl.CalcListBoxArea ();
1150                         listbox_ctrl.Refresh ();
1151                 }
1152
1153                 #endregion Private Methods
1154
1155
1156                 /*
1157                         ComboBox.ObjectCollection
1158                 */
1159                 [ListBindableAttribute (false)]
1160                 public class ObjectCollection : IList, ICollection, IEnumerable
1161                 {
1162
1163                         private ComboBox owner;
1164                         internal ArrayList object_items = new ArrayList ();
1165                         internal ArrayList combobox_items = new ArrayList ();
1166
1167                         public ObjectCollection (ComboBox owner)
1168                         {
1169                                 this.owner = owner;
1170                         }
1171
1172                         #region Public Properties
1173                         public virtual int Count {
1174                                 get { return object_items.Count; }
1175                         }
1176
1177                         public virtual bool IsReadOnly {
1178                                 get { return false; }
1179                         }
1180
1181                         [Browsable (false)]
1182                         [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
1183                         public virtual object this [int index] {
1184                                 get {
1185                                         if (index < 0 || index >= Count)
1186                                                 throw new ArgumentOutOfRangeException ("Index of out range");
1187
1188                                         return object_items[index];
1189                                 }
1190                                 set {
1191                                         if (index < 0 || index >= Count)
1192                                                 throw new ArgumentOutOfRangeException ("Index of out range");
1193
1194                                         object_items[index] = value;
1195                                 }
1196                         }
1197
1198                         bool ICollection.IsSynchronized {
1199                                 get { return false; }
1200                         }
1201
1202                         object ICollection.SyncRoot {
1203                                 get { return this; }
1204                         }
1205
1206                         bool IList.IsFixedSize {
1207                                 get { return false; }
1208                         }
1209
1210                         #endregion Public Properties
1211                         
1212                         #region Private Properties                      
1213                         internal ArrayList ObjectItems {
1214                                 get { return object_items;}
1215                                 set {
1216                                         object_items = value;
1217                                 }
1218                         }
1219                         
1220                         internal ArrayList ListBoxItems {
1221                                 get { return combobox_items;}
1222                                 set {
1223                                         combobox_items = value;
1224                                 }
1225                         }                       
1226                         #endregion Private Properties
1227
1228                         #region Public Methods
1229                         public int Add (object item)
1230                         {
1231                                 int idx;
1232
1233                                 idx = AddItem (item);
1234                                 owner.UpdatedItems ();
1235                                 return idx;
1236                         }
1237
1238                         public void AddRange (object[] items)
1239                         {
1240                                 foreach (object mi in items)
1241                                         AddItem (mi);
1242                                         
1243                                 owner.UpdatedItems ();
1244                         }
1245
1246                         public virtual void Clear ()
1247                         {
1248                                 owner.selected_index = -1;
1249                                 object_items.Clear ();
1250                                 combobox_items.Clear ();
1251                                 owner.UpdatedItems ();
1252                                 owner.Refresh ();
1253                         }
1254                         
1255                         public virtual bool Contains (object obj)
1256                         {
1257                                 return object_items.Contains (obj);
1258                         }
1259
1260                         public void CopyTo (object[] dest, int arrayIndex)
1261                         {
1262                                 object_items.CopyTo (dest, arrayIndex);
1263                         }
1264
1265                         void ICollection.CopyTo (Array dest, int index)
1266                         {
1267                                 object_items.CopyTo (dest, index);
1268                         }
1269
1270                         public virtual IEnumerator GetEnumerator ()
1271                         {
1272                                 return object_items.GetEnumerator ();
1273                         }
1274
1275                         int IList.Add (object item)
1276                         {
1277                                 return Add (item);
1278                         }
1279
1280                         public virtual int IndexOf (object value)
1281                         {
1282                                 return object_items.IndexOf (value);
1283                         }
1284
1285                         public virtual void Insert (int index,  object item)
1286                         {
1287                                 if (index < 0 || index > Count)
1288                                         throw new ArgumentOutOfRangeException ("Index of out range");                                   
1289                                 
1290                                 ObjectCollection new_items = new ObjectCollection (owner);                              
1291                                 object sel_item = owner.SelectedItem;
1292                                                                                                 
1293                                 owner.BeginUpdate ();
1294                                 
1295                                 for (int i = 0; i < index; i++) {
1296                                         new_items.AddItem (ObjectItems[i]);
1297                                 }
1298
1299                                 new_items.AddItem (item);
1300
1301                                 for (int i = index; i < Count; i++){
1302                                         new_items.AddItem (ObjectItems[i]);
1303                                 }                               
1304
1305                                 ObjectItems = new_items.ObjectItems;
1306                                 ListBoxItems = new_items.ListBoxItems;
1307                                 
1308                                 if (sel_item != null) {
1309                                         int idx = IndexOf (sel_item);
1310                                         owner.selected_index = idx;
1311                                         owner.listbox_ctrl.SetHighLightedItem (owner.Items[idx]);
1312                                 }
1313                                                                                                 
1314                                 owner.EndUpdate ();     // Calls UpdatedItems
1315                         }
1316
1317                         public virtual void Remove (object value)
1318                         {                               
1319                                 if (IndexOf (value) == owner.SelectedIndex)
1320                                         owner.SelectedItem = null;
1321                                 
1322                                 RemoveAt (IndexOf (value));                             
1323                                 
1324                         }
1325
1326                         public virtual void RemoveAt (int index)
1327                         {
1328                                 if (index < 0 || index >= Count)
1329                                         throw new ArgumentOutOfRangeException ("Index of out range");
1330                                         
1331                                 if (index == owner.SelectedIndex)
1332                                         owner.SelectedItem = null;
1333
1334                                 object_items.RemoveAt (index);
1335                                 combobox_items.RemoveAt (index);
1336                                 owner.UpdatedItems ();
1337                         }
1338                         #endregion Public Methods
1339
1340                         #region Private Methods
1341                         private int AddItem (object item)
1342                         {
1343                                 int cnt = object_items.Count;
1344                                 object_items.Add (item);
1345                                 combobox_items.Add (new ComboBox.ComboBoxItem (cnt));                           
1346                                 return cnt;
1347                         }
1348                         
1349                         internal void AddRange (IList items)
1350                         {
1351                                 foreach (object mi in items)
1352                                         AddItem (mi);
1353                                                                                 
1354                                 owner.UpdatedItems ();
1355                         }
1356
1357                         internal ComboBox.ComboBoxItem GetComboBoxItem (int index)
1358                         {
1359                                 if (index < 0 || index >= Count)
1360                                         throw new ArgumentOutOfRangeException ("Index of out range");
1361
1362                                 return (ComboBox.ComboBoxItem) combobox_items[index];
1363                         }
1364
1365                         internal void SetComboBoxItem (ComboBox.ComboBoxItem item, int index)
1366                         {
1367                                 if (index < 0 || index >= Count)
1368                                         throw new ArgumentOutOfRangeException ("Index of out range");
1369
1370                                 combobox_items[index] = item;
1371                         }
1372
1373                         #endregion Private Methods
1374                 }
1375
1376                 /*
1377                         class ComboListBox
1378                 */
1379                 internal class ComboListBox : Control
1380                 {
1381                         private ComboBox owner;                 
1382                         private VScrollBarLB vscrollbar_ctrl;
1383                         private int top_item;                   /* First item that we show the in the current page */
1384                         private int last_item;                  /* Last visible item */
1385                         public object highlighted_item; /* Item that is currently selected */
1386                         internal int page_size;                 /* Number of listbox items per page */
1387                         private Rectangle textarea_drawable;    /* Rectangle of the drawable text area */
1388                         
1389                         internal enum ItemNavigation
1390                         {
1391                                 First,
1392                                 Last,
1393                                 Next,
1394                                 Previous,
1395                                 NextPage,
1396                                 PreviousPage,
1397                         }
1398                         
1399                         class VScrollBarLB : VScrollBar
1400                         {
1401                                 public VScrollBarLB ()
1402                                 {                                       
1403                                 }
1404                                 
1405                                 public void FireMouseDown (MouseEventArgs e) 
1406                                 {
1407                                         OnMouseDown (e);
1408                                 }       
1409                                 
1410                                 public void FireMouseUp (MouseEventArgs e) 
1411                                 {
1412                                         OnMouseUp (e);
1413                                 }
1414                                 
1415                                 public void FireMouseMove (MouseEventArgs e) 
1416                                 {
1417                                         OnMouseMove (e);
1418                                 }                       
1419                                 
1420                         }
1421
1422                         public ComboListBox (ComboBox owner) : base ()
1423                         {       
1424                                 this.owner = owner;                                                             
1425                                 top_item = 0;
1426                                 last_item = 0;
1427                                 page_size = 0;
1428                                 highlighted_item = null;
1429
1430                                 MouseDown += new MouseEventHandler (OnMouseDownPUW);
1431                                 MouseUp += new MouseEventHandler (OnMouseUpPUW);
1432                                 MouseMove += new MouseEventHandler (OnMouseMovePUW);                            
1433                                 KeyDown += new KeyEventHandler (OnKeyDownPUW);
1434                                 Paint += new PaintEventHandler (OnPaintPUW);                            
1435                                 SetStyle (ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true);
1436                                 SetStyle (ControlStyles.ResizeRedraw | ControlStyles.Opaque, true);                             
1437                         }
1438
1439                         protected override CreateParams CreateParams
1440                         {
1441                                 get {
1442                                         CreateParams cp = base.CreateParams;                                    
1443                                         if (owner != null && owner.DropDownStyle != ComboBoxStyle.Simple) {
1444                                                 cp.Style = unchecked ((int)(WindowStyles.WS_POPUP | WindowStyles.WS_VISIBLE | WindowStyles.WS_CLIPSIBLINGS | WindowStyles.WS_CLIPCHILDREN));
1445                                                 cp.ExStyle |= (int)(WindowStyles.WS_EX_TOOLWINDOW | WindowStyles.WS_EX_TOPMOST);
1446                                         }                                       
1447                                         return cp;
1448                                 }
1449                         }
1450
1451                         #region Private Methods                 
1452                         // Calcs the listbox area
1453                         internal void CalcListBoxArea ()
1454                         {                               
1455                                 int width, height;
1456                                 int item_height = owner.ItemHeight;
1457                                 bool show_scrollbar = false;
1458                                 
1459                                 if (owner.DropDownStyle == ComboBoxStyle.Simple) {
1460                                         width = owner.CBoxInfo.listbox_area.Width;
1461                                         height = owner.CBoxInfo.listbox_area.Height;
1462
1463                                         if (owner.IntegralHeight == true) {
1464                                                 int remaining = (height -
1465                                                         ThemeEngine.Current.DrawComboListBoxDecorationBottom (owner.DropDownStyle) -
1466                                                         ThemeEngine.Current.DrawComboListBoxDecorationTop (owner.DropDownStyle)) %
1467                                                         (item_height - 2);                                                      
1468                 
1469                                                 if (remaining > 0) {
1470                                                         height -= remaining;                                                    
1471                                                 }
1472                                         }
1473                                 }
1474                                 else { // DropDown or DropDownList
1475                                         
1476                                         width = owner.DropDownWidth;
1477                                         int count = (owner.Items.Count <= owner.MaxDropDownItems) ? owner.Items.Count : owner.MaxDropDownItems;                         
1478                                         
1479                                         if (owner.DrawMode == DrawMode.OwnerDrawVariable) {                                             
1480                                                 height = 0;
1481                                                 for (int i = 0; i < count; i++) {
1482                                                         height += owner.GetItemHeight (i);
1483                                                 }
1484                                                 
1485                                         } else  {
1486                                                 height = (item_height - 2) * count;
1487                                         }
1488                                         
1489                                         
1490                                         height += ThemeEngine.Current.DrawComboListBoxDecorationBottom (owner.DropDownStyle);                           
1491                                         height += ThemeEngine.Current.DrawComboListBoxDecorationTop (owner.DropDownStyle);
1492                                 }
1493                                 
1494                                 if (owner.Items.Count <= owner.MaxDropDownItems) {                                      
1495                                         
1496                                         /* Does not need vertical scrollbar*/
1497                                         if (vscrollbar_ctrl != null) {                                          
1498                                                 vscrollbar_ctrl.Visible = false;                                                
1499                                         }                                       
1500                                 }
1501                                 else {
1502                                         /* Need vertical scrollbar */
1503                                         if (vscrollbar_ctrl == null) {
1504                                                 vscrollbar_ctrl = new VScrollBarLB ();
1505                                                 vscrollbar_ctrl.Minimum = 0;
1506                                                 vscrollbar_ctrl.SmallChange = 1;
1507                                                 vscrollbar_ctrl.LargeChange = 1;
1508                                                 vscrollbar_ctrl.Maximum = 0;
1509                                                 vscrollbar_ctrl.ValueChanged += new EventHandler (VerticalScrollEvent);
1510                                                 
1511                                                 Controls.Add (vscrollbar_ctrl);
1512                                         }
1513                                         
1514                                         vscrollbar_ctrl.Height = height - ThemeEngine.Current.DrawComboListBoxDecorationBottom (owner.DropDownStyle) -
1515                                                         ThemeEngine.Current.DrawComboListBoxDecorationTop (owner.DropDownStyle);
1516                                                         
1517                                         vscrollbar_ctrl.Location = new Point (width - vscrollbar_ctrl.Width - ThemeEngine.Current.DrawComboListBoxDecorationRight (owner.DropDownStyle), 
1518                                                         ThemeEngine.Current.DrawComboListBoxDecorationTop (owner.DropDownStyle));
1519                                                 
1520                                         vscrollbar_ctrl.Maximum = owner.Items.Count - owner.MaxDropDownItems;
1521                                         show_scrollbar = vscrollbar_ctrl.Visible = true;
1522                                         
1523                                 }
1524                                 
1525                                 Size = new Size (width, height);
1526                                 textarea_drawable = ClientRectangle;
1527                                 textarea_drawable.Width = width;
1528                                 textarea_drawable.Height = height;                              
1529
1530                                 // Exclude decorations
1531                                 textarea_drawable.X += ThemeEngine.Current.DrawComboListBoxDecorationLeft (owner.DropDownStyle);
1532                                 textarea_drawable.Y += ThemeEngine.Current.DrawComboListBoxDecorationTop (owner.DropDownStyle);
1533                                 textarea_drawable.Width -= ThemeEngine.Current.DrawComboListBoxDecorationRight (owner.DropDownStyle);
1534                                 textarea_drawable.Width -= ThemeEngine.Current.DrawComboListBoxDecorationLeft (owner.DropDownStyle);
1535                                 textarea_drawable.Height -= ThemeEngine.Current.DrawComboListBoxDecorationBottom (owner.DropDownStyle);                         
1536                                 textarea_drawable.Height -= ThemeEngine.Current.DrawComboListBoxDecorationTop (owner.DropDownStyle);
1537                                 
1538                                 if (vscrollbar_ctrl != null && show_scrollbar)
1539                                         textarea_drawable.Width -= vscrollbar_ctrl.Width;
1540
1541                                 last_item = LastVisibleItem ();                         
1542                                 page_size = textarea_drawable.Height / (item_height - 2);                               
1543                         }                       
1544
1545                         private void Draw (Rectangle clip, Graphics dc)
1546                         {       
1547                                 dc.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush
1548                                         (owner.BackColor), clip);                               
1549
1550                                 if (owner.Items.Count > 0) {
1551                                         Rectangle item_rect;
1552                                         DrawItemState state = DrawItemState.None;
1553                                         
1554                                         for (int i = top_item; i <= last_item; i++) {
1555                                                 item_rect = GetItemDisplayRectangle (i, top_item);                                              
1556
1557                                                 if (clip.IntersectsWith (item_rect) == false)
1558                                                         continue;
1559
1560                                                 /* Draw item */
1561                                                 state = DrawItemState.None;
1562
1563                                                 if (i == GetHighLightedIndex () ) {
1564                                                         state |= DrawItemState.Selected;
1565                                                         
1566                                                         if (owner.DropDownStyle == ComboBoxStyle.DropDownList) {
1567                                                                 state |= DrawItemState.Focus;
1568                                                         }                                                       
1569                                                 }
1570                                                         
1571                                                 owner.OnDrawItem (new DrawItemEventArgs (dc, owner.Font, item_rect,
1572                                                         i, state, owner.ForeColor, owner.BackColor));
1573                                         }
1574                                 }                       
1575                                 
1576                                 ThemeEngine.Current.DrawComboListBoxDecorations (dc, owner, ClientRectangle);
1577                         }
1578                         
1579                         public int GetHighLightedIndex ()
1580                         {                                       
1581                                 return owner.Items.IndexOf (highlighted_item);
1582                         }
1583                         
1584                         public object GetHighLightedItem ()
1585                         {                               
1586                                 return highlighted_item;
1587                         }
1588
1589                         private Rectangle GetItemDisplayRectangle (int index, int first_displayble)
1590                         {
1591                                 if (index < 0 || index >= owner.Items.Count)
1592                                         throw new  ArgumentOutOfRangeException ("GetItemRectangle index out of range.");
1593
1594                                 Rectangle item_rect = new Rectangle ();
1595                                 int height = owner.GetItemHeight (index);
1596
1597                                 item_rect.X = ThemeEngine.Current.DrawComboListBoxDecorationRight (owner.DropDownStyle);
1598                                 item_rect.Width = textarea_drawable.Width;
1599                                 item_rect.Y = 2 + ((height - 2) * (index - first_displayble));
1600                                 item_rect.Height = height;
1601                                 return item_rect;
1602                         }
1603
1604                         public void HideWindow ()
1605                         {
1606                                 if (owner.DropDownStyle == ComboBoxStyle.Simple)
1607                                         return;
1608                                         
1609                                 Capture = false;
1610                                 Hide ();
1611                                 highlighted_item = -1;
1612                                 owner.DropDownListBoxFinished ();
1613                         }
1614
1615                         private int IndexFromPointDisplayRectangle (int x, int y)
1616                         {
1617                                 for (int i = top_item; i <= last_item; i++) {
1618                                         if (GetItemDisplayRectangle (i, top_item).Contains (x, y) == true)
1619                                                 return i;
1620                                 }
1621
1622                                 return -1;
1623                         }
1624                         
1625                         protected override bool IsInputKey (Keys keyData)
1626                         {
1627                                 return owner.IsInputKey (keyData);
1628                         }
1629
1630                         private int LastVisibleItem ()
1631                         {
1632                                 Rectangle item_rect;
1633                                 int top_y = textarea_drawable.Y + textarea_drawable.Height;
1634                                 int i = 0;                              
1635                                 
1636                                 for (i = top_item; i < owner.Items.Count; i++) {
1637                                         item_rect = GetItemDisplayRectangle (i, top_item);                              
1638                                         if (item_rect.Y + item_rect.Height > top_y) {
1639                                                 return i;
1640                                         }
1641                                 }
1642                                 return i - 1;
1643                         }
1644                         
1645                         private void NavigateItemVisually (ItemNavigation navigation)
1646                         {
1647                                 int item = -1;
1648                                 
1649                                 switch (navigation) {
1650                                 case ItemNavigation.Next: {
1651                                         if (GetHighLightedIndex () + 1 < owner.Items.Count) {
1652                                                 
1653                                                 if (GetHighLightedIndex () + 1 > last_item) {
1654                                                         top_item++;
1655                                                         vscrollbar_ctrl.Value = top_item;
1656                                                 }
1657                                                 item = GetHighLightedIndex () + 1;
1658                                         }
1659                                         break;
1660                                 }
1661                                 
1662                                 case ItemNavigation.Previous: {
1663                                         if (GetHighLightedIndex () > 0) {                                               
1664                                                 
1665                                                 if (GetHighLightedIndex () - 1 < top_item) {                                                    
1666                                                         top_item--;
1667                                                         vscrollbar_ctrl.Value = top_item;                                                       
1668                                                 }
1669                                                 item = GetHighLightedIndex () - 1;
1670                                         }                                       
1671                                         break;
1672                                 }
1673                                 
1674                                 case ItemNavigation.NextPage: {
1675                                         if (GetHighLightedIndex () + page_size - 1 >= owner.Items.Count) {
1676                                                 top_item = owner.Items.Count - page_size;
1677                                                 vscrollbar_ctrl.Value = top_item;                                               
1678                                                 item = owner.Items.Count - 1;
1679                                         }
1680                                         else {
1681                                                 if (GetHighLightedIndex () + page_size - 1  > last_item) {
1682                                                         top_item = GetHighLightedIndex ();
1683                                                         vscrollbar_ctrl.Value = GetHighLightedIndex ();
1684                                                 }
1685                                         
1686                                                 item = GetHighLightedIndex () + page_size - 1;
1687                                         }                                       
1688                                         break;
1689                                 }
1690                                 
1691                                 case ItemNavigation.PreviousPage: {                                     
1692                                         
1693                                         /* Go to the first item*/
1694                                         if (GetHighLightedIndex () - (page_size - 1) <= 0) {
1695                                                                                                                                                 
1696                                                 top_item = 0;
1697                                                 vscrollbar_ctrl.Value = top_item;
1698                                                 item = 0;                       
1699                                         }
1700                                         else { /* One page back */
1701                                                 if (GetHighLightedIndex () - (page_size - 1)  < top_item) {
1702                                                         top_item = GetHighLightedIndex () - (page_size - 1);
1703                                                         vscrollbar_ctrl.Value = top_item;
1704                                                 }
1705                                         
1706                                                 item = GetHighLightedIndex () - (page_size - 1);
1707                                         }
1708                                         
1709                                         break;
1710                                 }                               
1711                                         
1712                                 default:
1713                                         break;
1714                                 }       
1715                                 
1716                                 if (item != -1) {
1717                                         SetHighLightedItem (owner.Items[item]);
1718                                         
1719                                         owner.OnSelectionChangeCommitted (new EventArgs ());
1720                                         
1721                                         if (owner.DropDownStyle == ComboBoxStyle.Simple) {
1722                                                 owner.SetControlText (owner.GetItemText (owner.Items[item]));
1723                                         }
1724                                 }
1725                         }
1726                         
1727                         private void OnKeyDownPUW (object sender, KeyEventArgs e)                       
1728                         {                               
1729                                 switch (e.KeyCode) {                    
1730                                 case Keys.Up:
1731                                         NavigateItemVisually (ItemNavigation.Previous);
1732                                         break;                          
1733         
1734                                 case Keys.Down:                         
1735                                         NavigateItemVisually (ItemNavigation.Next);
1736                                         break;
1737                                 
1738                                 case Keys.PageUp:
1739                                         NavigateItemVisually (ItemNavigation.PreviousPage);
1740                                         break;                          
1741         
1742                                 case Keys.PageDown:                             
1743                                         NavigateItemVisually (ItemNavigation.NextPage);
1744                                         break;
1745                                 
1746                                 default:
1747                                         break;
1748                                 }
1749                         }
1750                         
1751                         public void SetHighLightedItem (object item)
1752                         {
1753                                 Rectangle invalidate;
1754                                 
1755                                 if (GetHighLightedItem () == item)
1756                                         return;
1757                                 
1758                                 /* Previous item */
1759                                 if (GetHighLightedIndex () != -1) {                                     
1760                                         invalidate = GetItemDisplayRectangle (GetHighLightedIndex (), top_item);
1761                                         if (ClientRectangle.Contains (invalidate))
1762                                                 Invalidate (invalidate);
1763                                 }
1764                                 
1765                                 highlighted_item = item;
1766                                 
1767                                 if (highlighted_item != null) {
1768                                          /* Current item */
1769                                         invalidate = GetItemDisplayRectangle (GetHighLightedIndex (), top_item);
1770                                         if (ClientRectangle.Contains (invalidate))
1771                                                 Invalidate (invalidate);
1772                                 }
1773                                 
1774                         }                       
1775
1776                         public void SetTopItem (int item)
1777                         {
1778                                 top_item = item;
1779                                 UpdateLastVisibleItem ();
1780                                 Refresh ();
1781                         }                       
1782                         
1783                         private void OnMouseDownPUW (object sender, MouseEventArgs e)
1784                         {       
1785                                 Rectangle scrollbar_screenrect;
1786                                 Point mouse_screen, scrollbar_screen;
1787                                 mouse_screen = PointToScreen (new Point (e.X, e.Y));
1788                                         
1789                                 /* Click on an element ? */                             
1790                                 int index = IndexFromPointDisplayRectangle (e.X, e.Y);
1791                                 if (index != -1) {                                      
1792                                         owner.SelectedIndex = index;
1793                                         SetHighLightedItem (owner.Items[index]);
1794                                         owner.OnSelectionChangeCommitted (new EventArgs ());
1795                                         HideWindow ();
1796                                         return;
1797                                 }
1798                                 
1799                                 if (owner.DropDownStyle == ComboBoxStyle.Simple)
1800                                         return;                                 
1801                                                                 
1802                                 /* Reroute event to scrollbar */                                
1803                                 if (vscrollbar_ctrl != null && vscrollbar_ctrl.Visible == true) {
1804                                         scrollbar_screenrect = vscrollbar_ctrl.ClientRectangle;
1805                                         scrollbar_screen = PointToScreen (vscrollbar_ctrl.Location);
1806                                         scrollbar_screenrect.X = scrollbar_screen.X;
1807                                         scrollbar_screenrect.Y = scrollbar_screen.Y;
1808                                         
1809                                         if (scrollbar_screenrect.Contains (mouse_screen)){                                      
1810                                                 Point pnt_client = vscrollbar_ctrl.PointToClient (mouse_screen);                                        
1811                                                 vscrollbar_ctrl.FireMouseDown (new MouseEventArgs (e.Button, e.Clicks,
1812                                                         pnt_client.X, pnt_client.Y, e.Delta));                                          
1813                                         } else  { /* Click in a non-client area*/
1814                                                 HideWindow ();                          
1815                                         }                               
1816                                 } else  { /* Click in a non-client area*/
1817                                         HideWindow ();
1818                                 }
1819                         }
1820
1821                         private void OnMouseMovePUW (object sender, MouseEventArgs e)
1822                         {                       
1823                                 if (owner.DropDownStyle == ComboBoxStyle.Simple)
1824                                         return;
1825                                                 
1826                                 int index = IndexFromPointDisplayRectangle (e.X, e.Y);
1827
1828                                 if (index != -1) {
1829                                         SetHighLightedItem (owner.Items[index]);
1830                                         return;
1831                                 }
1832                                 
1833                                 if (owner.DropDownStyle == ComboBoxStyle.Simple)
1834                                         return;         
1835                                 
1836                                 /* Reroute event to scrollbar */
1837                                 if (vscrollbar_ctrl != null && vscrollbar_ctrl.Visible == true) {       
1838                                         Rectangle scrollbar_screenrect;
1839                                         Point mouse_screen, scrollbar_screen;
1840                                         mouse_screen = PointToScreen (new Point (e.X, e.Y));
1841                                         
1842                                         scrollbar_screenrect = vscrollbar_ctrl.ClientRectangle;
1843                                         scrollbar_screen = PointToScreen (vscrollbar_ctrl.Location);
1844                                         scrollbar_screenrect.X = scrollbar_screen.X;
1845                                         scrollbar_screenrect.Y = scrollbar_screen.Y;
1846                                         
1847                                         if (scrollbar_screenrect.Contains (mouse_screen)){                                      
1848                                                 Point pnt_client = vscrollbar_ctrl.PointToClient (mouse_screen);
1849                                                 
1850                                                 vscrollbar_ctrl.FireMouseMove (new MouseEventArgs (e.Button, e.Clicks,
1851                                                         pnt_client.X, pnt_client.Y, e.Delta));
1852                                         }
1853                                 }                               
1854                         }
1855                         
1856                         private void OnMouseUpPUW (object sender, MouseEventArgs e)
1857                         {
1858                                 if (owner.DropDownStyle == ComboBoxStyle.Simple)
1859                                         return;                                 
1860                                         
1861                                 /* Reroute event to scrollbar */        
1862                                 Rectangle scrollbar_screenrect;
1863                                 Point mouse_screen, scrollbar_screen;
1864                                 mouse_screen = PointToScreen (new Point (e.X, e.Y));
1865                                 
1866                                 if (vscrollbar_ctrl != null && vscrollbar_ctrl.Visible == true) {       
1867                                         scrollbar_screenrect = vscrollbar_ctrl.ClientRectangle;
1868                                         scrollbar_screen = PointToScreen (vscrollbar_ctrl.Location);
1869                                         scrollbar_screenrect.X = scrollbar_screen.X;
1870                                         scrollbar_screenrect.Y = scrollbar_screen.Y;
1871                                         
1872                                         if (scrollbar_screenrect.Contains (mouse_screen)){                                      
1873                                                 Point pnt_client = vscrollbar_ctrl.PointToClient (mouse_screen);                                        
1874                                                 
1875                                                 vscrollbar_ctrl.FireMouseUp (new MouseEventArgs (e.Button, e.Clicks,
1876                                                         pnt_client.X, pnt_client.Y, e.Delta));
1877                                         }
1878                                 }
1879                         }
1880
1881                         private void OnPaintPUW (Object o, PaintEventArgs pevent)
1882                         {
1883                                 Draw (pevent.ClipRectangle,pevent.Graphics);
1884                         }
1885
1886                         public bool ShowWindow ()
1887                         {
1888                                 if (owner.DropDownStyle != ComboBoxStyle.Simple && owner.Items.Count == 0)
1889                                         return false;
1890                                         
1891                                 SetTopItem (0);
1892                                 SetHighLightedItem (owner.SelectedItem);
1893                                 
1894                                 CalcListBoxArea ();                             
1895                                 Show ();
1896                                 
1897                                 if (owner.DropDownStyle != ComboBoxStyle.Simple) {
1898                                         Capture = true;
1899                                 }
1900                                 
1901                                 Refresh ();
1902                                 
1903                                 if (owner.DropDown != null) {
1904                                         owner.DropDown (owner, EventArgs.Empty);
1905                                 }
1906                                 
1907                                 return true;
1908                         }
1909                         
1910                         public void UpdateLastVisibleItem ()
1911                         {
1912                                 last_item = LastVisibleItem ();
1913                         }
1914
1915                         // Value Changed
1916                         private void VerticalScrollEvent (object sender, EventArgs e)
1917                         {                               
1918                                 top_item =  vscrollbar_ctrl.Value;
1919                                 UpdateLastVisibleItem ();
1920                                 Refresh ();
1921                         }                       
1922
1923                         #endregion Private Methods
1924                 }\r
1925         }
1926 }
1927