* TreeView.cs: Don't draw the selected node when we lose
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / ListViewItem.cs
1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
8 // 
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
11 // 
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 //
20 // Copyright (c) 2004 Novell, Inc. (http://www.novell.com)
21 //
22 // Author:
23 //      Ravindra (rkumar@novell.com)
24 //
25 // Todo:
26 //     - Drawing of focus rectangle
27
28
29
30 // NOT COMPLETE
31
32
33 using System.Collections;
34 using System.ComponentModel;
35 using System.Drawing;
36 using System.Runtime.Serialization;
37
38 namespace System.Windows.Forms
39 {
40         [DefaultProperty ("Text")]
41         [DesignTimeVisible (false)]
42         [Serializable]
43         [ToolboxItem (false)]
44         [TypeConverter (typeof (ListViewItemConverter))]
45         public class ListViewItem : ICloneable, ISerializable
46         {
47                 #region Instance Variables
48                 private int image_index = -1;
49                 private bool is_checked = false;
50                 private bool is_focused = false;
51                 private int state_image_index = -1;
52                 private ListViewSubItemCollection sub_items;
53                 private object tag;
54                 private bool use_item_style = true;
55
56                 // internal variables
57                 internal Rectangle checkbox_rect;       // calculated by CalcListViewItem method
58                 internal Rectangle entire_rect;
59                 internal Rectangle icon_rect;
60                 internal Rectangle item_rect;
61                 internal Rectangle label_rect;
62                 internal Point location = Point.Empty;  // set by the ListView control
63                 internal ListView owner;
64                 internal bool selected;
65
66                 #endregion Instance Variables
67
68                 #region Public Constructors
69                 public ListViewItem ()
70                 {
71                         this.sub_items = new ListViewSubItemCollection (this);
72                         this.sub_items.Add ("");                        
73                 }
74
75                 public ListViewItem (string text) : this (text, -1)
76                 {
77                 }
78
79                 public ListViewItem (string [] items) : this (items, -1)
80                 {
81                 }
82
83                 public ListViewItem (ListViewItem.ListViewSubItem [] subItems, int imageIndex)
84                 {
85                         this.sub_items = new ListViewSubItemCollection (this);
86                         this.sub_items.AddRange (subItems);
87                         this.image_index = imageIndex;
88                 }
89
90                 public ListViewItem (string text, int imageIndex)
91                 {
92                         this.image_index = imageIndex;
93                         this.sub_items = new ListViewSubItemCollection (this);
94                         this.sub_items.Add (text);
95                 }
96
97                 public ListViewItem (string [] items, int imageIndex)
98                 {
99                         this.sub_items = new ListViewSubItemCollection (this);
100                         this.sub_items.AddRange (items);
101                         this.image_index = imageIndex;
102                 }
103
104                 public ListViewItem (string [] items, int imageIndex, Color foreColor, 
105                                      Color backColor, Font font)
106                 {
107                         this.sub_items = new ListViewSubItemCollection (this);
108                         this.sub_items.AddRange (items);
109                         this.image_index = imageIndex;
110                         ForeColor = foreColor;
111                         BackColor = backColor;
112                         Font = font;
113                 }
114                 #endregion      // Public Constructors
115
116                 #region Public Instance Properties
117                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
118                 public Color BackColor {
119                         get {
120                                 if (sub_items.Count > 0)
121                                         return sub_items[0].BackColor;
122
123                                 if (owner != null)
124                                         return owner.BackColor;
125                                 
126                                 return ThemeEngine.Current.ColorWindow;
127                         }
128
129                         set { sub_items[0].BackColor = value; }
130                 }
131
132                 [Browsable (false)]
133                 public Rectangle Bounds {
134                         get {
135                                 return GetBounds (ItemBoundsPortion.Entire);
136                         }
137                 }
138
139                 [DefaultValue (false)]
140                 [RefreshProperties (RefreshProperties.Repaint)]
141                 public bool Checked {
142                         get { return is_checked; }
143                         set { 
144                                 if (is_checked == value)
145                                         return;
146                                 
147                                 if (owner != null) {
148                                         is_checked = value;
149                                         if (is_checked) {
150                                                 if (owner.CheckedItems.Contains (this) == false) {
151                                                         owner.CheckedItems.list.Add (this);
152                                                         owner.CheckedIndices.list.Add (this.Index);
153                                                 }
154                                         }
155                                         else {
156                                                 owner.CheckedItems.list.Remove (this);
157                                                 owner.CheckedIndices.list.Remove (this.Index);
158                                         }
159                                         
160                                         owner.Invalidate (Bounds);
161                                 }                       
162                         }
163                 }
164
165                 [Browsable (false)]
166                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
167                 public bool Focused {
168                         get { return is_focused; }
169                         set {   
170                                 if (is_focused == value)
171                                         return;
172
173                                 is_focused = value; 
174
175                                 if (owner != null)
176                                         owner.Invalidate (Bounds);
177                         }
178                 }
179
180                 [Localizable (true)]
181                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
182                 public Font Font {
183                         get {
184                                 if (sub_items.Count > 0)
185                                         return sub_items[0].Font;
186
187                                 if (owner != null)
188                                         return owner.Font;
189
190                                 return ThemeEngine.Current.DefaultFont;
191                         }
192                         set {   
193                                 if (sub_items[0].Font == value)
194                                         return;
195
196                                 sub_items[0].Font = value; 
197
198                                 if (owner != null)
199                                         owner.Invalidate (Bounds);
200                         }
201                 }
202
203                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
204                 public Color ForeColor {
205                         get {
206                                 if (sub_items.Count > 0)
207                                         return sub_items[0].ForeColor;
208
209                                 if (owner != null)
210                                         return owner.ForeColor;
211
212                                 return ThemeEngine.Current.ColorWindowText;
213                         }
214                         set { sub_items[0].ForeColor = value; }
215                 }
216
217                 [DefaultValue (-1)]
218                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
219                 [Editor ("System.Windows.Forms.Design.ImageIndexEditor, " + Consts.AssemblySystem_Design,
220                          typeof (System.Drawing.Design.UITypeEditor))]
221                 [Localizable (true)]
222                 [TypeConverter (typeof (ImageIndexConverter))]
223                 public int ImageIndex {
224                         get { return image_index; }
225                         set {
226                                 if (value < -1)
227                                         throw new ArgumentException ("Invalid ImageIndex. It must be greater than or equal to -1.");
228                                 
229                                 image_index = value;
230
231                                 if (owner != null)
232                                         owner.Invalidate (Bounds);      
233                         }
234                 }
235
236                 [Browsable (false)]
237                 public ImageList ImageList {
238                         get {
239                                 if (owner == null)
240                                         return null;
241                                 else if (owner.View == View.LargeIcon)
242                                         return owner.large_image_list;
243                                 else
244                                         return owner.small_image_list;
245                         }
246                 }
247
248                 [Browsable (false)]
249                 public int Index {
250                         get {
251                                 if (owner == null)
252                                         return -1;
253                                 else
254                                         return owner.Items.IndexOf (this);
255                         }
256                 }
257
258                 [Browsable (false)]
259                 public ListView ListView {
260                         get { return owner; }
261                 }
262
263                 [Browsable (false)]
264                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
265                 public bool Selected {
266                         get { return selected; }
267                         set {
268                                 if (owner != null) {
269                                         if (owner.CanMultiselect == false &&
270                                             owner.SelectedItems.Count > 0) {
271                                                 owner.SelectedItems.Clear ();
272                                                 owner.SelectedIndices.list.Clear ();
273                                         }
274
275                                         selected = value;
276                                         if (selected) {
277                                                 if (owner.SelectedItems.Contains (this) == false) {
278                                                         owner.SelectedItems.list.Add (this);
279                                                         owner.SelectedIndices.list.Add (this.Index);
280                                                 }
281                                         }
282                                         else {
283                                                 owner.SelectedItems.list.Remove (this);
284                                                 owner.SelectedIndices.list.Remove (this.Index);
285                                         }       
286                                         
287                                         owner.Invalidate (Bounds);
288                                 }
289                         }
290                 }
291
292                 [DefaultValue (-1)]
293                 [Editor ("System.Windows.Forms.Design.ImageIndexEditor, " + Consts.AssemblySystem_Design,
294                          typeof (System.Drawing.Design.UITypeEditor))]
295                 [Localizable (true)]
296                 [TypeConverter (typeof (ImageIndexConverter))]
297                 public int StateImageIndex {
298                         get { return state_image_index; }
299                         set {
300                                 if (value < -1 || value > 14)
301                                         throw new ArgumentOutOfRangeException ("Invalid StateImageIndex. It must be in the range of [-1, 14].");
302
303                                 state_image_index = value;
304                         }
305                 }
306
307                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
308                 public ListViewSubItemCollection SubItems {
309                         get { return sub_items; }
310                 }
311
312                 [Bindable (true)]
313                 [DefaultValue (null)]
314                 [Localizable (false)]
315                 [TypeConverter (typeof (StringConverter))]
316                 public object Tag {
317                         get { return tag; }
318                         set { tag = value; }
319                 }
320
321                 [Localizable (true)]
322                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
323                 public string Text {
324                         get {
325                                 if (this.sub_items.Count > 0)
326                                         return this.sub_items [0].Text;
327                                 else
328                                         return "";
329                         }
330                         set { this.sub_items [0].Text = value; }
331                 }
332
333                 [DefaultValue (true)]
334                 public bool UseItemStyleForSubItems {
335                         get { return use_item_style; }
336                         set { use_item_style = value; }
337                 }
338                 #endregion      // Public Instance Properties
339
340                 #region Public Instance Methods
341                 public void BeginEdit ()
342                 {
343                         // FIXME: TODO
344                         // if (owner != null && owner.LabelEdit 
345                         //    && owner.Activation == ItemActivation.Standard)
346                         // allow editing
347                         // else
348                         // throw new InvalidOperationException ();
349                 }
350
351                 public virtual object Clone ()
352                 {
353                         ListViewItem clone = new ListViewItem ();
354                         clone.image_index = this.image_index;
355                         clone.is_checked = this.is_checked;
356                         clone.is_focused = this.is_focused;
357                         clone.selected = this.selected;
358                         clone.state_image_index = this.state_image_index;
359                         clone.sub_items = new ListViewSubItemCollection (this);
360                         
361                         foreach (ListViewSubItem subItem in this.sub_items)
362                                 clone.sub_items.Add (subItem.Text, subItem.ForeColor,
363                                                      subItem.BackColor, subItem.Font);
364                         clone.tag = this.tag;
365                         clone.use_item_style = this.use_item_style;
366                         clone.owner = null;
367
368                         return clone;
369                 }
370
371                 public virtual void EnsureVisible ()
372                 {
373                         if (this.owner != null) {
374                                 owner.EnsureVisible (owner.Items.IndexOf (this));
375                         }
376                 }
377
378                 public Rectangle GetBounds (ItemBoundsPortion portion)
379                 {
380                         if (owner == null)
381                                 return Rectangle.Empty;
382                                 
383                         /*  Original Ravi's design calculated all items in a virtual space
384                             We convert them real screen positions
385                         */
386                         switch (portion) {
387
388                         case ItemBoundsPortion.Icon: {
389                                 Rectangle rect = icon_rect;
390                                 rect.X -= owner.h_marker;
391                                 rect.Y -= owner.v_marker;
392                                 return rect;
393                         }
394
395                         case ItemBoundsPortion.Label: {
396                                 Rectangle rect = label_rect;
397                                 rect.X -= owner.h_marker;
398                                 rect.Y -= owner.v_marker;
399                                 return rect;
400                         }
401
402                         case ItemBoundsPortion.ItemOnly: {
403                                 Rectangle rect = item_rect;
404                                 rect.X -= owner.h_marker;
405                                 rect.Y -= owner.v_marker;
406                                 return rect;
407                         }
408
409                         case ItemBoundsPortion.Entire: {
410                                 Rectangle rect = entire_rect;
411                                 rect.X -= owner.h_marker;
412                                 rect.Y -= owner.v_marker;
413                                 return rect;                            
414                         }
415
416                         default:
417                                 throw new ArgumentException ("Invalid value for portion.");
418                         }
419                 }
420
421                 void ISerializable.GetObjectData (SerializationInfo info, StreamingContext context)
422                 {
423                         // FIXME: TODO
424                 }
425
426                 public virtual void Remove ()
427                 {
428                         if (owner != null)
429                                 owner.Items.Remove (this);
430                         owner = null;
431                 }
432
433                 public override string ToString ()
434                 {
435                         return string.Format ("ListViewItem: {0}", this.Text);
436                 }
437                 #endregion      // Public Instance Methods
438
439                 #region Protected Methods
440                 protected virtual void Deserialize (SerializationInfo info, StreamingContext context)
441                 {
442                         // FIXME: TODO
443                 }
444
445                 protected virtual void Serialize (SerializationInfo info, StreamingContext context)
446                 {
447                         // FIXME: TODO
448                 }
449                 #endregion      // Protected Methods
450
451                 #region Private Internal Methods
452                 internal Rectangle CheckRectReal {
453                         get {
454                                 Rectangle rect = checkbox_rect;
455                                 rect.X -= owner.h_marker;
456                                 rect.Y -= owner.v_marker;
457                                 return rect;
458                         }
459                 }
460                 
461                 internal Rectangle CheckRect {
462                         get { return this.checkbox_rect; }
463                 }
464
465                 internal Rectangle EntireRect {
466                         get { return this.entire_rect; }
467                 }
468
469                 internal Rectangle IconRect {
470                         get { return this.icon_rect; }
471                 }
472
473                 internal Rectangle LabelRect {
474                         get { return this.label_rect; }
475                 }
476
477                 internal void CalcListViewItem ()
478                 {
479                         int item_ht;
480                         Size text_size = owner.text_size;
481                         
482                         if (owner.CheckBoxes)
483                                 checkbox_rect.Size = owner.CheckBoxSize;
484                         else
485                                 checkbox_rect = Rectangle.Empty;
486
487                         checkbox_rect.Location = this.location;
488
489                         switch (owner.View) {
490
491                         case View.Details:
492                                 // LAMESPEC: MSDN says, "In all views except the details
493                                 // view of the ListView, this value specifies the same
494                                 // bounding rectangle as the Entire value." Actually, it
495                                 // returns same bounding rectangles for Item and Entire
496                                 // values in the case of Details view.
497
498                                 icon_rect.X = checkbox_rect.X + checkbox_rect.Width + 2;
499                                 icon_rect.Y = checkbox_rect.Y;
500
501                                 item_ht = Math.Max (owner.CheckBoxSize.Height + 1,
502                                                     text_size.Height);
503
504                                 if (owner.SmallImageList != null) {
505                                         item_ht = Math.Max (item_ht,
506                                                             owner.SmallImageList.ImageSize.Height + 1);
507                                         icon_rect.Width = owner.SmallImageList.ImageSize.Width;
508                                 }
509                                 else
510                                         icon_rect.Width = 0;
511
512                                 label_rect.Height = checkbox_rect.Height = icon_rect.Height = item_ht;
513
514                                 label_rect.X = icon_rect.X + icon_rect.Width;
515                                 label_rect.Y = icon_rect.Y;
516
517                                 if (owner.Columns.Count > 0)
518                                         label_rect.Width = Math.Max (text_size.Width, owner.Columns[0].Wd);
519                                 else
520                                         label_rect.Width = text_size.Width;
521
522                                 item_rect = entire_rect = Rectangle.Union
523                                         (Rectangle.Union (checkbox_rect, icon_rect), label_rect);
524
525                                 // Take into account the rest of columns. First column
526                                 // is already taken into account above.
527                                 for (int i = 1; i < owner.Columns.Count; i++) {
528                                         item_rect.Width += owner.Columns [i].Wd;
529                                         entire_rect.Width += owner.Columns [i].Wd;
530                                 }
531                                 break;
532
533                         case View.LargeIcon:
534                                 if (owner.LargeImageList != null) {
535                                         icon_rect.Width = owner.LargeImageList.ImageSize.Width + 16;
536                                         icon_rect.Height = owner.LargeImageList.ImageSize.Height + 4;
537                                 }
538                                 else {
539                                         icon_rect.Width = 16;
540                                         icon_rect.Height = 4;
541                                 }
542
543                                 if (text_size.Width <= (checkbox_rect.Width + icon_rect.Width)) {
544                                         icon_rect.X = checkbox_rect.X + checkbox_rect.Width;
545                                         icon_rect.Y = checkbox_rect.Y;
546
547                                         label_rect.X = icon_rect.X + (icon_rect.Width 
548                                                                       - text_size.Width) / 2;
549                                         label_rect.Y = Math.Max (checkbox_rect.Bottom,
550                                                                  icon_rect.Bottom) + 2;
551                                         label_rect.Size = text_size;
552                                 }
553                                 else {
554                                         label_rect.X = this.location.X;
555
556                                         int centerX = label_rect.X + text_size.Width / 2;
557                                         icon_rect.X = centerX - icon_rect.Width / 2;
558                                         checkbox_rect.X = (icon_rect.X - checkbox_rect.Width);
559
560                                         icon_rect.Y = checkbox_rect.Y;
561
562                                         label_rect.Y = Math.Max (checkbox_rect.Bottom,
563                                                                  icon_rect.Bottom) + 2;
564                                         label_rect.Size = text_size;
565                                 }
566
567                                 item_rect = Rectangle.Union (icon_rect, label_rect);
568                                 entire_rect = Rectangle.Union (item_rect, checkbox_rect);
569                                 break;
570
571                         case View.List:
572                                         goto case View.SmallIcon;
573
574                         case View.SmallIcon:
575                                 icon_rect.X = checkbox_rect.X + checkbox_rect.Width;
576                                 icon_rect.Y = checkbox_rect.Y;
577
578                                 item_ht = Math.Max (owner.CheckBoxSize.Height, text_size.Height);
579
580                                 if (owner.SmallImageList != null) {
581                                         item_ht = Math.Max (item_ht,
582                                                             owner.SmallImageList.ImageSize.Height + 1);
583                                         icon_rect.Width = owner.SmallImageList.ImageSize.Width;
584                                 }
585                                 else
586                                         icon_rect.Width = 0;
587
588                                 label_rect.Height = checkbox_rect.Height = icon_rect.Height = item_ht;
589
590                                 label_rect.X = icon_rect.X + icon_rect.Width;
591                                 label_rect.Y = icon_rect.Y;
592                                 label_rect.Width = text_size.Width;
593
594                                 item_rect = Rectangle.Union (icon_rect, label_rect);
595                                 entire_rect = Rectangle.Union (item_rect, checkbox_rect);
596                                 break;
597                         }
598                         
599                 }
600                 #endregion      // Private Internal Methods
601
602                 #region Subclasses
603
604                 [DefaultProperty ("Text")]
605                 [DesignTimeVisible (false)]
606                 [Serializable]
607                 [ToolboxItem (false)]
608                 [TypeConverter (typeof(ListViewSubItemConverter))]
609                 public class ListViewSubItem
610                 {
611                         private Color back_color;
612                         private Font font;
613                         private Color fore_color;
614                         internal ListViewItem owner;
615                         private string text;
616                         
617                         #region Public Constructors
618                         public ListViewSubItem ()
619                         {
620                         }
621
622                         public ListViewSubItem (ListViewItem owner, string text)
623                                 : this (owner, text, ThemeEngine.Current.ColorWindowText,
624                                         ThemeEngine.Current.ColorWindow,
625                                         ThemeEngine.Current.DefaultFont)
626                         {
627                         }
628
629                         public ListViewSubItem (ListViewItem owner, string text, Color foreColor,
630                                                 Color backColor, Font font)
631                         {
632                                 this.owner = owner;
633                                 this.text = text;
634                                 this.fore_color = foreColor;
635                                 this.back_color = backColor;
636                                 this.font = font;
637                         }
638                         #endregion // Public Constructors
639
640                         #region Public Instance Properties
641                         public Color BackColor {
642                                 get { return back_color; }
643                                 set { 
644                                         back_color = value; 
645                                         Invalidate ();
646                                     }
647                         }
648
649                         [Localizable (true)]
650                         public Font Font {
651                                 get {
652                                         if (font != null)
653                                                 return font;
654                                         else if (owner != null)
655                                                 return owner.Font;
656                                         return font;
657                                 }
658                                 set { 
659                                         font = value; 
660                                         Invalidate ();
661                                     }
662                         }
663
664                         public Color ForeColor {
665                                 get { return fore_color; }
666                                 set { 
667                                         fore_color = value; 
668                                         Invalidate ();
669                                     }
670                         }
671
672                         [Localizable (true)]
673                         public string Text {
674                                 get { return text; }
675                                 set { 
676                                         text = value; 
677                                         Invalidate ();
678                                     }
679                         }
680                         #endregion // Public Instance Properties
681
682                         #region Public Methods
683                         public void ResetStyle ()
684                         {
685                                 font = ThemeEngine.Current.DefaultFont;
686                                 back_color = ThemeEngine.Current.DefaultControlBackColor;
687                                 fore_color = ThemeEngine.Current.DefaultControlForeColor;
688                                 Invalidate ();
689                         }
690
691                         public override string ToString ()
692                         {
693                                 return string.Format ("ListViewSubItem {{0}}", text);
694                         }
695                         #endregion // Public Methods
696
697                         
698                         #region Private Methods
699                         private void Invalidate ()
700                         {
701                                 if (owner == null || owner.owner == null)
702                                         return;
703
704                                 owner.owner.Invalidate ();
705                         }
706                         #endregion // Private Methods
707                 }
708
709                 public class ListViewSubItemCollection : IList, ICollection, IEnumerable
710                 {
711                         private ArrayList list;
712                         internal ListViewItem owner;
713
714                         #region Public Constructors
715                         public ListViewSubItemCollection (ListViewItem owner)
716                         {
717                                 this.owner = owner;
718                                 this.list = new ArrayList ();
719                         }
720                         #endregion // Public Constructors
721
722                         #region Public Properties
723                         [Browsable (false)]
724                         public virtual int Count {
725                                 get { return list.Count; }
726                         }
727
728                         public virtual bool IsReadOnly {
729                                 get { return false; }
730                         }
731
732                         public ListViewSubItem this [int index] {
733                                 get { return (ListViewSubItem) list [index]; }
734                                 set { 
735                                         value.owner = this.owner;
736                                         list [index] = value;
737                                 }
738                         }
739
740                         bool ICollection.IsSynchronized {
741                                 get { return list.IsSynchronized; }
742                         }
743
744                         object ICollection.SyncRoot {
745                                 get { return list.SyncRoot; }
746                         }
747
748                         bool IList.IsFixedSize {
749                                 get { return list.IsFixedSize; }
750                         }
751
752                         object IList.this [int index] {
753                                 get { return this [index]; }
754                                 set {
755                                         if (! (value is ListViewSubItem))
756                                                 throw new ArgumentException ("Not of type ListViewSubItem", "value");
757                                         this [index] = (ListViewSubItem) value;
758                                 }
759                         }
760                         #endregion // Public Properties
761
762                         #region Public Methods
763                         public ListViewSubItem Add (ListViewSubItem item)
764                         {
765                                 item.owner = this.owner;
766                                 list.Add (item);
767                                 return item;
768                         }
769
770                         public ListViewSubItem Add (string text)
771                         {
772                                 ListViewSubItem item = new ListViewSubItem (this.owner, text);
773                                 list.Add (item);
774                                 return item;
775                         }
776
777                         public ListViewSubItem Add (string text, Color foreColor,
778                                                     Color backColor, Font font)
779                         {
780                                 ListViewSubItem item = new ListViewSubItem (this.owner, text,
781                                                                             foreColor, backColor, font);
782                                 list.Add (item);
783                                 return item;
784                         }
785
786                         public void AddRange (ListViewSubItem [] items)
787                         {
788                                 this.Clear ();
789                                 foreach (ListViewSubItem item in items)
790                                         this.Add (item);
791                         }
792
793                         public void AddRange (string [] items)
794                         {
795                                 this.Clear ();
796                                 foreach (string item in items)
797                                         this.Add (item);
798                         }
799
800                         public void AddRange (string [] items, Color foreColor,
801                                               Color backColor, Font font)
802                         {
803                                 this.Clear ();
804                                 foreach (string item in items)
805                                         this.Add (item, foreColor, backColor, font);
806                         }
807
808                         public virtual void Clear ()
809                         {
810                                 list.Clear ();
811                         }
812
813                         public bool Contains (ListViewSubItem item)
814                         {
815                                 return list.Contains (item);
816                         }
817
818                         public virtual IEnumerator GetEnumerator ()
819                         {
820                                 return list.GetEnumerator ();
821                         }
822
823                         void ICollection.CopyTo (Array dest, int index)
824                         {
825                                 list.CopyTo (dest, index);
826                         }
827
828                         int IList.Add (object item)
829                         {
830                                 if (! (item is ListViewSubItem)) {
831                                         throw new ArgumentException ("Not of type ListViewSubItem", "item");
832                                 }
833
834                                 ListViewSubItem sub_item = (ListViewSubItem) item;
835                                 sub_item.owner = this.owner;
836                                 return list.Add (sub_item);
837                         }
838
839                         bool IList.Contains (object subItem)
840                         {
841                                 if (! (subItem is ListViewSubItem)) {
842                                         throw new ArgumentException ("Not of type ListViewSubItem", "subItem");
843                                 }
844
845                                 return this.Contains ((ListViewSubItem) subItem);
846                         }
847
848                         int IList.IndexOf (object subItem)
849                         {
850                                 if (! (subItem is ListViewSubItem)) {
851                                         throw new ArgumentException ("Not of type ListViewSubItem", "subItem");
852                                 }
853
854                                 return this.IndexOf ((ListViewSubItem) subItem);
855                         }
856
857                         void IList.Insert (int index, object item)
858                         {
859                                 if (! (item is ListViewSubItem)) {
860                                         throw new ArgumentException ("Not of type ListViewSubItem", "item");
861                                 }
862
863                                 this.Insert (index, (ListViewSubItem) item);
864                         }
865
866                         void IList.Remove (object item)
867                         {
868                                 if (! (item is ListViewSubItem)) {
869                                         throw new ArgumentException ("Not of type ListViewSubItem", "item");
870                                 }
871
872                                 this.Remove ((ListViewSubItem) item);
873                         }
874
875                         public int IndexOf (ListViewSubItem subItem)
876                         {
877                                 return list.IndexOf (subItem);
878                         }
879
880                         public void Insert (int index, ListViewSubItem item)
881                         {
882                                 item.owner = this.owner;
883                                 list.Insert (index, item);
884                         }
885
886                         public void Remove (ListViewSubItem item)
887                         {
888                                 list.Remove (item);
889                         }
890
891                         public virtual void RemoveAt (int index)
892                         {
893                                 list.RemoveAt (index);
894                         }
895                         #endregion // Public Methods
896                 }
897                 #endregion // Subclasses
898         }
899 }