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-2005 Novell, Inc.
23 // Jordi Mas i Hernandez, jordi@ximian.com
26 // - Horizontal item scroll
27 // - Performance testing
35 using System.Collections;
36 using System.ComponentModel;
37 using System.ComponentModel.Design;
38 using System.ComponentModel.Design.Serialization;
39 using System.Reflection;
40 using System.Runtime.InteropServices;
42 namespace System.Windows.Forms
44 [DefaultProperty("Items")]
45 [DefaultEvent("SelectedIndexChanged")]
46 [Designer ("System.Windows.Forms.Design.ListBoxDesigner, " + Consts.AssemblySystem_Design, (string)null)]
47 public class ListBox : ListControl
49 public const int DefaultItemHeight = 13;
50 public const int NoMatches = -1;
52 internal class ListBoxInfo
54 internal int item_height; /* Item's height */
55 internal int top_item; /* First item that we show the in the current page */
56 internal int last_item; /* Last visible item */
57 internal int page_size; /* Number of listbox items per page. In MultiColumn listbox indicates items per column */
58 internal Rectangle textdrawing_rect; /* Displayable Client Rectangle minus the scrollbars and with IntegralHeight calculated*/
59 internal bool show_verticalsb; /* Is Vertical scrollbar show it? */
60 internal bool show_horizontalsb; /* Is Horizontal scrollbar show it? */
61 internal Rectangle client_rect; /* Client Rectangle. Usually = ClientRectangle except when IntegralHeight has been applied*/
62 internal int max_itemwidth; /* Maxium item width within the listbox */
71 show_verticalsb = false;
72 show_horizontalsb = false;
76 internal class ListBoxItem
79 internal bool Selected;
80 internal int ItemHeight; /* Only used for OwnerDrawVariable */
81 internal CheckState State;
83 public ListBoxItem (int index)
88 State = CheckState.Unchecked;
91 public void CopyState (ListBoxItem src)
93 Selected = src.Selected;
94 ItemHeight = src.ItemHeight;
99 internal enum ItemNavigation
111 internal enum UpdateOperation
118 private BorderStyle border_style;
119 private int column_width;
120 private DrawMode draw_mode;
121 private int horizontal_extent;
122 private bool horizontal_scrollbar;
123 private bool integral_height;
124 private bool multicolumn;
125 private bool scroll_always_visible;
126 private int selected_index;
127 private SelectedIndexCollection selected_indices;
128 private SelectedObjectCollection selected_items;
129 private SelectionMode selection_mode;
131 private bool use_tabstops;
132 private int preferred_height;
133 private int top_index;
134 private int column_width_internal;
135 private VScrollBar vscrollbar_ctrl;
136 private HScrollBar hscrollbar_ctrl;
137 private bool suspend_ctrlupdate;
138 private bool ctrl_pressed;
139 private bool shift_pressed;
140 private bool has_focus;
142 internal int focused_item;
143 internal ListBoxInfo listbox_info;
144 internal ObjectCollection items;
148 border_style = BorderStyle.Fixed3D;
\r
149 draw_mode = DrawMode.Normal;
\r
150 horizontal_extent = 0;
\r
151 horizontal_scrollbar = false;
\r
152 integral_height = true;
\r
153 multicolumn = false;
\r
154 preferred_height = 7;
\r
155 scroll_always_visible = false;
\r
158 selection_mode = SelectionMode.One;
\r
162 BackColor = ThemeEngine.Current.ColorWindow;
164 suspend_ctrlupdate = false;
165 ctrl_pressed = false;
166 shift_pressed = false;
169 items = new ObjectCollection (this);
170 selected_indices = new SelectedIndexCollection (this);
171 selected_items = new SelectedObjectCollection (this);
172 listbox_info = new ListBoxInfo ();
173 listbox_info.item_height = FontHeight;
175 /* Vertical scrollbar */
176 vscrollbar_ctrl = new VScrollBar ();
177 vscrollbar_ctrl.Minimum = 0;
178 vscrollbar_ctrl.SmallChange = 1;
179 vscrollbar_ctrl.LargeChange = 1;
180 vscrollbar_ctrl.Maximum = 0;
181 vscrollbar_ctrl.ValueChanged += new EventHandler (VerticalScrollEvent);
182 vscrollbar_ctrl.Visible = false;
184 /* Horizontal scrollbar */
185 hscrollbar_ctrl = new HScrollBar ();
186 hscrollbar_ctrl.Minimum = 0;
187 hscrollbar_ctrl.SmallChange = 1;
188 hscrollbar_ctrl.LargeChange = 1;
189 hscrollbar_ctrl.Maximum = 0;
190 hscrollbar_ctrl.Visible = false;
191 hscrollbar_ctrl.ValueChanged += new EventHandler (HorizontalScrollEvent);
194 MouseDown += new MouseEventHandler (OnMouseDownLB);
195 KeyDown += new KeyEventHandler (OnKeyDownLB);
196 KeyUp += new KeyEventHandler (OnKeyUpLB);
197 GotFocus += new EventHandler (OnGotFocus);
198 LostFocus += new EventHandler (OnLostFocus);
200 SetStyle (ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true);
205 [EditorBrowsable (EditorBrowsableState.Never)]
206 public new event EventHandler BackgroundImageChanged;
209 [EditorBrowsable (EditorBrowsableState.Advanced)]
210 public new event EventHandler Click;
212 public event DrawItemEventHandler DrawItem;
213 public event MeasureItemEventHandler MeasureItem;
216 [EditorBrowsable (EditorBrowsableState.Never)]
217 public new event PaintEventHandler Paint;
219 public event EventHandler SelectedIndexChanged;
222 [EditorBrowsable (EditorBrowsableState.Advanced)]
223 public new event EventHandler TextChanged;
226 #region Public Properties
227 public override Color BackColor {
228 get { return base.BackColor; }
230 if (base.BackColor == value)
233 base.BackColor = value;
234 base.Refresh (); // Careful. Calling the base method is not the same that calling
235 } // the overriden one that refresh also all the items
239 [EditorBrowsable (EditorBrowsableState.Never)]
240 public override Image BackgroundImage {
241 get { return base.BackgroundImage; }
243 if (base.BackgroundImage == value)
246 base.BackgroundImage = value;
248 if (BackgroundImageChanged != null)
249 BackgroundImageChanged (this, EventArgs.Empty);
255 [DefaultValue (BorderStyle.Fixed3D)]
257 public BorderStyle BorderStyle {
258 get { return border_style; }
261 if (!Enum.IsDefined (typeof (BorderStyle), value))
262 throw new InvalidEnumArgumentException (string.Format("Enum argument value '{0}' is not valid for BorderStyle", value));
264 if (border_style == value)
267 border_style = value;
274 public int ColumnWidth {
275 get { return column_width; }
277 if (column_width < 0)
278 throw new ArgumentException ("A value less than zero is assigned to the property.");
280 column_width = value;
283 ColumnWidthInternal = 120;
285 ColumnWidthInternal = value;
291 protected override CreateParams CreateParams {
292 get { return base.CreateParams;}
295 protected override Size DefaultSize {
296 get { return new Size (120, 96); }
299 [RefreshProperties(RefreshProperties.Repaint)]
300 [DefaultValue (DrawMode.Normal)]
301 public virtual DrawMode DrawMode {
302 get { return draw_mode; }
305 if (!Enum.IsDefined (typeof (DrawMode), value))
306 throw new InvalidEnumArgumentException (string.Format("Enum argument value '{0}' is not valid for DrawMode", value));
308 if (value == DrawMode.OwnerDrawVariable && multicolumn == true)
309 throw new InvalidEnumArgumentException ("Cannot have variable height and multicolumn");
311 if (draw_mode == value)
319 public override Color ForeColor {
320 get { return base.ForeColor; }
323 if (base.ForeColor == value)
326 base.ForeColor = value;
333 public int HorizontalExtent {
334 get { return horizontal_extent; }
336 if (horizontal_extent == value)
339 horizontal_extent = value;
344 [DefaultValue (false)]
346 public bool HorizontalScrollbar {
347 get { return horizontal_scrollbar; }
349 if (horizontal_scrollbar == value)
352 horizontal_scrollbar = value;
353 UpdateShowHorizontalScrollBar ();
358 [DefaultValue (true)]
360 [RefreshProperties(RefreshProperties.Repaint)]
361 public bool IntegralHeight {
362 get { return integral_height; }
364 if (integral_height == value)
367 integral_height = value;
374 [RefreshProperties(RefreshProperties.Repaint)]
375 public virtual int ItemHeight {
376 get { return listbox_info.item_height; }
379 throw new ArgumentOutOfRangeException ("The ItemHeight property was set beyond 255 pixels");
381 listbox_info.item_height = value;
386 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
388 [Editor ("System.Windows.Forms.Design.ListControlStringCollectionEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
389 public ObjectCollection Items {
390 get { return items; }
393 [DefaultValue (false)]
394 public bool MultiColumn {
395 get { return multicolumn; }
397 if (multicolumn == value)
400 if (value == true && DrawMode == DrawMode.OwnerDrawVariable)
401 throw new ArgumentException ("A multicolumn ListBox cannot have a variable-sized height.");
405 if (IsHandleCreated) {
406 RellocateScrollBars ();
408 UpdateItemInfo (UpdateOperation.AllItems, 0, 0);
414 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
415 [EditorBrowsable (EditorBrowsableState.Advanced)]
416 public int PreferredHeight {
417 get { return preferred_height;}
420 public override RightToLeft RightToLeft {
421 get { return base.RightToLeft; }
423 if (base.RightToLeft == value)
426 base.RightToLeft = value;
431 // Only affects the Vertical ScrollBar
432 [DefaultValue (false)]
434 public bool ScrollAlwaysVisible {
435 get { return scroll_always_visible; }
437 if (scroll_always_visible == value)
440 scroll_always_visible = value;
441 UpdateShowVerticalScrollBar ();
442 UpdateShowHorizontalScrollBar ();
448 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
449 public override int SelectedIndex {
450 get { return selected_index;}
452 if (value < -1 || value >= Items.Count)
453 throw new ArgumentOutOfRangeException ("Index of out range");
455 if (SelectionMode == SelectionMode.None)
456 throw new ArgumentException ("cannot call this method if SelectionMode is SelectionMode.None");
458 if (selected_index == value)
461 if (SelectionMode == SelectionMode.One)
462 UnSelectItem (selected_index, true);
465 selected_index = value;
466 focused_item = value;
467 OnSelectedIndexChanged (new EventArgs ());
472 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
473 public SelectedIndexCollection SelectedIndices {
474 get { return selected_indices; }
479 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
480 public object SelectedItem {
482 if (SelectedItems.Count > 0)
483 return SelectedItems[0];
489 int index = Items.IndexOf (value);
494 if (index != SelectedIndex) {
495 SelectedIndex = index;
501 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
502 public SelectedObjectCollection SelectedItems {
503 get {return selected_items;}
506 [DefaultValue (SelectionMode.One)]
507 public virtual SelectionMode SelectionMode {
508 get { return selection_mode; }
510 if (!Enum.IsDefined (typeof (SelectionMode), value))
511 throw new InvalidEnumArgumentException (string.Format("Enum argument value '{0}' is not valid for SelectionMode", value));
513 if (selection_mode == value)
516 selection_mode = value;
518 if (SelectedItems.Count > 0) {
519 switch (selection_mode) {
520 case SelectionMode.None:
523 case SelectionMode.One: {
524 if (SelectedItems.Count > 1) { // All except one
525 int cnt = selected_indices.Count - 1;
526 for (int i = 0; i < cnt; i++) {
527 UnSelectItem (i, true);
539 [DefaultValue (false)]
541 get { return sorted; }
554 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
555 [EditorBrowsable (EditorBrowsableState.Advanced)]
556 public override string Text {
558 if (SelectionMode != SelectionMode.None && SelectedIndex != -1)
559 return Items[SelectedIndex].ToString ();
567 if (SelectionMode == SelectionMode.None)
572 index = FindStringExact (value);
577 SelectedIndex = index;
582 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
583 public int TopIndex {
584 get { return top_index;}
586 if (value == top_index)
589 if (value < 0 || value >= Items.Count)
597 [DefaultValue (true)]
598 public bool UseTabStops {
599 get { return use_tabstops; }
602 if (use_tabstops == value)
605 use_tabstops = value;
610 #endregion Public Properties
612 #region Private Properties
614 internal ListBoxInfo LBoxInfo {
615 get { return listbox_info; }
618 private int ColumnWidthInternal {
619 get { return column_width_internal; }
620 set { column_width_internal = value; }
623 #endregion Private Properties
625 #region Public Methods
626 protected virtual void AddItemsCore (object[] value)
628 Items.AddRange (value);
631 public void BeginUpdate ()
633 suspend_ctrlupdate = true;
636 public void ClearSelected ()
638 foreach (int i in selected_indices) {
639 UnSelectItem (i, false);
642 selected_indices.ClearIndices ();
643 selected_items.ClearObjects ();
646 protected virtual ObjectCollection CreateItemCollection ()
648 return new ObjectCollection (this);
651 public void EndUpdate ()
653 suspend_ctrlupdate = false;
654 UpdateItemInfo (UpdateOperation.AllItems, 0, 0);
658 public int FindString (String s)
660 return FindString (s, 0);
663 public int FindString (string s, int startIndex)
665 for (int i = startIndex; i < Items.Count; i++) {
666 if ((Items[i].ToString ()).StartsWith (s))
673 public int FindStringExact (string s)
675 return FindStringExact (s, 0);
678 public int FindStringExact (string s, int startIndex)
680 for (int i = startIndex; i < Items.Count; i++) {
681 if ((Items[i].ToString ()).Equals (s))
688 public int GetItemHeight (int index)
690 if (index < 0 || index >= Items.Count)
691 throw new ArgumentOutOfRangeException ("Index of out range");
693 if (DrawMode == DrawMode.OwnerDrawVariable && IsHandleCreated == true) {
695 if ((Items.GetListBoxItem (index)).ItemHeight != -1) {
696 return (Items.GetListBoxItem (index)).ItemHeight;
699 MeasureItemEventArgs args = new MeasureItemEventArgs (DeviceContext, index, ItemHeight);
700 OnMeasureItem (args);
701 (Items.GetListBoxItem (index)).ItemHeight = args.ItemHeight;
702 return args.ItemHeight;
708 public Rectangle GetItemRectangle (int index)
710 if (index < 0 || index >= Items.Count)
711 throw new ArgumentOutOfRangeException ("GetItemRectangle index out of range.");
713 Rectangle rect = new Rectangle ();
715 if (MultiColumn == false) {
718 rect.Height = GetItemHeight (index);
719 rect.Width = listbox_info.textdrawing_rect.Width;
721 if (DrawMode == DrawMode.OwnerDrawVariable) {
723 for (int i = 0; i < index; i++) {
724 rect.Y += GetItemHeight (i);
727 rect.Y = ItemHeight * index;
733 which_page = index / listbox_info.page_size;
734 rect.Y = (index % listbox_info.page_size) * ItemHeight;
735 rect.X = which_page * ColumnWidthInternal;
736 rect.Height = ItemHeight;
737 rect.Width = ColumnWidthInternal;
743 public bool GetSelected (int index)
745 if (index < 0 || index >= Items.Count)
746 throw new ArgumentOutOfRangeException ("Index of out range");
748 return (Items.GetListBoxItem (index)).Selected;
751 public int IndexFromPoint (Point p)
753 return IndexFromPoint (p.X, p.Y);
756 // Only returns visible points
757 public int IndexFromPoint (int x, int y)
759 for (int i = LBoxInfo.top_item; i < LBoxInfo.last_item; i++) {
760 if (GetItemRectangle (i).Contains (x,y) == true)
767 protected override void OnChangeUICues (UICuesEventArgs e)
769 base.OnChangeUICues (e);
772 protected override void OnDataSourceChanged (EventArgs e)
774 base.OnDataSourceChanged (e);
777 protected override void OnDisplayMemberChanged (EventArgs e)
779 base.OnDisplayMemberChanged (e);
782 protected virtual void OnDrawItem (DrawItemEventArgs e)
785 if (DrawItem != null && (DrawMode == DrawMode.OwnerDrawFixed || DrawMode == DrawMode.OwnerDrawVariable)) {
790 ThemeEngine.Current.DrawListBoxItem (this, e);
793 protected override void OnFontChanged (EventArgs e)
795 base.OnFontChanged (e);
796 listbox_info.item_height = FontHeight;
798 RellocateScrollBars ();
800 UpdateItemInfo (UpdateOperation.AllItems, 0, 0);
803 protected override void OnHandleCreated (EventArgs e)
805 base.OnHandleCreated (e);
807 UpdateInternalClientRect (ClientRectangle);
808 Controls.Add (vscrollbar_ctrl);
809 Controls.Add (hscrollbar_ctrl);
810 UpdateItemInfo (UpdateOperation.AllItems, 0, 0);
813 protected override void OnHandleDestroyed (EventArgs e)
815 base.OnHandleDestroyed (e);
818 protected virtual void OnMeasureItem (MeasureItemEventArgs e)
820 if (draw_mode != DrawMode.OwnerDrawVariable)
823 if (MeasureItem != null)
824 MeasureItem (this, e);
827 protected override void OnParentChanged (EventArgs e)
829 base.OnParentChanged (e);
832 protected override void OnResize (EventArgs e)
835 UpdateInternalClientRect (ClientRectangle);
838 protected override void OnSelectedIndexChanged (EventArgs e)
840 base.OnSelectedIndexChanged (e);
842 if (SelectedIndexChanged != null)
843 SelectedIndexChanged (this, e);
846 protected override void OnSelectedValueChanged (EventArgs e)
848 base.OnSelectedValueChanged (e);
851 public override void Refresh ()
853 if (draw_mode == DrawMode.OwnerDrawVariable) {
854 for (int i = 0; i < Items.Count; i++) {
855 (Items.GetListBoxItem (i)).ItemHeight = -1;
862 protected override void RefreshItem (int index)
864 if (index < 0 || index >= Items.Count)
865 throw new ArgumentOutOfRangeException ("Index of out range");
867 if (draw_mode == DrawMode.OwnerDrawVariable) {
868 (Items.GetListBoxItem (index)).ItemHeight = -1;
872 protected override void SetBoundsCore (int x, int y, int width, int height, BoundsSpecified specified)
874 base.SetBoundsCore (x, y, width, height, specified);
877 protected override void SetItemCore (int index, object value)
879 if (index < 0 || index >= Items.Count)
882 Items[index] = value;
885 protected override void SetItemsCore (IList value)
890 public void SetSelected (int index, bool value)
892 if (index < 0 || index >= Items.Count)
893 throw new ArgumentOutOfRangeException ("Index of out range");
895 if (SelectionMode == SelectionMode.None)
896 throw new InvalidOperationException ();
901 UnSelectItem (index, true);
904 protected virtual void Sort ()
906 if (Items.Count == 0)
913 public override string ToString ()
915 return base.ToString () + ", Items Count: " + Items.Count;
918 protected virtual void WmReflectCommand (ref Message m)
923 protected override void WndProc (ref Message m)
925 switch ((Msg) m.Msg) {
928 PaintEventArgs paint_event;
929 paint_event = XplatUI.PaintEventStart (Handle);
930 OnPaintLB (paint_event);
931 XplatUI.PaintEventEnd (Handle);
935 case Msg.WM_ERASEBKGND:
936 m.Result = (IntPtr) 1;
943 base.WndProc (ref m);
946 #endregion Public Methods
948 #region Private Methods
950 internal void CalcClientArea ()
952 listbox_info.textdrawing_rect = listbox_info.client_rect;
953 listbox_info.textdrawing_rect.Y += ThemeEngine.Current.DrawListBoxDecorationTop (BorderStyle);
954 listbox_info.textdrawing_rect.X += ThemeEngine.Current.DrawListBoxDecorationLeft (BorderStyle);
955 //BUG: Top and Left decorations
956 listbox_info.textdrawing_rect.Height -= ThemeEngine.Current.DrawListBoxDecorationBottom (BorderStyle);
957 listbox_info.textdrawing_rect.Width -= ThemeEngine.Current.DrawListBoxDecorationRight (BorderStyle);
959 if (listbox_info.show_verticalsb)
960 listbox_info.textdrawing_rect.Width -= vscrollbar_ctrl.Width;
962 if (listbox_info.show_horizontalsb)
963 listbox_info.textdrawing_rect.Height -= hscrollbar_ctrl.Height;
965 if (DrawMode == DrawMode.OwnerDrawVariable) {
968 listbox_info.page_size = 0;
969 for (int i = 0; i < Items.Count; i++) {
970 height += GetItemHeight (i);
971 if (height > listbox_info.textdrawing_rect.Height)
974 listbox_info.page_size++;
978 listbox_info.page_size = listbox_info.textdrawing_rect.Height / listbox_info.item_height;
981 if (listbox_info.page_size == 0) {
982 listbox_info.page_size = 1;
985 /* Adjust size to visible the maxim number of displayable items */
986 if (IntegralHeight == true) {
988 // From MS Docs: The integral height is based on the height of the ListBox, rather than
989 // the client area height. As a result, when the IntegralHeight property is set true,
990 // items can still be partially shown if scroll bars are displayed.
992 int remaining = (listbox_info.client_rect.Height -
993 ThemeEngine.Current.DrawListBoxDecorationBottom (BorderStyle) -
994 ThemeEngine.Current.DrawListBoxDecorationBottom (BorderStyle)) %
995 listbox_info.item_height;
998 listbox_info.client_rect.Height -= remaining;
1000 RellocateScrollBars ();
1006 internal void Draw (Rectangle clip)
1008 if (LBoxInfo.textdrawing_rect.Contains (clip) == false) {
1009 // IntegralHeight has effect, we also have to paint the unused area
1010 if (ClientRectangle.Height > listbox_info.client_rect.Height) {
1011 Region area = new Region (ClientRectangle);
1012 area.Exclude (listbox_info.client_rect);
1014 DeviceContext.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (Parent.BackColor),
1015 area.GetBounds (DeviceContext));
1018 DeviceContext.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (BackColor), LBoxInfo.textdrawing_rect);
1021 if (Items.Count > 0) {
1022 Rectangle item_rect;
1023 DrawItemState state = DrawItemState.None;
1025 for (int i = LBoxInfo.top_item; i <= LBoxInfo.last_item; i++) {
1026 item_rect = GetItemDisplayRectangle (i, LBoxInfo.top_item);
1028 if (clip.IntersectsWith (item_rect) == false)
1032 state = DrawItemState.None;
1034 if ((Items.GetListBoxItem (i)).Selected) {
1035 state |= DrawItemState.Selected;
1038 if (has_focus == true && focused_item == i)
1039 state |= DrawItemState.Focus;
1041 OnDrawItem (new DrawItemEventArgs (DeviceContext, Font, item_rect,
1042 i, state, ForeColor, BackColor));
1046 ThemeEngine.Current.DrawListBoxDecorations (DeviceContext, this);
1049 // Converts a GetItemRectangle to a one that we can display
1050 internal Rectangle GetItemDisplayRectangle (int index, int first_displayble)
1052 Rectangle item_rect;
1053 Rectangle first_item_rect = GetItemRectangle (first_displayble);
1054 item_rect = GetItemRectangle (index);
1055 item_rect.X -= first_item_rect.X;
1056 item_rect.Y -= first_item_rect.Y;
1058 item_rect.Y += ThemeEngine.Current.DrawListBoxDecorationTop (BorderStyle);
1059 item_rect.X += ThemeEngine.Current.DrawListBoxDecorationLeft (BorderStyle);
1060 item_rect.Width -= ThemeEngine.Current.DrawListBoxDecorationRight (BorderStyle);
1066 private void HorizontalScrollEvent (object sender, EventArgs e)
1068 LBoxInfo.top_item = listbox_info.page_size * hscrollbar_ctrl.Value;
1069 LBoxInfo.last_item = LastVisibleItem ();
1073 // Only returns visible points. The diference of with IndexFromPoint is that the rectangle
1074 // has screen coordinates
1075 internal int IndexFromPointDisplayRectangle (int x, int y)
1077 if (LBoxInfo.top_item == LBoxInfo.last_item)
1080 for (int i = LBoxInfo.top_item; i <= LBoxInfo.last_item; i++) {
1081 if (GetItemDisplayRectangle (i, LBoxInfo.top_item).Contains (x, y) == true)
1088 private int LastVisibleItem ()
1090 Rectangle item_rect;
1091 int top_y = LBoxInfo.textdrawing_rect.Y + LBoxInfo.textdrawing_rect.Height;
1094 if (LBoxInfo.top_item >= Items.Count)
1095 return LBoxInfo.top_item;
1097 for (i = LBoxInfo.top_item; i < Items.Count; i++) {
1099 item_rect = GetItemDisplayRectangle (i, LBoxInfo.top_item);
1102 if (item_rect.X > LBoxInfo.textdrawing_rect.Width)
1106 if (IntegralHeight) {
1107 if (item_rect.Y + item_rect.Height > top_y) {
1112 if (item_rect.Y + item_rect.Height > top_y)
1120 private void UpdatedTopItem ()
1123 int col = (LBoxInfo.top_item / LBoxInfo.page_size);
1124 hscrollbar_ctrl.Value = col;
1127 if (LBoxInfo.top_item > vscrollbar_ctrl.Maximum)
1128 vscrollbar_ctrl.Value = vscrollbar_ctrl.Maximum;
1130 vscrollbar_ctrl.Value = LBoxInfo.top_item;
1134 // Navigates to the indicated item and returns the new item
1135 private int NavigateItemVisually (ItemNavigation navigation)
1137 int page_size, columns, selected_index = -1;
1140 columns = LBoxInfo.textdrawing_rect.Width / ColumnWidthInternal;
1141 page_size = columns * LBoxInfo.page_size;
1142 if (page_size == 0) {
1143 page_size = LBoxInfo.page_size;
1146 page_size = LBoxInfo.page_size;
1149 switch (navigation) {
1151 case ItemNavigation.PreviousColumn: {
1152 if (focused_item - LBoxInfo.page_size < 0) {
1156 if (focused_item - LBoxInfo.page_size < LBoxInfo.top_item) {
1157 LBoxInfo.top_item = focused_item - LBoxInfo.page_size;
1161 selected_index = focused_item - LBoxInfo.page_size;
1165 case ItemNavigation.NextColumn: {
1166 if (focused_item + LBoxInfo.page_size >= Items.Count) {
1170 if (focused_item + LBoxInfo.page_size > LBoxInfo.last_item) {
1171 LBoxInfo.top_item = focused_item;
1175 selected_index = focused_item + LBoxInfo.page_size;
1179 case ItemNavigation.First: {
1180 LBoxInfo.top_item = 0;
1186 case ItemNavigation.Last: {
1188 if (Items.Count < LBoxInfo.page_size) {
1189 LBoxInfo.top_item = 0;
1190 selected_index = Items.Count - 1;
1193 LBoxInfo.top_item = Items.Count - LBoxInfo.page_size;
1194 selected_index = Items.Count - 1;
1200 case ItemNavigation.Next: {
1201 if (focused_item + 1 < Items.Count) {
1202 if (focused_item + 1 > LBoxInfo.last_item) {
1203 LBoxInfo.top_item++;
1206 selected_index = focused_item + 1;
1211 case ItemNavigation.Previous: {
1212 if (focused_item > 0) {
1213 if (focused_item - 1 < LBoxInfo.top_item) {
1214 LBoxInfo.top_item--;
1217 selected_index = focused_item - 1;
1222 case ItemNavigation.NextPage: {
1223 if (Items.Count < page_size) {
1224 NavigateItemVisually (ItemNavigation.Last);
1228 if (focused_item + page_size - 1 >= Items.Count) {
1229 LBoxInfo.top_item = Items.Count - page_size;
1231 selected_index = Items.Count - 1;
1234 if (focused_item + page_size - 1 > LBoxInfo.last_item) {
1235 LBoxInfo.top_item = focused_item;
1239 selected_index = focused_item + page_size - 1;
1245 case ItemNavigation.PreviousPage: {
1247 if (focused_item - (LBoxInfo.page_size - 1) <= 0) {
1249 LBoxInfo.top_item = 0;
1254 if (focused_item - (LBoxInfo.page_size - 1) < LBoxInfo.top_item) {
1255 LBoxInfo.top_item = focused_item - (LBoxInfo.page_size - 1);
1259 selected_index = focused_item - (LBoxInfo.page_size - 1);
1268 return selected_index;
1272 private void OnGotFocus (object sender, EventArgs e)
1276 if (focused_item != -1) {
1277 Rectangle invalidate = GetItemDisplayRectangle (focused_item, LBoxInfo.top_item);
1278 Invalidate (invalidate);
1282 private void OnLostFocus (object sender, EventArgs e)
1286 if (focused_item != -1) {
1287 Rectangle invalidate = GetItemDisplayRectangle (focused_item, LBoxInfo.top_item);
1288 Invalidate (invalidate);
1292 private void OnKeyDownLB (object sender, KeyEventArgs e)
1296 switch (e.KeyCode) {
1298 case Keys.ControlKey:
1299 ctrl_pressed = true;
1303 shift_pressed = true;
1307 new_item = NavigateItemVisually (ItemNavigation.First);
1311 new_item = NavigateItemVisually (ItemNavigation.Last);
1315 new_item = NavigateItemVisually (ItemNavigation.Previous);
1319 new_item = NavigateItemVisually (ItemNavigation.Next);
1323 new_item = NavigateItemVisually (ItemNavigation.PreviousPage);
1327 new_item = NavigateItemVisually (ItemNavigation.NextPage);
1331 if (multicolumn == true) {
1332 new_item = NavigateItemVisually (ItemNavigation.NextColumn);
1337 if (multicolumn == true) {
1338 new_item = NavigateItemVisually (ItemNavigation.PreviousColumn);
1343 if (selection_mode == SelectionMode.MultiSimple) {
1344 SelectedItemFromNavigation (focused_item);
1353 if (new_item != -1) {
1354 SetFocusedItem (new_item);
1357 if (new_item != -1) {
1358 if (selection_mode != SelectionMode.MultiSimple && selection_mode != SelectionMode.None) {
1359 SelectedItemFromNavigation (new_item);
1364 private void OnKeyUpLB (object sender, KeyEventArgs e)
1366 switch (e.KeyCode) {
1367 case Keys.ControlKey:
1368 ctrl_pressed = false;
1371 shift_pressed = false;
1378 internal virtual void OnMouseDownLB (object sender, MouseEventArgs e)
1380 if (Click != null) {
1381 if (e.Button == MouseButtons.Left) {
1386 int index = IndexFromPointDisplayRectangle (e.X, e.Y);
1389 SelectedItemFromNavigation (index);
1390 SetFocusedItem (index);
1394 private void OnPaintLB (PaintEventArgs pevent)
1397 Paint (this, pevent);
1399 if (Width <= 0 || Height <= 0 || Visible == false || suspend_ctrlupdate == true)
1402 /* Copies memory drawing buffer to screen*/
1403 Draw (pevent.ClipRectangle);
1404 pevent.Graphics.DrawImage (ImageBuffer, pevent.ClipRectangle, pevent.ClipRectangle, GraphicsUnit.Pixel);
1408 internal void RellocateScrollBars ()
1410 if (listbox_info.show_verticalsb) {
1412 vscrollbar_ctrl.Size = new Size (vscrollbar_ctrl.Width,
1413 listbox_info.client_rect.Height - ThemeEngine.Current.DrawListBoxDecorationTop (BorderStyle) -
1414 ThemeEngine.Current.DrawListBoxDecorationBottom (BorderStyle));
1416 vscrollbar_ctrl.Location = new Point (listbox_info.client_rect.Width - vscrollbar_ctrl.Width
1417 - ThemeEngine.Current.DrawListBoxDecorationRight (BorderStyle),
1418 ThemeEngine.Current.DrawListBoxDecorationTop (BorderStyle));
1422 if (listbox_info.show_horizontalsb) {
1426 width = listbox_info.client_rect.Width - (ThemeEngine.Current.DrawListBoxDecorationLeft (BorderStyle) + ThemeEngine.Current.DrawListBoxDecorationRight (BorderStyle));
1428 if (listbox_info.show_verticalsb)
1429 width -= vscrollbar_ctrl.Width;
1431 hscrollbar_ctrl.Size = new Size (width, hscrollbar_ctrl.Height);
1433 hscrollbar_ctrl.Location = new Point (ThemeEngine.Current.DrawListBoxDecorationLeft (BorderStyle),
1434 listbox_info.client_rect.Height - hscrollbar_ctrl.Height
1435 - ThemeEngine.Current.DrawListBoxDecorationTop (BorderStyle));
1441 // Add an item in the Selection array and marks it visually as selected
1442 private void SelectItem (int index)
1447 Rectangle invalidate = GetItemDisplayRectangle (index, LBoxInfo.top_item);
1448 (Items.GetListBoxItem (index)).Selected = true;
1449 selected_indices.AddIndex (index);
1450 selected_items.AddObject (Items[index]);
1452 if (ClientRectangle.Contains (invalidate))
1453 Invalidate (invalidate);
1457 // An item navigation operation (mouse or keyboard) has caused to select a new item
1458 private void SelectedItemFromNavigation (int index)
1460 switch (SelectionMode) {
1461 case SelectionMode.None: // Do nothing
1463 case SelectionMode.One: {
1464 SelectedIndex = index;
1467 case SelectionMode.MultiSimple: {
1468 if (selected_index == -1) {
1469 SelectedIndex = index;
1472 if ((Items.GetListBoxItem (index)).Selected) // BUG: index or selected_index?
1473 UnSelectItem (index, true);
1476 OnSelectedIndexChanged (new EventArgs ());
1482 case SelectionMode.MultiExtended: {
1483 if (selected_index == -1) {
1484 SelectedIndex = index;
1487 if (ctrl_pressed == false && shift_pressed == false) {
1491 if (shift_pressed == true) {
1492 ShiftSelection (index);
1493 } else { // ctrl_pressed or single item
1497 OnSelectedIndexChanged (new EventArgs ());
1507 private void ShiftSelection (int index)
1509 int shorter_item = -1, dist = Items.Count + 1, cur_dist;
1511 foreach (int idx in selected_indices) {
1513 cur_dist = idx - index;
1516 cur_dist = index - idx;
1519 if (cur_dist < dist) {
1525 if (shorter_item != -1) {
1528 if (shorter_item > index) {
1532 start = shorter_item;
1537 for (int idx = start; idx <= end; idx++) {
1543 void SetFocusedItem (int index)
1545 Rectangle invalidate;
1546 int prev = focused_item;
1548 focused_item = index;
1550 if (has_focus == false)
1553 if (prev != -1) { // Invalidates previous item
1554 invalidate = GetItemDisplayRectangle (prev, LBoxInfo.top_item);
1555 Invalidate (invalidate);
1559 invalidate = GetItemDisplayRectangle (index, LBoxInfo.top_item);
1560 Invalidate (invalidate);
1564 // Removes an item in the Selection array and marks it visually as unselected
1565 private void UnSelectItem (int index, bool remove)
1570 Rectangle invalidate = GetItemDisplayRectangle (index, LBoxInfo.top_item);
1571 (Items.GetListBoxItem (index)).Selected = false;
1574 selected_indices.RemoveIndex (index);
1575 selected_items.RemoveObject (Items[index]);
1578 if (ClientRectangle.Contains (invalidate))
1579 Invalidate (invalidate);
1582 internal StringFormat GetFormatString ()
1584 StringFormat string_format = new StringFormat ();
1586 if (RightToLeft == RightToLeft.Yes)
1587 string_format.Alignment = StringAlignment.Far;
1589 string_format.Alignment = StringAlignment.Near;
1592 string_format.SetTabStops (0, new float [] {(float)(Font.Height * 3.7)});
1594 return string_format;
1597 // Updates the scrollbar's position with the new items and inside area
1598 internal virtual void UpdateItemInfo (UpdateOperation operation, int first, int last)
1600 if (!IsHandleCreated || suspend_ctrlupdate == true)
1603 UpdateShowVerticalScrollBar ();
1605 if (listbox_info.show_verticalsb && Items.Count > listbox_info.page_size)
1606 if (vscrollbar_ctrl.Enabled)
1607 vscrollbar_ctrl.Maximum = Items.Count - listbox_info.page_size;
1609 if (listbox_info.show_horizontalsb) {
1611 int fullpage = (listbox_info.page_size * (listbox_info.client_rect.Width / ColumnWidthInternal));
1613 if (hscrollbar_ctrl.Enabled && listbox_info.page_size > 0)
1614 hscrollbar_ctrl.Maximum = Math.Max (0, 1 + ((Items.Count - fullpage) / listbox_info.page_size));
1618 if (MultiColumn == false) {
1619 /* Calc the longest items for non multicolumn listboxes */
1620 if (operation == UpdateOperation.AllItems || operation == UpdateOperation.DeleteItems) {
1623 for (int i = 0; i < Items.Count; i++) {
1624 size = DeviceContext.MeasureString (Items[i].ToString(), Font);
1626 if ((int) size.Width > listbox_info.max_itemwidth)
1627 listbox_info.max_itemwidth = (int) size.Width;
1631 if (operation == UpdateOperation.AddItems) {
1634 for (int i = first; i < last + 1; i++) {
1635 size = DeviceContext.MeasureString (Items[i].ToString(), Font);
1637 if ((int) size.Width > listbox_info.max_itemwidth)
1638 listbox_info.max_itemwidth = (int) size.Width;
1647 if (Items.Count == 0) {
1648 selected_index = -1;
1652 SelectedItems.ReCreate ();
1653 SelectedIndices.ReCreate ();
1654 UpdateShowHorizontalScrollBar ();
1655 LBoxInfo.last_item = LastVisibleItem ();
1659 private void UpdateInternalClientRect (Rectangle client_rectangle)
1661 listbox_info.client_rect = client_rectangle;
1662 UpdateShowHorizontalScrollBar ();
1663 UpdateShowVerticalScrollBar ();
1664 RellocateScrollBars ();
1665 UpdateItemInfo (UpdateOperation.AllItems, 0, 0);
1668 /* Determines if the horizontal scrollbar has to be displyed */
1669 private void UpdateShowHorizontalScrollBar ()
1672 bool enabled = true;
1674 if (MultiColumn) { /* Horizontal scrollbar is always shown in Multicolum mode */
1676 /* Is it really need it */
1677 int page_size = listbox_info.client_rect.Height / listbox_info.item_height;
1678 int fullpage = (page_size * (listbox_info.textdrawing_rect.Height / ColumnWidthInternal));
1680 if (Items.Count > fullpage) {
1683 else { /* Acording to MS Documentation ScrollAlwaysVisible only affects Horizontal scrollbars but
1684 this is not true for MultiColumn listboxes */
1685 if (ScrollAlwaysVisible == true) {
1691 } else { /* If large item*/
1693 if (listbox_info.max_itemwidth > listbox_info.client_rect.Width && HorizontalScrollbar) {
1695 hscrollbar_ctrl.Maximum = listbox_info.max_itemwidth;
1699 if (hscrollbar_ctrl.Enabled != enabled)
1700 hscrollbar_ctrl.Enabled = enabled;
1702 if (listbox_info.show_horizontalsb == show)
1705 listbox_info.show_horizontalsb = show;
1706 hscrollbar_ctrl.Visible = show;
1709 RellocateScrollBars ();
1715 /* Determines if the vertical scrollbar has to be displyed */
1716 private void UpdateShowVerticalScrollBar ()
1719 bool enabled = true;
1721 if (!MultiColumn) { /* Vertical scrollbar is never shown in Multicolum mode */
1722 if (Items.Count > listbox_info.page_size) {
1726 if (ScrollAlwaysVisible) {
1732 if (vscrollbar_ctrl.Enabled != enabled)
1733 vscrollbar_ctrl.Enabled = enabled;
1735 if (listbox_info.show_verticalsb == show)
1738 listbox_info.show_verticalsb = show;
1739 vscrollbar_ctrl.Visible = show;
1742 if (vscrollbar_ctrl.Enabled)
1743 vscrollbar_ctrl.Maximum = Items.Count - listbox_info.page_size;
1745 RellocateScrollBars ();
1752 private void VerticalScrollEvent (object sender, EventArgs e)
1754 LBoxInfo.top_item = /*listbox_info.page_size + */ vscrollbar_ctrl.Value;
1755 LBoxInfo.last_item = LastVisibleItem ();
1760 #endregion Private Methods
1763 ListBox.ObjectCollection
1765 [ListBindable (false)]
1766 public class ObjectCollection : IList, ICollection, IEnumerable
1769 internal class ListObjectComparer : IComparer
\r
1771 private ListBox owner;
\r
1773 public ListObjectComparer (ListBox owner)
\r
1775 this.owner = owner;
\r
1778 public int Compare (object a, object b)
\r
1780 string str1 = a.ToString ();
1781 string str2 = b.ToString ();
\r
1782 return str1.CompareTo (str2);
\r
1787 internal class ListItemComparer : IComparer
\r
1789 private ListBox owner;
\r
1791 public ListItemComparer (ListBox owner)
\r
1793 this.owner = owner;
\r
1796 public int Compare (object a, object b)
\r
1798 int index1 = ((ListBox.ListBoxItem) (a)).Index;
1799 int index2 = ((ListBox.ListBoxItem) (b)).Index;
1800 string str1 = owner.Items[index1].ToString ();
1801 string str2 = owner.Items[index2].ToString ();
\r
1802 return str1.CompareTo (str2);
\r
1806 private ListBox owner;
1807 internal ArrayList object_items = new ArrayList ();
1808 internal ArrayList listbox_items = new ArrayList ();
1810 public ObjectCollection (ListBox owner)
1815 public ObjectCollection (ListBox owner, object[] obj)
1821 public ObjectCollection (ListBox owner, ObjectCollection obj)
1827 #region Public Properties
1828 public virtual int Count {
1829 get { return object_items.Count; }
1832 public virtual bool IsReadOnly {
1833 get { return false; }
1837 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
1838 public virtual object this [int index] {
1840 if (index < 0 || index >= Count)
1841 throw new ArgumentOutOfRangeException ("Index of out range");
1843 return object_items[index];
1846 if (index < 0 || index >= Count)
1847 throw new ArgumentOutOfRangeException ("Index of out range");
1849 object_items[index] = value;
1853 bool ICollection.IsSynchronized {
1854 get { return false; }
1857 object ICollection.SyncRoot {
1858 get { return this; }
1861 bool IList.IsFixedSize {
1862 get { return false; }
1865 #endregion Public Properties
1867 #region Private Properties
1868 internal ArrayList ObjectItems {
1869 get { return object_items;}
1871 object_items = value;
1875 internal ArrayList ListBoxItems {
1876 get { return listbox_items;}
1878 listbox_items = value;
1881 #endregion Private Properties
1883 #region Public Methods
1884 public int Add (object item)
1888 idx = AddItem (item);
1889 owner.UpdateItemInfo (UpdateOperation.AddItems, idx, idx);
1893 public void AddRange (object[] items)
1897 foreach (object mi in items)
1900 owner.UpdateItemInfo (UpdateOperation.AddItems, cnt, Count - 1);
1903 public void AddRange (ObjectCollection col)
1907 foreach (object mi in col)
1910 owner.UpdateItemInfo (UpdateOperation.AddItems, cnt, Count - 1);
1913 public virtual void Clear ()
1915 object_items.Clear ();
1916 listbox_items.Clear ();
1917 owner.UpdateItemInfo (UpdateOperation.AllItems, 0, 0);
1919 public virtual bool Contains (object obj)
1921 return object_items.Contains (obj);
1924 public void CopyTo (object[] dest, int arrayIndex)
1926 object_items.CopyTo (dest, arrayIndex);
1929 void ICollection.CopyTo (Array dest, int index)
1931 object_items.CopyTo (dest, index);
1934 public virtual IEnumerator GetEnumerator ()
1936 return object_items.GetEnumerator ();
1939 int IList.Add (object item)
1944 public virtual int IndexOf (object value)
1946 return object_items.IndexOf (value);
1949 public virtual void Insert (int index, object item)
1951 if (index < 0 || index >= Count)
1952 throw new ArgumentOutOfRangeException ("Index of out range");
1955 ObjectCollection new_items = new ObjectCollection (owner);
1957 owner.BeginUpdate ();
1959 for (int i = 0; i < index; i++) {
1960 idx = new_items.AddItem (ObjectItems[i]);
1961 (new_items.GetListBoxItem (idx)).CopyState (GetListBoxItem (i));
1964 new_items.AddItem (item);
1966 for (int i = index; i < Count; i++){
1967 idx = new_items.AddItem (ObjectItems[i]);
1968 (new_items.GetListBoxItem (idx)).CopyState (GetListBoxItem (i));
1971 ObjectItems = new_items.ObjectItems;
1972 ListBoxItems = new_items.ListBoxItems;
1974 owner.EndUpdate (); // Calls UpdateItemInfo
1977 public virtual void Remove (object value)
1979 RemoveAt (IndexOf (value));
1982 public virtual void RemoveAt (int index)
1984 if (index < 0 || index >= Count)
1985 throw new ArgumentOutOfRangeException ("Index of out range");
1987 object_items.RemoveAt (index);
1988 listbox_items.RemoveAt (index);
1989 owner.UpdateItemInfo (UpdateOperation.DeleteItems, index, index);
1991 #endregion Public Methods
1993 #region Private Methods
1994 internal int AddItem (object item)
1996 int cnt = object_items.Count;
1997 object_items.Add (item);
1998 listbox_items.Add (new ListBox.ListBoxItem (cnt));
2002 internal ListBox.ListBoxItem GetListBoxItem (int index)
2004 if (index < 0 || index >= Count)
2005 throw new ArgumentOutOfRangeException ("Index of out range");
2007 return (ListBox.ListBoxItem) listbox_items[index];
2010 internal void SetListBoxItem (ListBox.ListBoxItem item, int index)
2012 if (index < 0 || index >= Count)
2013 throw new ArgumentOutOfRangeException ("Index of out range");
2015 listbox_items[index] = item;
2018 internal void Sort ()
2020 /* Keep this order */
2021 listbox_items.Sort (new ListItemComparer (owner));
2022 object_items.Sort (new ListObjectComparer (owner));
2024 for (int i = 0; i < listbox_items.Count; i++) {
2025 ListBox.ListBoxItem item = GetListBoxItem (i);
2030 #endregion Private Methods
2034 ListBox.SelectedIndexCollection
2036 public class SelectedIndexCollection : IList, ICollection, IEnumerable
2038 private ListBox owner;
2039 private ArrayList indices = new ArrayList ();
2041 public SelectedIndexCollection (ListBox owner)
2046 #region Public Properties
2048 public virtual int Count {
2049 get { return indices.Count; }
2052 public virtual bool IsReadOnly {
2053 get { return true; }
2056 public int this [int index] {
2058 if (index < 0 || index >= Count)
2059 throw new ArgumentOutOfRangeException ("Index of out range");
2061 return (int) indices[index];
2065 bool ICollection.IsSynchronized {
2066 get { return true; }
2069 bool IList.IsFixedSize{
2070 get { return true; }
2073 object ICollection.SyncRoot {
2074 get { return this; }
2077 #endregion Public Properties
2079 #region Public Methods
2080 public bool Contains (int selectedIndex)
2082 return indices.Contains (selectedIndex);
2085 public virtual void CopyTo (Array dest, int index)
2087 indices.CopyTo (dest, index);
2090 public virtual IEnumerator GetEnumerator ()
2092 return indices.GetEnumerator ();
2095 int IList.Add (object obj)
2097 throw new NotSupportedException ();
2102 throw new NotSupportedException ();
2105 bool IList.Contains (object selectedIndex)
2107 return Contains ((int)selectedIndex);
2110 int IList.IndexOf (object selectedIndex)
2112 return IndexOf ((int) selectedIndex);
2115 void IList.Insert (int index, object value)
2117 throw new NotSupportedException ();
2120 void IList.Remove (object value)
2122 throw new NotSupportedException ();
2125 void IList.RemoveAt (int index)
2127 throw new NotSupportedException ();
2130 object IList.this[int index]{
2131 get {return indices[index]; }
2132 set {throw new NotImplementedException (); }
2135 public int IndexOf (int selectedIndex)
2137 return indices.IndexOf (selectedIndex);
2139 #endregion Public Methods
2141 #region Private Methods
2143 internal void AddIndex (int index)
2145 indices.Add (index);
2148 internal void ClearIndices ()
2153 internal void RemoveIndex (int index)
2155 indices.Remove (index);
2158 internal void ReCreate ()
2162 for (int i = 0; i < owner.Items.Count; i++) {
2163 ListBox.ListBoxItem item = owner.Items.GetListBoxItem (i);
2166 indices.Add (item.Index);
2170 #endregion Private Methods
2174 SelectedObjectCollection
2176 public class SelectedObjectCollection : IList, ICollection, IEnumerable
2178 private ListBox owner;
2179 private ArrayList object_items = new ArrayList ();
2181 public SelectedObjectCollection (ListBox owner)
2186 #region Public Properties
2187 public virtual int Count {
2188 get { return object_items.Count; }
2191 public virtual bool IsReadOnly {
2192 get { return true; }
2196 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
2197 public virtual object this [int index] {
2199 if (index < 0 || index >= Count)
2200 throw new ArgumentOutOfRangeException ("Index of out range");
2202 return object_items[index];
2204 set {throw new NotSupportedException ();}
2207 bool ICollection.IsSynchronized {
2208 get { return true; }
2211 object ICollection.SyncRoot {
2212 get { return this; }
2215 bool IList.IsFixedSize {
2216 get { return true; }
2219 object IList.this[int index] {
2220 get { return object_items[index]; }
2221 set { throw new NotSupportedException (); }
2224 #endregion Public Properties
2226 #region Public Methods
2227 public virtual bool Contains (object selectedObject)
2229 return object_items.Contains (selectedObject);
2232 public virtual void CopyTo (Array dest, int index)
2234 object_items.CopyTo (dest, index);
2237 int IList.Add (object value)
2239 throw new NotSupportedException ();
2244 throw new NotSupportedException ();
2247 bool IList.Contains (object selectedIndex)
2249 throw new NotImplementedException ();
2252 void IList.Insert (int index, object value)
2254 throw new NotSupportedException ();
2257 void IList.Remove (object value)
2259 throw new NotSupportedException ();
2262 void IList.RemoveAt (int index)
2264 throw new NotSupportedException ();
2267 public int IndexOf (object item)
2269 return object_items.IndexOf (item);
2272 public virtual IEnumerator GetEnumerator ()
2274 return object_items.GetEnumerator ();
2277 #endregion Public Methods
2279 #region Private Methods
2280 internal void AddObject (object obj)
2282 object_items.Add (obj);
2285 internal void ClearObjects ()
2287 object_items.Clear ();
2290 internal void ReCreate ()
2292 object_items.Clear ();
2294 for (int i = 0; i < owner.Items.Count; i++) {
2295 ListBox.ListBoxItem item = owner.Items.GetListBoxItem (i);
2298 object_items.Add (owner.Items[item.Index]);
2302 internal void RemoveObject (object obj)
2304 object_items.Remove (obj);
2307 #endregion Private Methods