1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 // Copyright (c) 2004 Novell, Inc.
23 // Jordi Mas i Hernandez, jordi@ximian.com
31 using System.Collections;
32 using System.ComponentModel;
33 using System.Reflection;
35 namespace System.Windows.Forms
38 public class ComboBox : ListControl
40 private DrawMode draw_mode;
41 private ComboBoxStyle dropdown_style;
42 private int dropdown_width;
43 private int max_length;
44 private int preferred_height;
45 private int selected_index;
46 private object selected_item;
47 internal ObjectCollection items;
48 private bool suspend_ctrlupdate;
49 private int maxdrop_items;
50 private bool integral_height;
52 internal ComboBoxInfo combobox_info;
53 private readonly int def_button_width = 16;
55 private ListBoxPopUp listbox_popup;
56 private StringFormat string_format;
58 internal class ComboBoxInfo
60 internal int item_height; /* Item's height */
61 internal Rectangle textarea_rect; /* Rectangle of the editable text area - decorations */
62 internal Rectangle button_rect;
63 internal bool show_button; /* Is the DropDown button shown? */
64 internal Rectangle client_rect; /* Client Rectangle. Usually = ClientRectangle except when IntegralHeight has been applied*/
65 internal ButtonState button_status; /* Drop button status */
66 internal Size listbox_size;
68 public ComboBoxInfo ()
70 button_status = ButtonState.Normal;
76 internal class ComboBoxItem
80 public ComboBoxItem (int index)
89 BackColor = ThemeEngine.Current.ColorWindow;
90 draw_mode = DrawMode.Normal;
91 selected_index = -1;
\r
94 combobox_info = new ComboBoxInfo ();
95 combobox_info.item_height = FontHeight;
96 suspend_ctrlupdate = false;
99 items = new ObjectCollection (this);
100 string_format = new StringFormat ();
101 CBoxInfo.show_button = true;
102 listbox_popup = null;
105 MouseDown += new MouseEventHandler (OnMouseDownCB);
106 MouseUp += new MouseEventHandler (OnMouseUpCB);
108 Console.WriteLine ("ComboBox is still an on going effort. Only ComboBoxStyle.DropDownList is implemented");
112 public new event EventHandler BackgroundImageChanged;
113 public event DrawItemEventHandler DrawItem;
114 public event EventHandler DropDown;
115 public event EventHandler DropDownStyleChanged;
116 public event MeasureItemEventHandler MeasureItem;
117 public new event PaintEventHandler Paint;
118 public event EventHandler SelectedIndexChanged;
119 public event EventHandler SelectionChangeCommitted;
122 #region Public Properties
123 public override Color BackColor {
124 get { return base.BackColor; }
126 if (base.BackColor == value)
129 base.BackColor = value;
134 public override Image BackgroundImage {
135 get { return base.BackgroundImage; }
137 if (base.BackgroundImage == value)
140 base.BackgroundImage = value;
142 if (BackgroundImageChanged != null)
143 BackgroundImageChanged (this, EventArgs.Empty);
149 protected override CreateParams CreateParams {
150 get { return base.CreateParams;}
153 protected override Size DefaultSize {
154 get { return new Size (121, PreferredHeight); }
157 public DrawMode DrawMode {
158 get { return draw_mode; }
161 if (!Enum.IsDefined (typeof (DrawMode), value))
162 throw new InvalidEnumArgumentException (string.Format("Enum argument value '{0}' is not valid for DrawMode", value));
164 if (draw_mode == value)
172 public ComboBoxStyle DropDownStyle {
173 get { return dropdown_style; }
176 if (!Enum.IsDefined (typeof (ComboBoxStyle), value))
177 throw new InvalidEnumArgumentException (string.Format("Enum argument value '{0}' is not valid for ComboBoxStyle", value));
179 if (dropdown_style == value)
182 dropdown_style = value;
187 public int DropDownWidth {
188 get { return dropdown_width; }
191 if (dropdown_width == value)
194 dropdown_width = value;
199 public override bool Focused {
200 get { return base.Focused; }
203 public override Color ForeColor {
204 get { return base.ForeColor; }
207 if (base.ForeColor == value)
210 base.ForeColor = value;
215 public bool IntegralHeight {
216 get { return integral_height; }
218 if (integral_height == value)
221 integral_height = value;
225 public virtual int ItemHeight {
226 get { return combobox_info.item_height; }
229 throw new ArgumentOutOfRangeException ("The item height value is less than zero");
231 combobox_info.item_height = value;
237 public ComboBox.ObjectCollection Items {
238 get { return items; }
241 public int MaxDropDownItems {
242 get { return maxdrop_items; }
244 if (maxdrop_items == value)
247 maxdrop_items = value;
251 public int MaxLength {
252 get { return max_length; }
254 if (max_length == value)
261 public int PreferredHeight {
262 get { return preferred_height; }
265 public override int SelectedIndex {
266 get { return selected_index; }
268 if (value < -2 || value >= Items.Count)
269 throw new ArgumentOutOfRangeException ("Index of out range");
271 if (selected_index == value)
274 selected_index = value;
275 OnSelectedIndexChanged (new EventArgs ());
280 public object SelectedItem {
282 if (selected_index !=-1 && Items.Count > 0)
283 return Items[selected_index];
288 if (selected_item == value)
291 int index = Items.IndexOf (value);
296 selected_index = index;
297 OnSelectedItemChanged (new EventArgs ());
302 public string SelectedText {
303 get {throw new NotImplementedException ();}
307 public int SelectionLength {
308 get {throw new NotImplementedException ();}
312 public int SelectionStart {
313 get {throw new NotImplementedException (); }
318 get { return sorted; }
328 public override string Text {
329 get { return ""; /*throw new NotImplementedException ();*/ }
333 #endregion Public Properties
335 #region Private Properties
336 internal ComboBoxInfo CBoxInfo {
337 get { return combobox_info; }
340 #endregion Private Properties
342 #region Public Methods
343 protected virtual void AddItemsCore (object[] value)
348 public void BeginUpdate ()
350 suspend_ctrlupdate = true;
353 protected virtual void Dispose (bool disposing)
358 public void EndUpdate ()
360 suspend_ctrlupdate = false;
364 public int FindString (string s)
366 return FindString (s, 0);
369 public int FindString (string s, int startIndex)
371 for (int i = startIndex; i < Items.Count; i++) {
372 if ((Items[i].ToString ()).StartsWith (s))
379 public int FindStringExact (string s)
381 return FindStringExact (s, 0);
384 public int FindStringExact (string s, int startIndex)
386 for (int i = startIndex; i < Items.Count; i++) {
387 if ((Items[i].ToString ()).Equals (s))
394 public int GetItemHeight (int index)
396 throw new NotImplementedException ();
399 protected override bool IsInputKey (Keys keyData)
404 protected override void OnBackColorChanged (EventArgs e)
406 base.OnBackColorChanged (e);
409 protected override void OnDataSourceChanged (EventArgs e)
411 base.OnDataSourceChanged (e);
414 protected override void OnDisplayMemberChanged (EventArgs e)
416 base.OnDisplayMemberChanged (e);
419 protected virtual void OnDrawItem (DrawItemEventArgs e)
421 if (DrawItem != null && (DrawMode == DrawMode.OwnerDrawFixed || DrawMode == DrawMode.OwnerDrawVariable))
424 if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) {
426 e.Graphics.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush
427 (ThemeEngine.Current.ColorHilight), e.Bounds);
429 e.Graphics.DrawString (Items[e.Index].ToString (), e.Font,
430 ThemeEngine.Current.ResPool.GetSolidBrush (ThemeEngine.Current.ColorHilightText),
431 e.Bounds, string_format);
433 // It seems to be a bug in CPDrawFocusRectangle
434 //ThemeEngine.Current.CPDrawFocusRectangle (e.Graphics, e.Bounds,
435 // ThemeEngine.Current.ColorHilightText, BackColor);
438 e.Graphics.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush
439 (e.BackColor), e.Bounds);
441 e.Graphics.DrawString (Items[e.Index].ToString (), e.Font,
442 ThemeEngine.Current.ResPool.GetSolidBrush (e.ForeColor),
443 e.Bounds, string_format);
447 protected virtual void OnDropDownStyleChanged (EventArgs e)
452 protected override void OnFontChanged (EventArgs e)
454 base.OnFontChanged (e);
457 protected override void OnForeColorChanged (EventArgs e)
459 base.OnForeColorChanged (e);
462 protected override void OnHandleCreated (EventArgs e)
464 base.OnHandleCreated (e);
468 protected override void OnHandleDestroyed (EventArgs e)
470 base.OnHandleDestroyed (e);
473 protected override void OnKeyPress (KeyPressEventArgs e)
478 protected virtual void OnMeasureItem (MeasureItemEventArgs e)
483 protected override void OnParentBackColorChanged (EventArgs e)
485 base.OnParentBackColorChanged (e);
488 protected override void OnResize (EventArgs e)
494 protected override void OnSelectedIndexChanged (EventArgs e)
496 base.OnSelectedIndexChanged (e);
498 if (SelectedIndexChanged != null)
499 SelectedIndexChanged (this, e);
502 protected virtual void OnSelectedItemChanged (EventArgs e)
507 protected override void OnSelectedValueChanged (EventArgs e)
509 base.OnSelectedValueChanged (e);
512 protected virtual void OnSelectionChangeCommitted (EventArgs e)
517 protected override void RefreshItem (int index)
523 protected virtual void Select (int start, int lenght)
528 public void SelectAll ()
533 protected override void SetBoundsCore (int x, int y, int width, int height, BoundsSpecified specified)
535 base.SetBoundsCore (x, y, width, height, specified);
538 protected override void SetItemCore (int index, object value)
540 if (index < 0 || index >= Items.Count)
543 Items[index] = value;
546 protected override void SetItemsCore (IList value)
551 public override string ToString ()
553 throw new NotImplementedException ();
556 protected override void WndProc (ref Message m)
559 switch ((Msg) m.Msg) {
562 PaintEventArgs paint_event;
563 paint_event = XplatUI.PaintEventStart (Handle);
564 OnPaintCB (paint_event);
565 XplatUI.PaintEventEnd (Handle);
569 case Msg.WM_ERASEBKGND:
570 m.Result = (IntPtr) 1;
577 base.WndProc (ref m);
581 #endregion Public Methods
583 #region Private Methods
585 internal void ButtonReleased ()
587 combobox_info.button_status = ButtonState.Normal;
588 Invalidate (combobox_info.button_rect);
591 // Calcs the text area size
592 internal void CalcTextArea ()
594 combobox_info.textarea_rect = ClientRectangle;
595 combobox_info.textarea_rect.Y += ThemeEngine.Current.DrawComboBoxDecorationTop ();
596 combobox_info.textarea_rect.X += ThemeEngine.Current.DrawComboBoxDecorationLeft ();
597 combobox_info.textarea_rect.Height -= ThemeEngine.Current.DrawComboBoxDecorationBottom ();
598 combobox_info.textarea_rect.Width -= ThemeEngine.Current.DrawComboBoxDecorationRight ();
600 if (CBoxInfo.show_button) {
601 combobox_info.textarea_rect.Width -= def_button_width;
603 combobox_info.button_rect = new Rectangle (combobox_info.textarea_rect.X + combobox_info.textarea_rect.Width,
604 combobox_info.textarea_rect.Y, def_button_width, combobox_info.textarea_rect.Height);
608 private void CreateListBoxPopUp ()
610 listbox_popup = new ListBoxPopUp (this);
611 listbox_popup.Location = PointToScreen (new Point (ClientRectangle.X, ClientRectangle.Y + ClientRectangle.Height));
612 listbox_popup.Size = combobox_info.listbox_size;
615 internal void Draw (Rectangle clip)
618 // No edit control, we paint the edit are ourselfs
619 if (dropdown_style == ComboBoxStyle.DropDownList) {
621 if (selected_index != -1) {
623 OnDrawItem (new DrawItemEventArgs (DeviceContext, Font, combobox_info.textarea_rect,
624 selected_index, DrawItemState.Selected,
625 ForeColor, BackColor));
628 DeviceContext.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (BackColor),
632 if (CBoxInfo.show_button) {
633 DeviceContext.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (ThemeEngine.Current.ColorButtonFace),
634 combobox_info.button_rect);
636 ThemeEngine.Current.CPDrawComboButton (DeviceContext,
637 combobox_info.button_rect, combobox_info.button_status);
640 ThemeEngine.Current.DrawComboBoxDecorations (DeviceContext, this);
643 internal virtual void OnMouseDownCB (object sender, MouseEventArgs e)
646 if (clicked == false && combobox_info.button_rect.Contains (e.X, e.Y)) {
650 if (combobox_info.button_status == ButtonState.Normal) {
651 combobox_info.button_status = ButtonState.Pushed;
654 if (combobox_info.button_status == ButtonState.Pushed) {
655 combobox_info.button_status = ButtonState.Normal;
659 if (combobox_info.button_status == ButtonState.Pushed) {
660 if (listbox_popup == null)
661 CreateListBoxPopUp ();
663 listbox_popup.ShowWindow ();
666 Invalidate (combobox_info.button_rect);
670 internal virtual void OnMouseUpCB (object sender, MouseEventArgs e)
673 if (clicked == true && combobox_info.button_rect.Contains (e.X, e.Y)) {
680 private void OnPaintCB (PaintEventArgs pevent)
682 if (Width <= 0 || Height <= 0 || Visible == false || suspend_ctrlupdate == true)
685 /* Copies memory drawing buffer to screen*/
686 Draw (ClientRectangle);
687 pevent.Graphics.DrawImage (ImageBuffer, ClientRectangle, ClientRectangle, GraphicsUnit.Pixel);
690 Paint (this, pevent);
693 #endregion Private Methods
697 ComboBox.ObjectCollection
699 public class ObjectCollection : IList, ICollection, IEnumerable
702 private ComboBox owner;
703 internal ArrayList object_items = new ArrayList ();
704 internal ArrayList listbox_items = new ArrayList ();
706 public ObjectCollection (ComboBox owner)
712 #region Public Properties
713 public virtual int Count {
714 get { return object_items.Count; }
717 public virtual bool IsReadOnly {
718 get { return false; }
721 public virtual object this [int index] {
723 if (index < 0 || index >= Count)
724 throw new ArgumentOutOfRangeException ("Index of out range");
726 return object_items[index];
729 if (index < 0 || index >= Count)
730 throw new ArgumentOutOfRangeException ("Index of out range");
732 object_items[index] = value;
736 bool ICollection.IsSynchronized {
737 get { return false; }
740 object ICollection.SyncRoot {
744 bool IList.IsFixedSize {
745 get { return false; }
748 #endregion Public Properties
750 #region Public Methods
751 public int Add (object item)
755 idx = AddItem (item);
759 public void AddRange (object[] items)
761 foreach (object mi in items)
766 public virtual void Clear ()
768 object_items.Clear ();
769 listbox_items.Clear ();
772 public virtual bool Contains (object obj)
774 return object_items.Contains (obj);
777 public void CopyTo (object[] dest, int arrayIndex)
779 object_items.CopyTo (dest, arrayIndex);
782 void ICollection.CopyTo (Array dest, int index)
784 object_items.CopyTo (dest, index);
787 public virtual IEnumerator GetEnumerator ()
789 return object_items.GetEnumerator ();
792 int IList.Add (object item)
797 public virtual int IndexOf (object value)
799 return object_items.IndexOf (value);
802 public virtual void Insert (int index, object item)
804 throw new NotImplementedException ();
807 public virtual void Remove (object value)
809 RemoveAt (IndexOf (value));
813 public virtual void RemoveAt (int index)
815 if (index < 0 || index >= Count)
816 throw new ArgumentOutOfRangeException ("Index of out range");
818 object_items.RemoveAt (index);
819 listbox_items.RemoveAt (index);
820 //owner.UpdateItemInfo (false, -1, -1);
822 #endregion Public Methods
824 #region Private Methods
825 private int AddItem (object item)
827 int cnt = object_items.Count;
828 object_items.Add (item);
829 listbox_items.Add (new ComboBox.ComboBoxItem (cnt));
833 internal ComboBox.ComboBoxItem GetComboBoxItem (int index)
835 if (index < 0 || index >= Count)
836 throw new ArgumentOutOfRangeException ("Index of out range");
838 return (ComboBox.ComboBoxItem) listbox_items[index];
841 internal void SetComboBoxItem (ComboBox.ComboBoxItem item, int index)
843 if (index < 0 || index >= Count)
844 throw new ArgumentOutOfRangeException ("Index of out range");
846 listbox_items[index] = item;
849 #endregion Private Methods
855 internal class ListBoxPopUp : Control
857 private ComboBox owner;
858 private bool need_vscrollbar;
859 private VScrollBar vscrollbar_ctrl;
860 private int top_item; /* First item that we show the in the current page */
861 private int last_item; /* Last visible item */
862 private int highlighted_item; /* Item that is currently selected */
863 private Rectangle textarea_rect; /* Rectangle of the drawable text area */
866 public ListBoxPopUp (ComboBox owner): base ()
869 need_vscrollbar = false;
872 highlighted_item = -1;
874 MouseDown += new MouseEventHandler (OnMouseDownPUW);
875 MouseMove += new MouseEventHandler (OnMouseMovePUW);
876 MouseUp += new MouseEventHandler (OnMouseUpPUW);
877 Paint += new PaintEventHandler (OnPaintPUW);
878 SetStyle (ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true);
879 SetStyle (ControlStyles.ResizeRedraw | ControlStyles.Opaque, true);
881 /* Vertical scrollbar */
882 vscrollbar_ctrl = new VScrollBar ();
883 vscrollbar_ctrl.Minimum = 0;
884 vscrollbar_ctrl.SmallChange = 1;
885 vscrollbar_ctrl.LargeChange = 1;
886 vscrollbar_ctrl.Maximum = 0;
887 vscrollbar_ctrl.ValueChanged += new EventHandler (VerticalScrollEvent);
888 vscrollbar_ctrl.Visible = false;
891 protected override CreateParams CreateParams
894 CreateParams cp = base.CreateParams;
895 cp.Style = unchecked ((int)(WindowStyles.WS_POPUP | WindowStyles.WS_VISIBLE | WindowStyles.WS_CLIPSIBLINGS | WindowStyles.WS_CLIPCHILDREN));
896 cp.ExStyle |= (int)WindowStyles.WS_EX_TOOLWINDOW;
902 #region Private Methods
904 protected override void CreateHandle ()
906 base.CreateHandle ();
907 Controls.Add (vscrollbar_ctrl);
910 // Calcs the listbox area
911 internal void CalcListBoxArea ()
915 width = owner.ClientRectangle.Width;
917 if (owner.Items.Count <= owner.MaxDropDownItems) {
918 height = owner.ItemHeight * owner.Items.Count;
919 need_vscrollbar = false;
922 height = owner.ItemHeight * owner.MaxDropDownItems;
923 need_vscrollbar = true;
925 vscrollbar_ctrl.Height = height - 1;
926 vscrollbar_ctrl.Location = new Point (width - vscrollbar_ctrl.Width - 1, 1);
928 vscrollbar_ctrl.Maximum = owner.Items.Count - owner.MaxDropDownItems;
931 if (vscrollbar_ctrl.Visible != need_vscrollbar)
932 vscrollbar_ctrl.Visible = need_vscrollbar;
934 Size = new Size (width, height);
935 textarea_rect = ClientRectangle;
937 // Exclude decorations
938 textarea_rect.X += 1;
939 textarea_rect.Y += 1;
940 textarea_rect.Width -= 1;
941 textarea_rect.Height -= 1;
944 textarea_rect.Width -= vscrollbar_ctrl.Width;
946 last_item = LastVisibleItem ();
949 private void Draw (Rectangle clip)
951 Rectangle cl = ClientRectangle;
953 if (owner.Items.Count > 0) {
955 DrawItemState state = DrawItemState.None;
957 for (int i = top_item; i < last_item; i++) {
958 item_rect = GetItemDisplayRectangle (i, top_item);
960 if (clip.IntersectsWith (item_rect) == false)
964 state = DrawItemState.None;
966 if (i == highlighted_item)
967 state |= DrawItemState.Selected;
969 owner.OnDrawItem (new DrawItemEventArgs (DeviceContext, owner.Font, item_rect,
970 i, state, owner.ForeColor, owner.BackColor));
974 //DeviceContext.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush
975 // (owner.BackColor), ClientRectangle);
977 DeviceContext.DrawRectangle (ThemeEngine.Current.ResPool.GetPen (ThemeEngine.Current.ColorWindowFrame),
978 cl.X, cl.Y, cl.Width - 1, cl.Height - 1);
981 private Rectangle GetItemDisplayRectangle (int index, int first_displayble)
983 if (index < 0 || index >= owner.Items.Count)
984 throw new ArgumentOutOfRangeException ("GetItemRectangle index out of range.");
986 Rectangle item_rect = new Rectangle ();
989 item_rect.Y = owner.ItemHeight * (index - first_displayble);
990 item_rect.Height = owner.ItemHeight;
991 item_rect.Width = textarea_rect.Width;
996 public void HideWindow ()
998 owner.ButtonReleased ();
1002 private int IndexFromPointDisplayRectangle (int x, int y)
1004 for (int i = top_item; i < last_item; i++) {
1005 if (GetItemDisplayRectangle (i, top_item).Contains (x, y) == true)
1012 private int LastVisibleItem ()
1014 Rectangle item_rect;
1015 int top_y = textarea_rect.Y + textarea_rect.Height;
1018 for (i = top_item; i < owner.Items.Count; i++) {
1019 item_rect = GetItemDisplayRectangle (i, top_item);
1020 if (item_rect.Y > top_y)
1026 private void OnMouseDownPUW (object sender, MouseEventArgs e)
1028 /* Click outside the client area destroys the popup */
1029 if (ClientRectangle.Contains (e.X, e.Y) == false) {
1034 /* Click on an element */
1035 int index = IndexFromPointDisplayRectangle (e.X, e.Y);
1036 if (index == -1) return;
1038 owner.SelectedIndex = index;
1042 private void OnMouseUpPUW (object sender, MouseEventArgs e)
1047 private void OnMouseMovePUW (object sender, MouseEventArgs e)
1049 Rectangle invalidate;
1050 int index = IndexFromPointDisplayRectangle (e.X, e.Y);
1052 if (index == -1) return;
1055 if (highlighted_item != -1) {
1056 invalidate = GetItemDisplayRectangle (highlighted_item, top_item);
1057 if (ClientRectangle.Contains (invalidate))
1058 Invalidate (invalidate);
1061 highlighted_item = index;
1064 invalidate = GetItemDisplayRectangle (highlighted_item, top_item);
1065 if (ClientRectangle.Contains (invalidate))
1066 Invalidate (invalidate);
1069 private void OnPaintPUW (Object o, PaintEventArgs pevent)
1071 if (Width <= 0 || Height <= 0 || Visible == false)
1074 Draw (pevent.ClipRectangle);
1075 pevent.Graphics.DrawImage (ImageBuffer, pevent.ClipRectangle, pevent.ClipRectangle, GraphicsUnit.Pixel);
1078 public void ShowWindow ()
1086 private void VerticalScrollEvent (object sender, EventArgs e)
1088 top_item = vscrollbar_ctrl.Value;
1089 last_item = LastVisibleItem ();
1093 #endregion Private Methods