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. (http://www.novell.com)
23 // Ravindra (rkumar@novell.com)
26 // - Keys to be handled ENTER/PAGE UP/PAGE DOWN/HOME/END/ARROWS/CTRL/SHIFT
27 // - Item text editing
28 // - Column resizing/reodering
29 // - Feedback for item activation, change in cursor types as mouse moves.
36 using System.Collections;
37 using System.ComponentModel;
38 using System.ComponentModel.Design;
40 using System.Runtime.InteropServices;
42 namespace System.Windows.Forms
44 [DefaultEvent ("SelectedIndexChanged")]
45 [DefaultProperty ("Items")]
46 [Designer ("System.Windows.Forms.Design.ListViewDesigner, " + Consts.AssemblySystem_Design, (string)null)]
47 public class ListView : Control
49 private ItemActivation activation = ItemActivation.Standard;
50 private ListViewAlignment alignment = ListViewAlignment.Top;
51 private bool allow_column_reorder = false;
52 private bool auto_arrange = true;
53 private bool check_boxes = false;
54 private CheckedIndexCollection checked_indices;
55 private CheckedListViewItemCollection checked_items;
56 private ColumnHeader clicked_column;
57 private ListViewItem clicked_item;
58 private ListViewItem last_clicked_item;
59 private ColumnHeaderCollection columns;
60 private bool ctrl_pressed;
61 private bool shift_pressed;
62 private bool draw_headers = true; // Used for painting. Do we need to draw column headers ?
63 private ListViewItem focused_item;
64 private bool full_row_select = false;
65 private bool grid_lines = false;
66 private ColumnHeaderStyle header_style = ColumnHeaderStyle.Clickable;
67 private bool hide_selection = true;
68 private bool hover_selection = false;
69 private IComparer item_sorter;
70 private ListViewItemCollection items;
71 private bool label_edit = false;
72 private bool label_wrap = true;
73 private bool multiselect = true;
74 private bool redraw = true;
75 private bool scrollable = true;
76 private SelectedIndexCollection selected_indices;
77 private SelectedListViewItemCollection selected_items;
78 private SortOrder sort_order = SortOrder.None;
79 private ImageList state_image_list;
80 private bool updating = false;
81 private View view = View.LargeIcon;
82 private int layout_wd; // We might draw more than our client area
83 private int layout_ht; // therefore we need to have these two.
84 //private TextBox editor; // Used for editing an item text
85 private ScrollBar h_scroll; // used for scrolling horizontally
86 private ScrollBar v_scroll; // used for scrolling vertically
87 private int h_marker; // Position markers for scrolling
91 internal ImageList large_image_list;
92 internal ImageList small_image_list;
93 internal Size text_size = Size.Empty;
96 public event LabelEditEventHandler AfterLabelEdit;
99 [EditorBrowsable (EditorBrowsableState.Never)]
100 public new event EventHandler BackgroundImageChanged;
102 public event LabelEditEventHandler BeforeLabelEdit;
103 public event ColumnClickEventHandler ColumnClick;
104 public event EventHandler ItemActivate;
105 public event ItemCheckEventHandler ItemCheck;
106 public event ItemDragEventHandler ItemDrag;
109 [EditorBrowsable (EditorBrowsableState.Never)]
110 public new event PaintEventHandler Paint;
112 public event EventHandler SelectedIndexChanged;
115 [EditorBrowsable (EditorBrowsableState.Never)]
116 public new event EventHandler TextChanged;
119 #region Public Constructors
122 background_color = ThemeEngine.Current.ColorWindow;
123 checked_indices = new CheckedIndexCollection (this);
124 checked_items = new CheckedListViewItemCollection (this);
125 columns = new ColumnHeaderCollection (this);
126 foreground_color = SystemColors.WindowText;
127 items = new ListViewItemCollection (this);
128 selected_indices = new SelectedIndexCollection (this);
129 selected_items = new SelectedListViewItemCollection (this);
131 border_style = BorderStyle.Fixed3D;
133 // we are mostly scrollable
134 h_scroll = new HScrollBar ();
135 v_scroll = new VScrollBar ();
136 h_marker = v_marker = 0;
138 // scroll bars are disabled initially
139 h_scroll.Visible = false;
140 h_scroll.ValueChanged += new EventHandler(HorizontalScroller);
141 v_scroll.Visible = false;
142 v_scroll.ValueChanged += new EventHandler(VerticalScroller);
145 base.DoubleClick += new EventHandler(ListView_DoubleClick);
146 base.KeyDown += new KeyEventHandler(ListView_KeyDown);
147 base.KeyUp += new KeyEventHandler(ListView_KeyUp);
148 base.MouseDown += new MouseEventHandler(ListView_MouseDown);
149 base.MouseHover += new EventHandler(ListView_MouseHover);
150 base.MouseUp += new MouseEventHandler(ListView_MouseUp);
151 base.MouseMove += new MouseEventHandler(ListView_MouseMove);
152 base.Paint += new PaintEventHandler (ListView_Paint);
154 #endregion // Public Constructors
156 #region Private Internal Properties
157 internal Size CheckBoxSize {
159 if (this.check_boxes) {
160 if (this.state_image_list != null)
161 return this.state_image_list.ImageSize;
163 return ThemeEngine.Current.ListViewCheckBoxSize;
169 internal bool CanMultiselect {
171 if (this.multiselect &&
172 (this.ctrl_pressed || this.shift_pressed))
178 #endregion // Private Internal Properties
180 #region Protected Properties
181 protected override CreateParams CreateParams {
182 get { return base.CreateParams; }
185 protected override Size DefaultSize {
186 get { return ThemeEngine.Current.ListViewDefaultSize; }
188 #endregion // Protected Properties
190 #region Public Instance Properties
191 [DefaultValue (ItemActivation.Standard)]
192 public ItemActivation Activation {
193 get { return activation; }
194 set { activation = value; }
197 [DefaultValue (ListViewAlignment.Top)]
199 public ListViewAlignment Alignment {
200 get { return alignment; }
202 if (this.alignment != value) {
204 // alignment does not matter in Details/List views
205 if (this.view == View.LargeIcon ||
206 this.View == View.SmallIcon)
212 [DefaultValue (false)]
213 public bool AllowColumnReorder {
214 get { return allow_column_reorder; }
216 if (this.allow_column_reorder != value) {
217 allow_column_reorder = value;
218 // column reorder does not matter in Details view
219 if (this.view != View.Details)
225 [DefaultValue (true)]
226 public bool AutoArrange {
227 get { return auto_arrange; }
229 if (auto_arrange != value) {
230 auto_arrange = value;
231 // autoarrange does not matter in Details/List views
232 if (this.view == View.LargeIcon || this.View == View.SmallIcon)
238 public override Color BackColor {
240 if (background_color.IsEmpty)
241 return ThemeEngine.Current.ColorWindow;
243 return background_color;
245 set { background_color = value; }
249 [EditorBrowsable (EditorBrowsableState.Never)]
250 public override Image BackgroundImage {
251 get { return background_image; }
253 if (value == background_image)
256 background_image = value;
257 if (BackgroundImageChanged != null)
258 BackgroundImageChanged (this, new EventArgs ());
262 [DefaultValue (BorderStyle.Fixed3D)]
264 public BorderStyle BorderStyle {
265 get { return border_style; }
267 if (border_style != value) {
268 border_style = value;
274 [DefaultValue (false)]
275 public bool CheckBoxes {
276 get { return check_boxes; }
278 if (check_boxes != value) {
286 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
287 public CheckedIndexCollection CheckedIndices {
288 get { return checked_indices; }
292 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
293 public CheckedListViewItemCollection CheckedItems {
294 get { return checked_items; }
297 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
299 [MergableProperty (false)]
300 public ColumnHeaderCollection Columns {
301 get { return columns; }
305 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
306 public ListViewItem FocusedItem {
307 get { return focused_item; }
310 public override Color ForeColor {
312 if (foreground_color.IsEmpty)
313 return ThemeEngine.Current.ColorWindowText;
315 return foreground_color;
317 set { foreground_color = value; }
320 [DefaultValue (false)]
321 public bool FullRowSelect {
322 get { return full_row_select; }
323 set { full_row_select = value; }
326 [DefaultValue (false)]
327 public bool GridLines {
328 get { return grid_lines; }
330 if (grid_lines != value) {
337 [DefaultValue (ColumnHeaderStyle.Clickable)]
338 public ColumnHeaderStyle HeaderStyle {
339 get { return header_style; }
341 if (header_style != value) {
342 header_style = value;
343 // header style matters only in Details view
344 if (this.view == View.Details)
350 [DefaultValue (true)]
351 public bool HideSelection {
352 get { return hide_selection; }
354 if (hide_selection != value) {
355 hide_selection = value;
361 [DefaultValue (false)]
362 public bool HoverSelection {
363 get { return hover_selection; }
364 set { hover_selection = value; }
367 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
369 [MergableProperty (false)]
370 public ListViewItemCollection Items {
371 get { return items; }
374 [DefaultValue (false)]
375 public bool LabelEdit {
376 get { return label_edit; }
377 set { label_edit = value; }
380 [DefaultValue (true)]
382 public bool LabelWrap {
383 get { return label_wrap; }
385 if (label_wrap != value) {
392 [DefaultValue (null)]
393 public ImageList LargeImageList {
394 get { return large_image_list; }
396 large_image_list = value;
402 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
403 public IComparer ListViewItemSorter {
404 get { return item_sorter; }
405 set { item_sorter = value; }
408 [DefaultValue (true)]
409 public bool MultiSelect {
410 get { return multiselect; }
411 set { multiselect = value; }
414 [DefaultValue (true)]
415 public bool Scrollable {
416 get { return scrollable; }
418 if (scrollable != value) {
426 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
427 public SelectedIndexCollection SelectedIndices {
428 get { return selected_indices; }
432 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
433 public SelectedListViewItemCollection SelectedItems {
434 get { return selected_items; }
437 [DefaultValue (null)]
438 public ImageList SmallImageList {
439 get { return small_image_list; }
441 small_image_list = value;
446 [DefaultValue (SortOrder.None)]
447 public SortOrder Sorting {
448 get { return sort_order; }
449 set { sort_order = value; }
452 [DefaultValue (null)]
453 public ImageList StateImageList {
454 get { return state_image_list; }
456 state_image_list = value;
463 [EditorBrowsable (EditorBrowsableState.Never)]
464 public override string Text {
473 if (TextChanged != null)
474 TextChanged (this, new EventArgs ());
479 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
480 public ListViewItem TopItem {
483 if (this.items.Count == 0)
485 // if contents are not scrolled
486 // it is the first item
487 else if (h_marker == 0 && v_marker == 0)
488 return this.items [0];
489 // do a hit test for the scrolled position
491 foreach (ListViewItem item in this.items) {
492 if (item.EntireRect.Contains (h_marker, v_marker))
500 [DefaultValue (View.LargeIcon)]
503 set { view = value; }
505 #endregion // Public Instance Properties
507 #region Internal Methods Properties
508 internal int TotalWidth {
509 get { return Math.Max (this.Width, this.layout_wd); }
512 internal int TotalHeight {
513 get { return Math.Max (this.Height, this.layout_ht); }
516 internal void Redraw (bool recalculate)
518 // Avoid calculations when control is being updated
523 CalculateListView (this.alignment);
529 internal Size GetChildColumnSize (int index)
531 Size ret_size = Size.Empty;
532 ColumnHeader col = this.columns [index];
534 if (col.Width == -2) { // autosize = max(items, columnheader)
535 Size size = Size.Ceiling (this.DeviceContext.MeasureString
536 (col.Text, this.Font));
537 ret_size = BiggestItem (index);
538 if (size.Width > ret_size.Width)
541 else { // -1 and all the values < -2 are put under one category
542 ret_size = BiggestItem (index);
543 // fall back to empty columns' width if no subitem is available for a column
544 if (ret_size.IsEmpty) {
545 ret_size.Width = ThemeEngine.Current.ListViewEmptyColumnWidth;
546 if (col.Text.Length > 0)
547 ret_size.Height = Size.Ceiling (this.DeviceContext.MeasureString
548 (col.Text, this.Font)).Height;
550 ret_size.Height = this.Font.Height;
554 // adjust the size for icon and checkbox for 0th column
556 ret_size.Width += (this.CheckBoxSize.Width + 4);
557 if (this.small_image_list != null)
558 ret_size.Width += this.small_image_list.ImageSize.Width;
563 // Returns the size of biggest item text in a column.
564 private Size BiggestItem (int col)
566 Size temp = Size.Empty;
567 Size ret_size = Size.Empty;
569 // 0th column holds the item text, we check the size of
570 // the various subitems falling in that column and get
571 // the biggest one's size.
572 foreach (ListViewItem item in items) {
573 if (col >= item.SubItems.Count)
576 temp = Size.Ceiling (this.DeviceContext.MeasureString
577 (item.SubItems [col].Text, this.Font));
578 if (temp.Width > ret_size.Width)
582 // adjustment for space
583 if (!ret_size.IsEmpty)
589 // Sets the size of the biggest item text as per the view
590 private void CalcTextSize ()
592 // clear the old value
593 text_size = Size.Empty;
595 if (items.Count == 0)
598 text_size = BiggestItem (0);
600 if (view == View.LargeIcon && this.label_wrap) {
601 Size temp = Size.Empty;
602 if (this.check_boxes)
603 temp.Width += 2 * this.CheckBoxSize.Width;
604 if (large_image_list != null)
605 temp.Width += large_image_list.ImageSize.Width;
608 // wrapping is done for two lines only
609 if (text_size.Width > temp.Width) {
610 text_size.Width = temp.Width;
611 text_size.Height *= 2;
614 else if (view == View.List) {
615 // in list view max text shown in determined by the
616 // control width, even if scolling is enabled.
617 int max_wd = this.Width - (this.CheckBoxSize.Width - 2);
618 if (this.small_image_list != null)
619 max_wd -= this.small_image_list.ImageSize.Width;
621 if (text_size.Width > max_wd)
622 text_size.Width = max_wd;
625 // we do the default settings, if we have got 0's
626 if (text_size.Height <= 0)
627 text_size.Height = this.Font.Height;
628 if (text_size.Width <= 0)
629 text_size.Width = this.Width;
632 text_size.Width += 4;
633 text_size.Height += 2;
636 // Sets the location of every item on
637 // the ListView as per the view
638 private void CalculateListView (ListViewAlignment align)
640 int current_pos_x = 0; // our x-position marker
641 int current_pos_y = 0; // our y-position marker
644 int max; // max x_pos or y_pos depending on the alignment
645 int current = 0; // current row or column
646 int vertical_spacing = ThemeEngine.Current.ListViewVerticalSpacing;
647 int horizontal_spacing = ThemeEngine.Current.ListViewHorizontalSpacing;
654 // ColumnHeaders are not drawn if headerstyle is none
655 int ht = (this.header_style == ColumnHeaderStyle.None) ?
656 2 : this.Font.Height + 2;
657 if (columns.Count > 0) {
658 foreach (ColumnHeader col in columns) {
659 col.X = current_pos_x;
661 col.CalcColumnHeader ();
662 current_pos_x += col.Wd;
664 this.layout_wd = current_pos_x;
666 // set the position marker for placing items
670 if (items.Count > 0) {
671 foreach (ListViewItem item in items) {
673 item.location.Y = current_pos_y;
674 item.CalcListViewItem ();
675 current_pos_y += item.EntireRect.Height;
677 this.layout_ht = current_pos_y;
679 // some space for bottom gridline
686 vertical_spacing = 0;
687 horizontal_spacing = 0;
688 goto case View.LargeIcon;
691 if (items.Count > 0) {
692 items [0].CalcListViewItem ();
693 item_ht = items [0].EntireRect.Height;
694 item_wd = items [0].EntireRect.Width;
696 // top (default) and snaptogrid alignments are handled same way
697 if (align == ListViewAlignment.Left) {
699 foreach (ListViewItem item in items) {
700 item.location.X = current_pos_x +
702 item.location.Y = current_pos_y;
703 item.CalcListViewItem ();
704 current_pos_y += item_ht;
706 current ++; // just to know about the last element
707 // we just did the last item
708 if (current == items.Count) {
709 if (max < current_pos_y)
711 current_pos_x = item.EntireRect.Right;
715 // is there enough space for another row ?
716 if ((current_pos_y + vertical_spacing
717 + item_ht) <= this.Height)
718 current_pos_y += vertical_spacing;
720 // start another column
721 // make current_pos_y as the
722 // max value and reset
723 // current_pos_y value.
725 current_pos_x += item_wd;
730 // adjust the layout dimensions
731 this.layout_ht = max;
732 this.layout_wd = current_pos_x;
734 else { // other default/top alignment
736 foreach (ListViewItem item in items) {
737 item.location.X = current_pos_x +
740 item.location.Y = current_pos_y;
741 item.CalcListViewItem ();
742 current_pos_x += item_wd;
744 current ++; // just to know about the last element
745 // we just did the last item
746 if (current == items.Count) {
747 if (max < current_pos_x)
749 current_pos_y = item.EntireRect.Bottom;
753 // is there enough space for another column?
754 if ((current_pos_x + horizontal_spacing
755 + item_wd) <= this.Width)
759 // make current_pos_x as the
760 // max value and reset
761 // current_pos_x value.
763 current_pos_y += (item_ht +
769 // adjust the layout dimensions
770 this.layout_wd = max;
771 this.layout_ht = current_pos_y;
777 if (items.Count > 0) {
778 items [0].CalcListViewItem ();
779 item_ht = items [0].EntireRect.Height;
780 item_wd = items [0].EntireRect.Width;
782 max = this.Height / item_ht;
784 max = 1; // we draw at least one row
786 foreach (ListViewItem item in items) {
787 item.location.X = current_pos_x;
788 item.location.Y = current_pos_y;
789 item.CalcListViewItem ();
791 if (current == max) {
792 current_pos_x += item_wd;
797 current_pos_y += item_ht;
800 // adjust the layout dimensions
801 this.layout_ht = max * item_ht;
802 if (current == 0) // we have fully filled layout
803 this.layout_wd = current_pos_x;
805 this.layout_wd = current_pos_x + item_wd;
810 if (this.scrollable && this.items.Count > 0) {
811 // making a scroll bar visible might make
812 // other scroll bar visible
813 if (this.layout_wd > this.Width) {
814 this.h_scroll.Visible = true;
815 if ((this.layout_ht + this.h_scroll.Height) > this.Height)
816 this.v_scroll.Visible = true;
818 else if (this.layout_ht > this.Height) {
819 this.v_scroll.Visible = true;
820 if ((this.layout_wd + this.v_scroll.Width) > this.Width)
821 this.h_scroll.Visible = true;
824 // create big enough buffers
825 if (this.layout_wd > this.Width ||
826 this.layout_ht > this.Height)
827 this.CreateBuffers (this.TotalWidth, this.TotalHeight);
829 if (this.h_scroll.Visible) {
830 this.h_scroll.Location = new Point (0, this.Height
831 - this.h_scroll.Height);
833 this.h_scroll.Minimum = 0;
835 // if v_scroll is visible, adjust the maximum of the
836 // h_scroll to account for the width of v_scroll
837 if (this.v_scroll.Visible) {
838 this.h_scroll.Maximum = this.layout_wd + this.v_scroll.Width;
839 this.h_scroll.Width = this.Width - this.v_scroll.Width;
842 this.h_scroll.Maximum = this.layout_wd;
843 this.h_scroll.Width = this.Width;
846 this.h_scroll.LargeChange = this.Width;
847 this.h_scroll.SmallChange = this.Font.Height;
850 // vertical scrollbar
851 if (this.v_scroll.Visible) {
852 this.v_scroll.Location = new Point (this.Width
853 - this.v_scroll.Width, 0);
855 this.v_scroll.Minimum = 0;
857 // if h_scroll is visible, adjust the maximum of the
858 // v_scroll to account for the height of h_scroll
859 if (this.h_scroll.Visible) {
860 this.v_scroll.Maximum = this.layout_ht + this.h_scroll.Height;
861 this.v_scroll.Height = this.Height - this.h_scroll.Height;
864 this.v_scroll.Maximum = this.layout_ht;
865 this.v_scroll.Height = this.Height;
868 this.v_scroll.LargeChange = this.Height;
869 this.v_scroll.SmallChange = this.Font.Height;
873 this.h_scroll.Visible = false;
874 this.v_scroll.Visible = false;
879 private void ListView_DoubleClick (object sender, EventArgs e)
881 if (this.activation == ItemActivation.Standard
882 && this.ItemActivate != null)
883 this.ItemActivate (this, e);
886 private void ListView_KeyDown (object sender, KeyEventArgs ke)
894 switch (ke.KeyCode) {
896 case Keys.ControlKey:
897 this.ctrl_pressed = true;
905 this.v_scroll.Value = this.v_scroll.Maximum;
909 this.v_scroll.Value = this.v_scroll.Minimum;
914 if (this.last_clicked_item != null)
915 index = this.last_clicked_item.Index;
922 this.last_clicked_item = this.items [index];
923 this.last_clicked_item.Selected = true;
924 this.EnsureVisible (index);
928 if (this.last_clicked_item != null)
929 index = this.last_clicked_item.Index + 1;
933 if (index == this.items.Count)
936 this.last_clicked_item = this.items [index];
937 this.last_clicked_item.Selected = true;
938 this.EnsureVisible (index);
942 this.shift_pressed = true;
955 private void ListView_KeyUp (object sender, KeyEventArgs ke)
958 if (ke.KeyCode == Keys.ControlKey)
959 this.ctrl_pressed = false;
961 if (ke.KeyCode == Keys.ShiftKey)
962 this.shift_pressed = false;
967 private void ListView_MouseDown (object sender, MouseEventArgs me)
969 if (items.Count == 0)
972 Point hit = Point.Empty;
973 if (this.HeaderStyle != ColumnHeaderStyle.None) {
974 // take horizontal scrolling into account
975 hit = new Point (me.X + h_marker, me.Y);
977 // hit test on columns
978 if (this.view == View.Details && this.columns.Count > 0) {
979 foreach (ColumnHeader col in this.columns) {
980 if (col.Rect.Contains (hit)) {
981 this.clicked_column = col;
987 if (this.clicked_column != null) {
988 this.clicked_column.pressed = true;
989 this.draw_headers = true;
997 // we need to take scrolling into account
998 hit = new Point (me.X + h_marker, me.Y + v_marker);
999 foreach (ListViewItem item in this.items) {
1000 if (item.CheckRect.Contains (hit)) {
1001 CheckState curr_state = item.Checked ?
1002 CheckState.Checked : CheckState.Unchecked;
1004 item.Checked = false;
1006 item.Checked = true;
1008 CheckState new_state = item.Checked ?
1009 CheckState.Checked : CheckState.Unchecked;
1010 this.Redraw (false);
1012 // Raise the ItemCheck event
1013 ItemCheckEventArgs ice = new ItemCheckEventArgs (item.Index,
1016 this.OnItemCheck (ice);
1020 if (this.view == View.Details &&
1021 this.FullRowSelect == false) {
1022 if (item.LabelRect.Contains (hit)) {
1023 this.clicked_item = item;
1028 if (item.EntireRect.Contains (hit)) {
1029 this.clicked_item = item;
1035 if (this.clicked_item != null) {
1036 this.clicked_item.Selected = true;
1038 this.OnSelectedIndexChanged (new EventArgs ());
1040 this.Redraw (false);
1043 // set the FocusedItem to be the current clicked_item
1044 this.focused_item = this.clicked_item;
1047 private void ListView_MouseHover (object sender, EventArgs e)
1049 // handle the hover events only when the mouse
1051 if (this.hover_selection == false || this.Capture)
1054 // hit test for the items
1055 Point hit = this.PointToClient (Control.MousePosition);
1056 ListViewItem item = this.GetItemAt (hit.X, hit.Y);
1059 item.Selected = true;
1061 this.OnSelectedIndexChanged (new EventArgs ());
1063 this.Redraw (false);
1067 private void ListView_MouseMove (object sender, MouseEventArgs me)
1069 // Column header is always at the top. It can
1070 // scroll only horizontally. So, we have to take
1071 // only horizontal scrolling into account
1072 Point hit = new Point (me.X + h_marker, me.Y);
1074 // non-null clicked_col means mouse down has happened
1076 if (this.clicked_column != null) {
1077 if (this.clicked_column.pressed == false &&
1078 this.clicked_column.Rect.Contains (hit)) {
1079 this.clicked_column.pressed = true;
1080 this.draw_headers = true;
1081 this.Redraw (false);
1083 else if (this.clicked_column.pressed &&
1084 ! this.clicked_column.Rect.Contains (hit)) {
1085 this.clicked_column.pressed = false;
1086 this.draw_headers = true;
1087 this.Redraw (false);
1092 private void ListView_MouseUp (object sender, MouseEventArgs me)
1094 this.Capture = false;
1095 if (items.Count == 0)
1098 Point hit = new Point (me.X, me.Y);
1100 if (this.clicked_column != null) {
1101 if (this.clicked_column.pressed) {
1102 this.clicked_column.pressed = false;
1103 this.draw_headers = true;
1104 this.Redraw (false);
1106 // Raise the ColumnClick event
1107 this.OnColumnClick (new ColumnClickEventArgs
1108 (this.clicked_column.Index));
1112 // Raise the ItemActivate event
1113 Rectangle rect = Rectangle.Empty;
1114 if (this.clicked_item != null) {
1115 if (this.view == View.Details && !this.full_row_select)
1116 rect = this.clicked_item.LabelRect;
1118 rect = this.clicked_item.EntireRect;
1120 // We handle double click in a separate handler
1121 if (this.activation != ItemActivation.Standard &&
1122 rect.Contains (hit)) {
1123 if (this.activation == ItemActivation.OneClick)
1124 this.ItemActivate (this, EventArgs.Empty);
1126 // ItemActivate is raised on the second click on the same item
1127 else if (this.activation == ItemActivation.TwoClick) {
1128 if (this.last_clicked_item == this.clicked_item) {
1129 this.ItemActivate (this, EventArgs.Empty);
1130 this.last_clicked_item = null;
1133 this.last_clicked_item = this.clicked_item;
1138 this.clicked_column = null;
1139 this.clicked_item = null;
1142 private void ListView_Paint (object sender, PaintEventArgs pe)
1144 if (this.Width <= 0 || this.Height <= 0 ||
1145 this.Visible == false || this.updating == true)
1149 ThemeEngine.Current.DrawListView (this.DeviceContext,
1150 pe.ClipRectangle, this);
1154 // We paint on the screen as per the location set
1155 // by the two scrollbars. In case of details view
1156 // since column headers can scroll only horizontally
1157 // and items can scroll in both directions, paiting is
1158 // done separtely for the column header and the items.
1160 Rectangle srcRect = this.ClientRectangle;
1161 Rectangle dstRect = this.ClientRectangle;
1163 // set the visible starting point
1165 srcRect.X += h_marker;
1166 srcRect.Y += v_marker;
1168 if (h_scroll.Visible) {
1169 srcRect.Height -= h_scroll.Height;
1170 dstRect.Height -= h_scroll.Height;
1173 if (v_scroll.Visible) {
1174 srcRect.Width -= v_scroll.Width;
1175 dstRect.Width -= v_scroll.Width;
1179 // We paint the column headers always at the top, in case
1180 // of vertical scrolling. Therefore, we advance the painting
1181 // by the amount equal to the column height.
1182 if (this.view == View.Details &&
1183 this.Columns.Count > 0 &&
1184 this.header_style != ColumnHeaderStyle.None &&
1187 int col_ht = this.Columns [0].Ht;
1189 if (this.draw_headers) {
1190 this.draw_headers = false;
1191 // Move the source rect by the amount of horizontal
1192 // scrolling done so far.
1193 Rectangle headerSrc = new Rectangle (h_marker, 0,
1194 srcRect.Width, col_ht);
1195 // dest rect is always stable at 0,0
1196 Rectangle headerDst = new Rectangle (0, 0, srcRect.Width, col_ht);
1197 pe.Graphics.DrawImage (this.ImageBuffer, headerDst,
1198 headerSrc, GraphicsUnit.Pixel);
1201 dstRect.Y += col_ht;
1202 srcRect.Y += col_ht;
1206 pe.Graphics.DrawImage (this.ImageBuffer, dstRect,
1207 srcRect, GraphicsUnit.Pixel);
1209 // Draw the border of the list view
1210 // The border is painted here separately, because
1211 // our imagebuffer might be scrollable
1212 ThemeEngine.Current.CPDrawBorderStyle (pe.Graphics,
1213 this.ClientRectangle,
1216 // Raise the Paint event
1221 private void HorizontalScroller (object sender, EventArgs e)
1223 // Avoid unnecessary flickering, when button is
1224 // kept pressed at the end
1225 if (h_marker != h_scroll.Value) {
1226 h_marker = h_scroll.Value;
1227 // draw the headers again
1228 this.draw_headers = true;
1233 private void VerticalScroller (object sender, EventArgs e)
1235 // Avoid unnecessary flickering, when button is
1236 // kept pressed at the end
1237 if (v_marker != v_scroll.Value) {
1238 v_marker = v_scroll.Value;
1242 #endregion // Internal Methods Properties
1244 #region Protected Methods
1245 protected override void CreateHandle ()
1247 base.CreateHandle ();
1250 protected override void Dispose (bool disposing)
1255 protected override bool IsInputKey (Keys keyData)
1257 return base.IsInputKey (keyData);
1260 protected virtual void OnAfterLabelEdit (LabelEditEventArgs e)
1262 if (AfterLabelEdit != null)
1263 AfterLabelEdit (this, e);
1266 protected virtual void OnBeforeLabelEdit (LabelEditEventArgs e)
1268 if (BeforeLabelEdit != null)
1269 BeforeLabelEdit (this, e);
1272 protected virtual void OnColumnClick (ColumnClickEventArgs e)
1274 if (ColumnClick != null)
1275 ColumnClick (this, e);
1278 protected override void OnEnabledChanged (EventArgs e)
1280 base.OnEnabledChanged (e);
1283 protected override void OnFontChanged (EventArgs e)
1285 base.OnFontChanged (e);
1288 protected override void OnHandleCreated (EventArgs e)
1290 base.OnHandleCreated (e);
1291 this.Controls.Add (this.v_scroll);
1292 this.Controls.Add (this.h_scroll);
1293 this.SetStyle (ControlStyles.UserPaint |
1294 ControlStyles.AllPaintingInWmPaint, true);
1297 protected override void OnHandleDestroyed (EventArgs e)
1299 base.OnHandleDestroyed (e);
1302 protected virtual void OnItemActivate (EventArgs e)
1304 if (ItemActivate != null)
1305 ItemActivate (this, e);
1308 protected virtual void OnItemCheck (ItemCheckEventArgs ice)
1310 if (ItemCheck != null)
1311 ItemCheck (this, ice);
1314 protected virtual void OnItemDrag (ItemDragEventArgs e)
1316 if (ItemDrag != null)
1320 protected virtual void OnSelectedIndexChanged (EventArgs e)
1322 if (SelectedIndexChanged != null)
1323 SelectedIndexChanged (this, e);
1326 protected override void OnSystemColorsChanged (EventArgs e)
1328 base.OnSystemColorsChanged (e);
1331 protected void RealizeProperties ()
1336 protected void UpdateExtendedStyles ()
1341 protected override void WndProc (ref Message m)
1343 base.WndProc (ref m);
1345 #endregion // Protected Methods
1347 #region Public Instance Methods
1348 public void ArrangeIcons ()
1350 ArrangeIcons (this.alignment);
1353 public void ArrangeIcons (ListViewAlignment alignment)
1355 // Icons are arranged only if view is set to LargeIcon or SmallIcon
1356 if (view == View.LargeIcon || view == View.SmallIcon) {
1357 this.CalculateListView (alignment);
1358 // we have done the calculations already
1359 this.Redraw (false);
1363 public void BeginUpdate ()
1365 // flag to avoid painting
1369 public void Clear ()
1376 public void EndUpdate ()
1378 // flag to avoid painting
1381 // probably, now we need a redraw with recalculations
1385 public void EnsureVisible (int index)
1387 if (index < 0 || index >= this.items.Count || this.scrollable == false)
1390 // dimensions of visible area
1391 int view_wd = this.Width - (this.v_scroll.Visible ? this.v_scroll.Width : 0);
1392 int view_ht = this.Height - (this.h_scroll.Visible ? this.h_scroll.Height : 0);
1393 // visible area is decided by the h_marker and v_marker
1394 Rectangle view_rect = new Rectangle (h_marker, v_marker, view_wd, view_ht);
1396 // an item's bounding rect
1397 Rectangle rect = this.items [index].EntireRect;
1399 // we don't need to do anything if item is visible.
1400 // visible area is represented by (0,0,view_wd,view_ht)
1401 if (view_rect.Contains (rect))
1404 // Scroll Left or Up
1405 if ((rect.Left < view_rect.Left) || (rect.Top < view_rect.Top)) {
1406 if (rect.Left < view_rect.Left)
1407 this.h_scroll.Value -= (view_rect.Left - rect.Left);
1408 if (rect.Top < view_rect.Top)
1409 this.v_scroll.Value -= (view_rect.Top - rect.Top);
1411 // Scroll Right or Down
1413 if (rect.Right > view_rect.Right)
1414 this.h_scroll.Value += (rect.Right - view_rect.Right);
1415 if (rect.Bottom > view_rect.Bottom)
1416 this.v_scroll.Value += (rect.Bottom - view_rect.Bottom);
1420 public ListViewItem GetItemAt (int x, int y)
1422 foreach (ListViewItem item in items) {
1423 if (item.Bounds.Contains (x, y))
1429 public Rectangle GetItemRect (int index)
1431 return GetItemRect (index, ItemBoundsPortion.Entire);
1434 public Rectangle GetItemRect (int index, ItemBoundsPortion portion)
1436 if (index < 0 || index >= items.Count)
1437 throw new IndexOutOfRangeException ("Invalid Index");
1439 return items [index].GetBounds (portion);
1444 if (sort_order != SortOrder.None)
1445 items.list.Sort (item_sorter);
1447 if (sort_order == SortOrder.Descending)
1448 items.list.Reverse ();
1453 public override string ToString ()
1455 int count = this.Items.Count;
1458 return string.Format ("System.Windows.Forms.ListView, Items.Count: 0");
1460 return string.Format ("System.Windows.Forms.ListView, Items.Count: {0}, Items[0]: {1}", count, this.Items [0].ToString ());
1462 #endregion // Public Instance Methods
1466 public class CheckedIndexCollection : IList, ICollection, IEnumerable
1468 internal ArrayList list;
1469 private ListView owner;
1471 #region Public Constructor
1472 public CheckedIndexCollection (ListView owner)
1474 list = new ArrayList ();
1477 #endregion // Public Constructor
1479 #region Public Properties
1481 public virtual int Count {
1482 get { return list.Count; }
1485 public virtual bool IsReadOnly {
1486 get { return true; }
1489 public int this [int index] {
1491 if (index < 0 || index >= list.Count)
1492 throw new ArgumentOutOfRangeException ("Index out of range.");
1493 return (int) list [index];
1497 bool ICollection.IsSynchronized {
1498 get { return list.IsSynchronized; }
1501 object ICollection.SyncRoot {
1502 get { return list.SyncRoot; }
1505 bool IList.IsFixedSize {
1506 get { return list.IsFixedSize; }
1509 object IList.this [int index] {
1510 get { return this [index]; }
1511 set { throw new NotSupportedException ("SetItem operation is not supported."); }
1513 #endregion // Public Properties
1515 #region Public Methods
1516 public bool Contains (int checkedIndex)
1518 return list.Contains (checkedIndex);
1521 public virtual IEnumerator GetEnumerator ()
1523 return list.GetEnumerator ();
1526 void ICollection.CopyTo (Array dest, int index)
1528 list.CopyTo (dest, index);
1531 int IList.Add (object value)
1533 throw new NotSupportedException ("Add operation is not supported.");
1538 throw new NotSupportedException ("Clear operation is not supported.");
1541 bool IList.Contains (object checkedIndex)
1543 return list.Contains (checkedIndex);
1546 int IList.IndexOf (object checkedIndex)
1548 return list.IndexOf (checkedIndex);
1551 void IList.Insert (int index, object value)
1553 throw new NotSupportedException ("Insert operation is not supported.");
1556 void IList.Remove (object value)
1558 throw new NotSupportedException ("Remove operation is not supported.");
1561 void IList.RemoveAt (int index)
1563 throw new NotSupportedException ("RemoveAt operation is not supported.");
1566 public int IndexOf (int checkedIndex)
1568 return list.IndexOf (checkedIndex);
1570 #endregion // Public Methods
1572 } // CheckedIndexCollection
1574 public class CheckedListViewItemCollection : IList, ICollection, IEnumerable
1576 internal ArrayList list;
1577 private ListView owner;
1579 #region Public Constructor
1580 public CheckedListViewItemCollection (ListView owner)
1582 list = new ArrayList ();
1585 #endregion // Public Constructor
1587 #region Public Properties
1589 public virtual int Count {
1590 get { return list.Count; }
1593 public virtual bool IsReadOnly {
1594 get { return true; }
1597 public ListViewItem this [int index] {
1599 if (index < 0 || index >= list.Count)
1600 throw new ArgumentOutOfRangeException ("Index out of range.");
1601 return (ListViewItem) list [index];
1605 bool ICollection.IsSynchronized {
1606 get { return list.IsSynchronized; }
1609 object ICollection.SyncRoot {
1610 get { return list.SyncRoot; }
1613 bool IList.IsFixedSize {
1614 get { return list.IsFixedSize; }
1617 object IList.this [int index] {
1618 get { return this [index]; }
1619 set { throw new NotSupportedException ("SetItem operation is not supported."); }
1621 #endregion // Public Properties
1623 #region Public Methods
1624 public bool Contains (ListViewItem item)
1626 return list.Contains (item);
1629 public virtual void CopyTo (Array dest, int index)
1631 list.CopyTo (dest, index);
1634 public virtual IEnumerator GetEnumerator ()
1636 return list.GetEnumerator ();
1639 int IList.Add (object value)
1641 throw new NotSupportedException ("Add operation is not supported.");
1646 throw new NotSupportedException ("Clear operation is not supported.");
1649 bool IList.Contains (object item)
1651 return list.Contains (item);
1654 int IList.IndexOf (object item)
1656 return list.IndexOf (item);
1659 void IList.Insert (int index, object value)
1661 throw new NotSupportedException ("Insert operation is not supported.");
1664 void IList.Remove (object value)
1666 throw new NotSupportedException ("Remove operation is not supported.");
1669 void IList.RemoveAt (int index)
1671 throw new NotSupportedException ("RemoveAt operation is not supported.");
1674 public int IndexOf (ListViewItem item)
1676 return list.IndexOf (item);
1678 #endregion // Public Methods
1680 } // CheckedListViewItemCollection
1682 public class ColumnHeaderCollection : IList, ICollection, IEnumerable
1684 internal ArrayList list;
1685 private ListView owner;
1687 #region Public Constructor
1688 public ColumnHeaderCollection (ListView owner)
1690 list = new ArrayList ();
1693 #endregion // Public Constructor
1695 #region Public Properties
1697 public virtual int Count {
1698 get { return list.Count; }
1701 public virtual bool IsReadOnly {
1702 get { return false; }
1705 public virtual ColumnHeader this [int index] {
1707 if (index < 0 || index >= list.Count)
1708 throw new ArgumentOutOfRangeException ("Index out of range.");
1709 return (ColumnHeader) list [index];
1713 bool ICollection.IsSynchronized {
1714 get { return list.IsSynchronized; }
1717 object ICollection.SyncRoot {
1718 get { return list.SyncRoot; }
1721 bool IList.IsFixedSize {
1722 get { return list.IsFixedSize; }
1725 object IList.this [int index] {
1726 get { return this [index]; }
1727 set { throw new NotSupportedException ("SetItem operation is not supported."); }
1729 #endregion // Public Properties
1731 #region Public Methods
1732 public virtual int Add (ColumnHeader value)
1734 value.owner = this.owner;
1735 return list.Add (value);
1738 public virtual ColumnHeader Add (string str, int width, HorizontalAlignment textAlign)
1740 ColumnHeader colHeader = new ColumnHeader (this.owner, str, textAlign, width);
1741 this.Add (colHeader);
1746 public virtual void AddRange (ColumnHeader [] values)
1748 foreach (ColumnHeader colHeader in values)
1749 this.Add (colHeader);
1752 public virtual void Clear ()
1757 public bool Contains (ColumnHeader value)
1759 return list.Contains (value);
1762 public virtual IEnumerator GetEnumerator ()
1764 return list.GetEnumerator ();
1767 void ICollection.CopyTo (Array dest, int index)
1769 list.CopyTo (dest, index);
1772 int IList.Add (object value)
1774 if (! (value is ColumnHeader)) {
1775 throw new ArgumentException ("Not of type ColumnHeader", "value");
1778 return this.Add ((ColumnHeader) value);
1781 bool IList.Contains (object value)
1783 if (! (value is ColumnHeader)) {
1784 throw new ArgumentException ("Not of type ColumnHeader", "value");
1787 return this.Contains ((ColumnHeader) value);
1790 int IList.IndexOf (object value)
1792 if (! (value is ColumnHeader)) {
1793 throw new ArgumentException ("Not of type ColumnHeader", "value");
1796 return this.IndexOf ((ColumnHeader) value);
1799 void IList.Insert (int index, object value)
1801 if (! (value is ColumnHeader)) {
1802 throw new ArgumentException ("Not of type ColumnHeader", "value");
1805 this.Insert (index, (ColumnHeader) value);
1808 void IList.Remove (object value)
1810 if (! (value is ColumnHeader)) {
1811 throw new ArgumentException ("Not of type ColumnHeader", "value");
1814 this.Remove ((ColumnHeader) value);
1817 public int IndexOf (ColumnHeader value)
1819 return list.IndexOf (value);
1822 public void Insert (int index, ColumnHeader value)
1824 if (index < 0 || index >= list.Count)
1825 throw new ArgumentOutOfRangeException ("Index out of range.");
1827 value.owner = this.owner;
1828 list.Insert (index, value);
1831 public void Insert (int index, string str, int width, HorizontalAlignment textAlign)
1833 ColumnHeader colHeader = new ColumnHeader (this.owner, str, textAlign, width);
1834 this.Insert (index, colHeader);
1837 public virtual void Remove (ColumnHeader column)
1839 list.Remove (column);
1842 public virtual void RemoveAt (int index)
1844 if (index < 0 || index >= list.Count)
1845 throw new ArgumentOutOfRangeException ("Index out of range.");
1847 list.RemoveAt (index);
1849 #endregion // Public Methods
1851 } // ColumnHeaderCollection
1853 public class ListViewItemCollection : IList, ICollection, IEnumerable
1855 internal ArrayList list;
1856 private ListView owner;
1858 #region Public Constructor
1859 public ListViewItemCollection (ListView owner)
1861 list = new ArrayList ();
1864 #endregion // Public Constructor
1866 #region Public Properties
1868 public virtual int Count {
1869 get { return list.Count; }
1872 public virtual bool IsReadOnly {
1873 get { return false; }
1876 public virtual ListViewItem this [int displayIndex] {
1878 if (displayIndex < 0 || displayIndex >= list.Count)
1879 throw new ArgumentOutOfRangeException ("Index out of range.");
1880 return (ListViewItem) list [displayIndex];
1884 if (displayIndex < 0 || displayIndex >= list.Count)
1885 throw new ArgumentOutOfRangeException ("Index out of range.");
1887 if (list.Contains (value))
1888 throw new ArgumentException ("An item cannot be added more than once. To add an item again, you need to clone it.", "value");
1890 value.owner = this.owner;
1891 list [displayIndex] = value;
1893 owner.Redraw (true);
1897 bool ICollection.IsSynchronized {
1898 get { return list.IsSynchronized; }
1901 object ICollection.SyncRoot {
1902 get { return list.SyncRoot; }
1905 bool IList.IsFixedSize {
1906 get { return list.IsFixedSize; }
1909 object IList.this [int index] {
1910 get { return this [index]; }
1912 if (value is ListViewItem)
1913 this [index] = (ListViewItem) value;
1915 this [index] = new ListViewItem (value.ToString ());
1918 #endregion // Public Properties
1920 #region Public Methods
1921 public virtual ListViewItem Add (ListViewItem value)
1923 if (list.Contains (value))
1924 throw new ArgumentException ("An item cannot be added more than once. To add an item again, you need to clone it.", "value");
1926 value.owner = this.owner;
1929 if (owner.Sorting != SortOrder.None)
1932 owner.Redraw (true);
1937 public virtual ListViewItem Add (string text)
1939 ListViewItem item = new ListViewItem (text);
1940 return this.Add (item);
1943 public virtual ListViewItem Add (string text, int imageIndex)
1945 ListViewItem item = new ListViewItem (text, imageIndex);
1946 return this.Add (item);
1949 public void AddRange (ListViewItem [] values)
1953 foreach (ListViewItem item in values) {
1954 item.owner = this.owner;
1958 if (owner.Sorting != SortOrder.None)
1961 owner.Redraw (true);
1964 public virtual void Clear ()
1969 public bool Contains (ListViewItem item)
1971 return list.Contains (item);
1974 public virtual void CopyTo (Array dest, int index)
1976 list.CopyTo (dest, index);
1979 public virtual IEnumerator GetEnumerator ()
1981 return list.GetEnumerator ();
1984 int IList.Add (object item)
1989 if (item is ListViewItem) {
1990 li = (ListViewItem) item;
1991 if (list.Contains (li))
1992 throw new ArgumentException ("An item cannot be added more than once. To add an item again, you need to clone it.", "item");
1995 li = new ListViewItem (item.ToString ());
1997 li.owner = this.owner;
1998 result = list.Add (li);
1999 owner.Redraw (true);
2004 bool IList.Contains (object item)
2006 return list.Contains (item);
2009 int IList.IndexOf (object item)
2011 return list.IndexOf (item);
2014 void IList.Insert (int index, object item)
2016 if (item is ListViewItem)
2017 this.Insert (index, (ListViewItem) item);
2019 this.Insert (index, item.ToString ());
2022 void IList.Remove (object item)
2024 if (list.Contains (item)) {
2026 owner.Redraw (true);
2030 public int IndexOf (ListViewItem item)
2032 return list.IndexOf (item);
2035 public ListViewItem Insert (int index, ListViewItem item)
2037 if (index < 0 || index >= list.Count)
2038 throw new ArgumentOutOfRangeException ("Index out of range.");
2040 if (list.Contains (item))
2041 throw new ArgumentException ("An item cannot be added more than once. To add an item again, you need to clone it.", "item");
2043 item.owner = this.owner;
2044 list.Insert (index, item);
2045 owner.Redraw (true);
2049 public ListViewItem Insert (int index, string text)
2051 return this.Insert (index, new ListViewItem (text));
2054 public ListViewItem Insert (int index, string text, int imageIndex)
2056 return this.Insert (index, new ListViewItem (text, imageIndex));
2059 public virtual void Remove (ListViewItem item)
2061 if (list.Contains (item)) {
2063 owner.Redraw (true);
2067 public virtual void RemoveAt (int index)
2069 if (index < 0 || index >= list.Count)
2070 throw new ArgumentOutOfRangeException ("Index out of range.");
2072 list.RemoveAt (index);
2073 owner.Redraw (false);
2075 #endregion // Public Methods
2077 } // ListViewItemCollection
2079 public class SelectedIndexCollection : IList, ICollection, IEnumerable
2081 internal ArrayList list;
2082 private ListView owner;
2084 #region Public Constructor
2085 public SelectedIndexCollection (ListView owner)
2087 list = new ArrayList ();
2090 #endregion // Public Constructor
2092 #region Public Properties
2094 public virtual int Count {
2095 get { return list.Count; }
2098 public virtual bool IsReadOnly {
2099 get { return true; }
2102 public int this [int index] {
2104 if (index < 0 || index >= list.Count)
2105 throw new ArgumentOutOfRangeException ("Index out of range.");
2106 return (int) list [index];
2110 bool ICollection.IsSynchronized {
2111 get { return list.IsSynchronized; }
2114 object ICollection.SyncRoot {
2115 get { return list.SyncRoot; }
2118 bool IList.IsFixedSize {
2119 get { return list.IsFixedSize; }
2122 object IList.this [int index] {
2123 get { return this [index]; }
2124 set { throw new NotSupportedException ("SetItem operation is not supported."); }
2126 #endregion // Public Properties
2128 #region Public Methods
2129 public bool Contains (int selectedIndex)
2131 return list.Contains (selectedIndex);
2134 public virtual void CopyTo (Array dest, int index)
2136 list.CopyTo (dest, index);
2139 public virtual IEnumerator GetEnumerator ()
2141 return list.GetEnumerator ();
2144 int IList.Add (object value)
2146 throw new NotSupportedException ("Add operation is not supported.");
2151 throw new NotSupportedException ("Clear operation is not supported.");
2154 bool IList.Contains (object selectedIndex)
2156 return list.Contains (selectedIndex);
2159 int IList.IndexOf (object selectedIndex)
2161 return list.IndexOf (selectedIndex);
2164 void IList.Insert (int index, object value)
2166 throw new NotSupportedException ("Insert operation is not supported.");
2169 void IList.Remove (object value)
2171 throw new NotSupportedException ("Remove operation is not supported.");
2174 void IList.RemoveAt (int index)
2176 throw new NotSupportedException ("RemoveAt operation is not supported.");
2179 public int IndexOf (int selectedIndex)
2181 return list.IndexOf (selectedIndex);
2183 #endregion // Public Methods
2185 } // SelectedIndexCollection
2187 public class SelectedListViewItemCollection : IList, ICollection, IEnumerable
2189 internal ArrayList list;
2190 private ListView owner;
2192 #region Public Constructor
2193 public SelectedListViewItemCollection (ListView owner)
2195 list = new ArrayList ();
2198 #endregion // Public Constructor
2200 #region Public Properties
2202 public virtual int Count {
2203 get { return list.Count; }
2206 public virtual bool IsReadOnly {
2207 get { return true; }
2210 public ListViewItem this [int index] {
2212 if (index < 0 || index >= list.Count)
2213 throw new ArgumentOutOfRangeException ("Index out of range.");
2214 return (ListViewItem) list [index];
2218 bool ICollection.IsSynchronized {
2219 get { return list.IsSynchronized; }
2222 object ICollection.SyncRoot {
2223 get { return list.SyncRoot; }
2226 bool IList.IsFixedSize {
2227 get { return list.IsFixedSize; }
2230 object IList.this [int index] {
2231 get { return this [index]; }
2232 set { throw new NotSupportedException ("SetItem operation is not supported."); }
2234 #endregion // Public Properties
2236 #region Public Methods
2237 public virtual void Clear ()
2239 // mark the items as unselected before clearing the list
2240 for (int i = 0; i < list.Count; i++)
2241 ((ListViewItem) list [i]).selected = false;
2246 public bool Contains (ListViewItem item)
2248 return list.Contains (item);
2251 public virtual void CopyTo (Array dest, int index)
2253 list.CopyTo (dest, index);
2256 public virtual IEnumerator GetEnumerator ()
2258 return list.GetEnumerator ();
2261 int IList.Add (object value)
2263 throw new NotSupportedException ("Add operation is not supported.");
2266 bool IList.Contains (object item)
2268 return list.Contains (item);
2271 int IList.IndexOf (object item)
2273 return list.IndexOf (item);
2276 void IList.Insert (int index, object value)
2278 throw new NotSupportedException ("Insert operation is not supported.");
2281 void IList.Remove (object value)
2283 throw new NotSupportedException ("Remove operation is not supported.");
2286 void IList.RemoveAt (int index)
2288 throw new NotSupportedException ("RemoveAt operation is not supported.");
2291 public int IndexOf (ListViewItem item)
2293 return list.IndexOf (item);
2295 #endregion // Public Methods
2297 } // SelectedListViewItemCollection
2299 #endregion // Subclasses