ListViewItem.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / WinForms / Managed / System / WinForms / ListViewItem.cs / 1305376 / ListViewItem.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

/* 
 */ 
namespace System.Windows.Forms {
    using System.Runtime.Serialization; 
    using System.Runtime.Serialization.Formatters;

    using System.Diagnostics;
    using System.Diagnostics.CodeAnalysis; 
    using System.Security;
    using System.Security.Permissions; 
    using System; 
    using System.Drawing;
    using System.Drawing.Design; 
    using System.ComponentModel;
    using System.IO;
    using Microsoft.Win32;
    using System.Collections; 
    using System.Collections.Specialized;
    using System.Runtime.Remoting; 
    using System.Runtime.InteropServices; 
    using System.ComponentModel.Design.Serialization;
    using System.Reflection; 
    using System.Globalization;

    /// 
    ///  
    ///    
    ///       Implements an item of a . 
    ///     
    /// 
    [ 
    TypeConverterAttribute(typeof(ListViewItemConverter)),
    ToolboxItem(false),
    DesignTimeVisible(false),
    DefaultProperty("Text"), 
    Serializable,
    SuppressMessage("Microsoft.Usage", "CA2240:ImplementISerializableCorrectly") 
    ] 
    public class ListViewItem : ICloneable, ISerializable {
 
        private const int MAX_SUBITEMS = 4096;

        private static readonly BitVector32.Section StateSelectedSection         = BitVector32.CreateSection(1);
        private static readonly BitVector32.Section StateImageMaskSet            = BitVector32.CreateSection(1, StateSelectedSection); 
        private static readonly BitVector32.Section StateWholeRowOneStyleSection = BitVector32.CreateSection(1, StateImageMaskSet);
        private static readonly BitVector32.Section SavedStateImageIndexSection  = BitVector32.CreateSection(15, StateWholeRowOneStyleSection); 
        private static readonly BitVector32.Section SubItemCountSection          = BitVector32.CreateSection(MAX_SUBITEMS, SavedStateImageIndexSection); 

        private int indentCount = 0; 
        private Point position = new Point(-1,-1);

        internal ListView listView;
 
        internal ListViewGroup group;
        private string groupName; 
 
        private ListViewSubItemCollection listViewSubItemCollection = null;
        private ListViewSubItem[] subItems; 

        // we stash the last index we got as a seed to GetDisplayIndex.
        private int lastIndex = -1;
 
        // An ID unique relative to a given list view that comctl uses to identify items.
        internal int ID = -1; 
 
        private BitVector32 state = new BitVector32();
        private ListViewItemImageIndexer imageIndexer; 
        private String toolTipText = String.Empty;
        object userData;

        // We need a special way to defer to the ListView's image 
        // list for indexing purposes.
        internal class ListViewItemImageIndexer : ImageList.Indexer { 
           private ListViewItem owner; 

 
           /// 
            public ListViewItemImageIndexer(ListViewItem item) {
              owner = item;
            } 

 
           public override ImageList ImageList { 
                get {
                        if (owner != null) { 
                            return owner.ImageList;
                        }
                        return null;
                    } 
                set { Debug.Assert(false, "We should never set the image list"); }
            } 
        } 

 
        /// 
        /// 
        ///    [To be supplied.]
        ///  
        public ListViewItem() {
            StateSelected = false; 
            UseItemStyleForSubItems = true; 
            SavedStateImageIndex = -1;
        } 

        /// 
        /// 
        ///     Creates a ListViewItem object from an Stream. 
        ///     The Serialization constructor is protected, as per FxCop Microsoft.Usage, CA2229 Rule.
        ///  
        [ 
            SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")  // Changing Deserialize to be non-virtual
                                                                                                    // would be a breaking change. 
        ]
        protected ListViewItem(SerializationInfo info, StreamingContext context) : this() {
            Deserialize(info, context);
        } 

        ///  
        ///  
        ///    [To be supplied.]
        ///  
        public ListViewItem(string text) : this(text, -1) {
        }

        ///  
        /// 
        ///    [To be supplied.] 
        ///  
        public ListViewItem(string text, int imageIndex) : this() {
            this.ImageIndexer.Index = imageIndex; 
            Text = text;
        }

        ///  
        /// 
        ///    [To be supplied.] 
        ///  
        public ListViewItem(string[] items) : this(items, -1) {
        } 

        /// 
        /// 
        ///    [To be supplied.] 
        /// 
        public ListViewItem(string[] items, int imageIndex) : this() { 
 
            this.ImageIndexer.Index = imageIndex;
            if (items != null && items.Length > 0) { 
                this.subItems = new ListViewSubItem[items.Length];
                for (int i = 0; i < items.Length; i++) {
                    subItems[i] = new ListViewSubItem(this, items[i]);
                } 
                this.SubItemCount = items.Length;
            } 
        } 

        ///  
        /// 
        ///    [To be supplied.]
        /// 
        public ListViewItem(string[] items, int imageIndex, Color foreColor, Color backColor, Font font) : this(items, imageIndex) { 
            this.ForeColor = foreColor;
            this.BackColor = backColor; 
            this.Font = font; 
        }
 
        /// 
        /// 
        ///    [To be supplied.]
        ///  
        public ListViewItem(ListViewSubItem[] subItems, int imageIndex) : this() {
 
            this.ImageIndexer.Index = imageIndex; 
            this.subItems = subItems;
            this.SubItemCount = this.subItems.Length; 

            // Update the owner of these subitems
            //
            for(int i=0; i < subItems.Length; ++i) { 
                subItems[i].owner = this;
            } 
        } 

        ///  
        /// 
        ///    [To be supplied.]
        /// 
        public ListViewItem(ListViewGroup group) : this() { 
            this.Group = group;
        } 
 
        /// 
        ///  
        ///    [To be supplied.]
        /// 
        public ListViewItem(string text, ListViewGroup group) : this(text) {
            this.Group = group; 
        }
 
        ///  
        /// 
        ///    [To be supplied.] 
        /// 
        public ListViewItem(string text, int imageIndex, ListViewGroup group) : this(text, imageIndex) {
            this.Group = group;
        } 

        ///  
        ///  
        ///    [To be supplied.]
        ///  
        public ListViewItem(string[] items, ListViewGroup group) : this(items) {
            this.Group = group;
        }
 
        /// 
        ///  
        ///    [To be supplied.] 
        /// 
        public ListViewItem(string[] items, int imageIndex, ListViewGroup group) : this(items, imageIndex) { 
            this.Group = group;
        }

        ///  
        /// 
        ///    [To be supplied.] 
        ///  
        public ListViewItem(string[] items, int imageIndex, Color foreColor, Color backColor, Font font, ListViewGroup group) :
            this(items, imageIndex, foreColor, backColor, font) { 
            this.Group = group;
        }

        ///  
        /// 
        ///    [To be supplied.] 
        ///  
        public ListViewItem(ListViewSubItem[] subItems, int imageIndex, ListViewGroup group) : this(subItems, imageIndex) {
            this.Group = group; 
        }

        /// 
        ///  
        ///    [To be supplied.]
        ///  
        public ListViewItem(string text, string imageKey) : this() { 
            this.ImageIndexer.Key = imageKey;
            Text = text; 
        }

        /// 
        ///  
        ///    [To be supplied.]
        ///  
        public ListViewItem(string[] items, string imageKey) : this() { 

            this.ImageIndexer.Key = imageKey; 
            if (items != null && items.Length > 0) {
                this.subItems = new ListViewSubItem[items.Length];
                for (int i = 0; i < items.Length; i++) {
                    subItems[i] = new ListViewSubItem(this, items[i]); 
                }
                this.SubItemCount = items.Length; 
            } 
        }
 
        /// 
        /// 
        ///    [To be supplied.]
        ///  
        public ListViewItem(string[] items, string imageKey, Color foreColor, Color backColor, Font font) : this(items, imageKey) {
            this.ForeColor = foreColor; 
            this.BackColor = backColor; 
            this.Font = font;
        } 

        /// 
        /// 
        ///    [To be supplied.] 
        /// 
        public ListViewItem(ListViewSubItem[] subItems, string imageKey) : this() { 
 
            this.ImageIndexer.Key = imageKey;
            this.subItems = subItems; 
            this.SubItemCount = this.subItems.Length;

            // Update the owner of these subitems
            // 
            for(int i=0; i < subItems.Length; ++i) {
                subItems[i].owner = this; 
            } 
        }
 
        /// 
        /// 
        ///    [To be supplied.]
        ///  
        public ListViewItem(string text, string imageKey, ListViewGroup group) : this(text, imageKey) {
            this.Group = group; 
        } 

        ///  
        /// 
        ///    [To be supplied.]
        /// 
        public ListViewItem(string[] items, string imageKey, ListViewGroup group) : this(items, imageKey) { 
            this.Group = group;
        } 
 
        /// 
        ///  
        ///    [To be supplied.]
        /// 
        public ListViewItem(string[] items, string imageKey, Color foreColor, Color backColor, Font font, ListViewGroup group) :
            this(items, imageKey, foreColor, backColor, font) { 
            this.Group = group;
        } 
 
        /// 
        ///  
        ///    [To be supplied.]
        /// 
        public ListViewItem(ListViewSubItem[] subItems, string imageKey, ListViewGroup group) : this(subItems, imageKey) {
            this.Group = group; 
        }
 
        ///  
        /// 
        ///     The font that this item will be displayed in. If its value is null, it will be displayed 
        ///     using the global font for the ListView control that hosts it.
        /// 
        [
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), 
        SRCategory(SR.CatAppearance)
        ] 
        public Color BackColor { 
            get {
                if (SubItemCount == 0) { 
                    if (listView != null) {
                        return listView.BackColor;
                    }
                    return SystemColors.Window; 
                }
                else { 
                    return subItems[0].BackColor; 
                }
            } 
            set {
                SubItems[0].BackColor = value;
            }
        } 

        ///  
        ///  
        ///     Returns the ListViewItem's bounding rectangle, including subitems. The bounding rectangle is empty if
        ///     the ListViewItem has not been added to a ListView control. 
        /// 
        [Browsable(false)]
        public Rectangle Bounds {
            get { 
                if (listView != null) {
                    return listView.GetItemRect(Index); 
                } 
                else
                    return new Rectangle(); 
            }
        }

        ///  
        /// 
        ///    [To be supplied.] 
        ///  
        [
        DefaultValue(false), 
        RefreshPropertiesAttribute(RefreshProperties.Repaint),
        SRCategory(SR.CatAppearance)
        ]
        public bool Checked { 
            get {
                return StateImageIndex > 0; 
            } 

            set { 
                if (Checked != value) {
                    if (listView != null && listView.IsHandleCreated) {
                        StateImageIndex = value ? 1 : 0;
 
                        // the setter for StateImageIndex calls ItemChecked handler
                        // thus need to verify validity of the listView again 
                        if ((this.listView != null) && !this.listView.UseCompatibleStateImageBehavior) { 
                            if (!listView.CheckBoxes) {
                                listView.UpdateSavedCheckedItems(this, value); 
                            }
                        }

                    } 
                    else {
                        SavedStateImageIndex = value ? 1 : 0; 
                    } 
                }
            } 
        }

        /// 
        ///  
        ///     Returns the focus state of the ListViewItem.
        ///  
        [ 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
        Browsable(false) 
        ]
        public bool Focused {
            get {
                if (listView != null && listView.IsHandleCreated) { 
                    return(listView.GetItemState(Index, NativeMethods.LVIS_FOCUSED) != 0);
                } 
                else return false; 
            }
 
            set {
                if (listView != null && listView.IsHandleCreated) {
                    listView.SetItemState(Index, value ? NativeMethods.LVIS_FOCUSED : 0, NativeMethods.LVIS_FOCUSED);
                } 
            }
        } 
 
        /// 
        ///  
        ///    [To be supplied.]
        /// 
        [
        Localizable(true), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
        SRCategory(SR.CatAppearance) 
        ] 
        public Font Font {
            get { 
                if (SubItemCount == 0) {
                    if (listView != null) {
                        return listView.Font;
                    } 
                    return Control.DefaultFont;
                } 
                else { 
                    return subItems[0].Font;
                } 
            }
            set {
                SubItems[0].Font = value;
            } 
        }
 
        ///  
        /// 
        ///    [To be supplied.] 
        /// 
        [
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
        SRCategory(SR.CatAppearance) 
        ]
        public Color ForeColor { 
            get { 
                if (SubItemCount == 0) {
                    if (listView != null) { 
                        return listView.ForeColor;
                    }
                    return SystemColors.WindowText;
                } 
                else {
                    return subItems[0].ForeColor; 
                } 
            }
            set { 
                SubItems[0].ForeColor = value;
            }
        }
 
        /// 
        ///  
        ///    The group to which this item belongs 
        /// 
        [ 
            DefaultValue(null),
            Localizable(true),
            SRCategory(SR.CatBehavior)
        ] 
        public ListViewGroup Group {
            get 
            { 
                return group;
            } 
            set
            {
                if (group != value) {
                    if (value != null) { 
                        value.Items.Add(this);
                    } 
                    else { 
                        group.Items.Remove(this);
                    } 
                }
                Debug.Assert(this.group == value, "BUG: group member variable wasn't updated!");

                // If the user specifically sets the group then don't use the groupName again. 
                this.groupName = null;
            } 
        } 

        ///  
        /// 
        ///     Returns the ListViewItem's currently set image index
        /// 
        [ 
        DefaultValue(-1),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), 
        Editor("System.Windows.Forms.Design.ImageIndexEditor, " + AssemblyRef.SystemDesign, typeof(UITypeEditor)), 
        Localizable(true),
        RefreshProperties(RefreshProperties.Repaint), 
        SRCategory(SR.CatBehavior),
        SRDescription(SR.ListViewItemImageIndexDescr),
        TypeConverterAttribute(typeof(NoneExcludedImageIndexConverter))
        ] 
        public int ImageIndex {
            get { 
                if (ImageIndexer.Index != -1 && ImageList != null && ImageIndexer.Index >= ImageList.Images.Count) { 
                    return ImageList.Images.Count - 1;
                } 
                return this.ImageIndexer.Index;
            }
            set {
                if (value < -1) { 
                    throw new ArgumentOutOfRangeException("ImageIndex", SR.GetString(SR.InvalidLowBoundArgumentEx, "ImageIndex", value.ToString(CultureInfo.CurrentCulture), (-1).ToString(CultureInfo.CurrentCulture)));
                } 
 
                ImageIndexer.Index = value;
 
                if (listView != null && listView.IsHandleCreated) {
                    listView.SetItemImage(Index, ImageIndexer.ActualIndex);
               }
            } 
        }
 
        internal ListViewItemImageIndexer ImageIndexer { 
            get {
                if (imageIndexer == null)  { 
                    imageIndexer = new ListViewItemImageIndexer(this);
                }
                return imageIndexer;
            } 
        }
 
        ///  
        /// 
        ///     Returns the ListViewItem's currently set image index 
        /// 
        [
        DefaultValue(""),
        TypeConverterAttribute(typeof(ImageKeyConverter)), 
        Editor("System.Windows.Forms.Design.ImageIndexEditor, " + AssemblyRef.SystemDesign, typeof(UITypeEditor)),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), 
        RefreshProperties(RefreshProperties.Repaint), 
        SRCategory(SR.CatBehavior),
        Localizable(true) 
        ]
        public string ImageKey {
            get {
                return this.ImageIndexer.Key; 
            }
            set { 
                   ImageIndexer.Key = value; 

                   if (listView != null && listView.IsHandleCreated) { 
                    listView.SetItemImage(Index, ImageIndexer.ActualIndex);
                   }
            }
        } 

        ///  
        [Browsable(false)] 
        public ImageList ImageList {
            get { 
                if (listView != null) {
                    switch(listView.View) {
                        case View.LargeIcon:
                        case View.Tile: 
                            return listView.LargeImageList;
                        case View.SmallIcon: 
                        case View.Details: 
                        case View.List:
                            return listView.SmallImageList; 
                    }
                }
                return null;
            } 
        }
 
        ///  
        [
        DefaultValue(0), 
        SRDescription(SR.ListViewItemIndentCountDescr),
        SRCategory(SR.CatDisplay)
        ]
        public int IndentCount { 
            get {
                return indentCount; 
            } 
            set {
                if (value == indentCount) 
                    return;
                if (value < 0) {
                    throw new ArgumentOutOfRangeException("IndentCount", SR.GetString(SR.ListViewIndentCountCantBeNegative));
                } 
                indentCount = value;
                if (listView != null && listView.IsHandleCreated) { 
                    listView.SetItemIndentCount(Index, indentCount); 
                }
            } 
        }


        ///  
        /// 
        ///     Returns ListViewItem's current index in the listview, or -1 if it has not been added to a ListView control. 
        ///  
        [Browsable(false)]
        public int Index { 
            get {
                if (listView != null) {
                    // if the list is virtual, the ComCtrl control does not keep any information
                    // about any list view items, so we use our cache instead. 
                    if (!listView.VirtualMode) {
                        lastIndex = listView.GetDisplayIndex(this, lastIndex); 
                    } 
                    return lastIndex;
                } 
                else {
                    return -1;
                }
            } 
        }
 
        ///  
        /// 
        /// Returns the ListView control that holds this ListViewItem. May be null if no 
        /// control has been assigned yet.
        /// 
        [Browsable(false)]
        public ListView ListView { 
            get {
                return listView; 
            } 
        }
 

        /// 
        /// 
        ///     Name associated with this ListViewItem 
        /// 
        [ 
        Localizable(true), 
        Browsable(false),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) 
        ]
        public string Name {
            get {
                if (SubItemCount == 0) { 
                    return string.Empty;
                } 
                else { 
                    return subItems[0].Name;
                } 
            }
            set {
                SubItems[0].Name = value;
            } 
        }
 
        ///  
        [
        SRCategory(SR.CatDisplay), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
        Browsable(false)
        ]
        public Point Position { 
            get {
                if (listView != null && listView.IsHandleCreated) { 
                    position = listView.GetItemPosition(Index); 
                }
                return position; 
            }
            set {
                if (value.Equals(position))
                    return; 
                position = value;
                if (listView != null && listView.IsHandleCreated) { 
                    if (!listView.VirtualMode) { 
                        listView.SetItemPosition(Index, position.X, position.Y);
                    } 
                }
            }
        }
 
        // the listView needs the raw encoding for the state image index when in VirtualMode
        internal int RawStateImageIndex { 
            get { 
                return (this.SavedStateImageIndex + 1) << 12;
            } 
        }

        /// 
        ///     Accessor for our state bit vector. 
        /// 
        private int SavedStateImageIndex { 
            get { 
                // State goes from zero to 15, but we need a negative
                // number, so we store + 1. 
                return state[SavedStateImageIndexSection] - 1;
            }
            set {
                // flag whether we've set a value. 
                //
                state[StateImageMaskSet] = (value == -1 ? 0 : 1); 
 
                // push in the actual value
                // 
                state[SavedStateImageIndexSection] = value + 1;
            }
        }
 
        /// 
        ///  
        ///     Treats the ListViewItem as a row of strings, and returns an array of those strings 
        /// 
        [ 
        Browsable(false),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
        ]
        public bool Selected { 
            get {
                if (listView != null && listView.IsHandleCreated) { 
                    return(listView.GetItemState(Index, NativeMethods.LVIS_SELECTED) != 0); 
                }
                else 
                    return StateSelected;
            }
            set {
                if (listView != null && listView.IsHandleCreated) { 
                    listView.SetItemState(Index, value ? NativeMethods.LVIS_SELECTED: 0, NativeMethods.LVIS_SELECTED);
 
                    // vsw 451976: update comctl32's selection information. 
                    listView.SetSelectionMark(Index);
                } 
                else {
                    StateSelected = value;
                    if (this.listView != null && this.listView.IsHandleCreated) {
                        // APPCOMPAT: set the selected state on the list view item only if the list view's Handle is already created. 
                        // vsw 448052.
                        listView.CacheSelectedStateForItem(this, value); 
                    } 
                }
            } 
        }

        /// 
        ///  
        ///    [To be supplied.]
        ///  
        [ 
        Localizable(true),
        TypeConverterAttribute(typeof(NoneExcludedImageIndexConverter)), 
        DefaultValue(-1),
        SRDescription(SR.ListViewItemStateImageIndexDescr),
        SRCategory(SR.CatBehavior),
        RefreshProperties(RefreshProperties.Repaint), 
        Editor("System.Windows.Forms.Design.ImageIndexEditor, " + AssemblyRef.SystemDesign, typeof(UITypeEditor)),
        RelatedImageList("ListView.StateImageList") 
        ] 
        public int StateImageIndex {
            get { 
                if (listView != null && listView.IsHandleCreated) {
                    int state = listView.GetItemState(Index, NativeMethods.LVIS_STATEIMAGEMASK);
                    return ((state >> 12) - 1);   // index is 1-based
                } 
                else return SavedStateImageIndex;
            } 
            set { 
                if (value < -1 || value > 14)
                    throw new ArgumentOutOfRangeException("StateImageIndex", SR.GetString(SR.InvalidArgument, "StateImageIndex", (value).ToString(CultureInfo.CurrentCulture))); 

                if (listView != null && listView.IsHandleCreated) {
                    this.state[StateImageMaskSet] = (value == -1 ? 0 : 1);
                    int state = ((value + 1) << 12);  // index is 1-based 
                    listView.SetItemState(Index, state, NativeMethods.LVIS_STATEIMAGEMASK);
                } 
                SavedStateImageIndex = value; 
            }
        } 


        internal bool StateImageSet {
            get { 
                return (this.state[StateImageMaskSet] != 0);
            } 
        } 

 
        /// 
        ///     Accessor for our state bit vector.
        /// 
        internal bool StateSelected { 
            get {
                return state[StateSelectedSection] == 1; 
            } 
            set {
                state[StateSelectedSection] = value ? 1 : 0; 
            }
        }

        ///  
        ///     Accessor for our state bit vector.
        ///  
        private int SubItemCount { 
            get {
                return state[SubItemCountSection]; 
            }
            set {
                state[SubItemCountSection] = value;
            } 
        }
 
        ///  
        /// 
        ///    [To be supplied.] 
        /// 
        [
        SRCategory(SR.CatData),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), 
        SRDescription(SR.ListViewItemSubItemsDescr),
        Editor("System.Windows.Forms.Design.ListViewSubItemCollectionEditor, " + AssemblyRef.SystemDesign,typeof(UITypeEditor)), 
        ] 
        public ListViewSubItemCollection SubItems {
            get { 
                if (SubItemCount == 0) {
                    subItems = new ListViewSubItem[1];
                    subItems[0] = new ListViewSubItem(this, string.Empty);
                    SubItemCount = 1; 
                }
 
                if (listViewSubItemCollection == null) { 
                    listViewSubItemCollection = new ListViewSubItemCollection(this);
                } 
                return listViewSubItemCollection;
            }
        }
 
        /// 
        [ 
        SRCategory(SR.CatData), 
        Localizable(false),
        Bindable(true), 
        SRDescription(SR.ControlTagDescr),
        DefaultValue(null),
        TypeConverter(typeof(StringConverter)),
        ] 
        public object Tag {
            get { 
                return userData; 
            }
            set { 
                userData = value;
            }
        }
 
        /// 
        ///  
        ///     Text associated with this ListViewItem 
        /// 
        [ 
        Localizable(true),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
        SRCategory(SR.CatAppearance)
        ] 
        public string Text {
            get { 
                if (SubItemCount == 0) { 
                    return string.Empty;
                } 
                else {
                    return subItems[0].Text;
                }
            } 
            set {
                SubItems[0].Text = value; 
            } 
        }
 
        /// 
        /// 
        ///     Tool tip text associated with this ListViewItem
        ///  
        [
        SRCategory(SR.CatAppearance), 
        DefaultValue("") 
        ]
        public string ToolTipText { 
            get {
                return toolTipText;
            }
            set { 
                if (value == null)
                    value = String.Empty; 
                if (WindowsFormsUtils.SafeCompareStrings(toolTipText, value, false /*ignoreCase*/)) { 
                    return;
                } 

                toolTipText = value;

                // tell the list view about this change 
                if (this.listView != null && this.listView.IsHandleCreated) {
                    this.listView.ListViewItemToolTipChanged(this); 
                } 
            }
        } 

        /// 
        /// 
        ///     Whether or not the font and coloring for the ListViewItem will be used for all of its subitems. 
        ///     If true, the ListViewItem style will be used when drawing the subitems.
        ///     If false, the ListViewItem and its subitems will be drawn in their own individual styles 
        ///     if any have been set. 
        /// 
        [ 
        DefaultValue(true),
        SRCategory(SR.CatAppearance)
        ]
        public bool UseItemStyleForSubItems { 
            get {
                return state[StateWholeRowOneStyleSection] == 1; 
            } 
            set {
                state[StateWholeRowOneStyleSection] = value ? 1 : 0; 
            }
        }

        ///  
        /// 
        ///     Initiate editing of the item's label. 
        ///     Only effective if LabelEdit property is true. 
        /// 
        public void BeginEdit() { 
            if (Index >= 0) {
                ListView lv = ListView;
                if (lv.LabelEdit == false)
                    throw new InvalidOperationException(SR.GetString(SR.ListViewBeginEditFailed)); 
                if (!lv.Focused)
                    lv.FocusInternal(); 
                UnsafeNativeMethods.SendMessage(new HandleRef(lv, lv.Handle), NativeMethods.LVM_EDITLABEL, Index, 0); 
            }
        } 

        /// 
        /// 
        ///    [To be supplied.] 
        /// 
        public virtual object Clone() { 
            ListViewSubItem[] clonedSubItems = new ListViewSubItem[this.SubItems.Count]; 
            for(int index=0; index < this.SubItems.Count; ++index) {
                ListViewSubItem subItem = this.SubItems[index]; 
                clonedSubItems[index] = new ListViewSubItem(null,
                                                            subItem.Text,
                                                            subItem.ForeColor,
                                                            subItem.BackColor, 
                                                            subItem.Font);
                clonedSubItems[index].Tag = subItem.Tag; 
            } 

            Type clonedType = this.GetType(); 
            ListViewItem newItem = null;

            if (clonedType == typeof(ListViewItem)) {
                newItem = new ListViewItem(clonedSubItems, this.ImageIndexer.Index); 
            }
            else { 
                // SECREVIEW : Late-binding does not represent a security thread, see bug#411899 for more info.. 
                //
                newItem = (ListViewItem)Activator.CreateInstance(clonedType); 
            }
            newItem.subItems = clonedSubItems;
            newItem.ImageIndexer.Index = this.ImageIndexer.Index;
            newItem.SubItemCount = this.SubItemCount; 
            newItem.Checked = this.Checked;
            newItem.UseItemStyleForSubItems = this.UseItemStyleForSubItems; 
            newItem.Tag = this.Tag; 

            // Only copy over the ImageKey if we're using it. 
            if (!String.IsNullOrEmpty(this.ImageIndexer.Key)) {
                newItem.ImageIndexer.Key = this.ImageIndexer.Key;
            }
 
            newItem.indentCount = this.indentCount;
            newItem.StateImageIndex = this.StateImageIndex; 
            newItem.toolTipText = this.toolTipText; 
            newItem.BackColor = this.BackColor;
            newItem.ForeColor = this.ForeColor; 
            newItem.Font = this.Font;
            newItem.Text = this.Text;
            newItem.Group = this.Group;
 
            return newItem;
        } 
 
        /// 
        ///  
        ///     Ensure that the item is visible, scrolling the view as necessary.
        /// 
        public virtual void EnsureVisible() {
            if (listView != null && listView.IsHandleCreated) { 
                listView.EnsureVisible(Index);
            } 
        } 

        ///  
        public ListViewItem FindNearestItem(SearchDirectionHint searchDirection) {
            Rectangle r = this.Bounds;

            switch (searchDirection) { 
                case SearchDirectionHint.Up:
                    return this.ListView.FindNearestItem(searchDirection, r.Left, r.Top); 
                case SearchDirectionHint.Down: 
                    return this.ListView.FindNearestItem(searchDirection, r.Left, r.Bottom);
                case SearchDirectionHint.Left: 
                    return this.ListView.FindNearestItem(searchDirection, r.Left, r.Top);
                case SearchDirectionHint.Right:
                    return this.ListView.FindNearestItem(searchDirection, r.Right, r.Top);
                default : 
                    Debug.Fail("we handled all the 4 directions");
                    return null; 
            } 
        }
 
        /// 
        /// 
        ///     Returns a specific portion of the ListViewItem's bounding rectangle.
        ///     The rectangle returned is empty if the ListViewItem has not been added to a ListView control. 
        /// 
        public Rectangle GetBounds(ItemBoundsPortion portion) { 
            if (listView != null && listView.IsHandleCreated) { 
                return listView.GetItemRect(Index, portion);
            } 
            else return new Rectangle();
        }

        ///  
        public ListViewSubItem GetSubItemAt(int x, int y) {
            if (listView != null && listView.IsHandleCreated && listView.View == View.Details) { 
                int iItem = -1; 
                int iSubItem = -1;
 
                listView.GetSubItemAt(x,y, out iItem, out iSubItem);

                // bug in commctl list view:
                // if the user clicks to the RIGHT of the last subitem the commctl returns the index of the subitem which would have fit there 
                // we have to check if iSubItem falls in the sub item collection
                if (iItem == this.Index && iSubItem != -1 && iSubItem < SubItems.Count) { 
                    return SubItems[iSubItem]; 
                } else {
                    return null; 
                }
            } else {
                return null;
            } 
        }
 
        ///  
        /// 
        ///  
        /// 
        internal void Host(ListView parent, int ID, int index) {
            // Don't let the name "host" fool you -- Handle is not necessarily created
            Debug.Assert(this.listView == null || !this.listView.VirtualMode, "ListViewItem::Host can't be used w/ a virtual item"); 
            Debug.Assert(parent == null || !parent.VirtualMode, "ListViewItem::Host can't be used w/ a virtual list");
 
            this.ID = ID; 
            listView = parent;
 
            // If the index is valid, then the handle has been created.
            if (index != -1) {
                UpdateStateToListView(index);
            } 
        }
 
        ///  
        ///     This is used to map list view items w/ their respective groups
        ///     in localized forms. 
        /// 
        internal void UpdateGroupFromName() {
            Debug.Assert(this.listView != null, "This method is used only when items are parented in a list view");
            Debug.Assert(!this.listView.VirtualMode, "we need to update the group only when the user specifies the list view items in localizable forms"); 
            if (String.IsNullOrEmpty(this.groupName)) {
                return; 
            } 

            ListViewGroup group = this.listView.Groups[this.groupName]; 
            this.Group = group;

            // Use the group name only once.
            this.groupName = null; 
        }
 
        internal void UpdateStateToListView(int index) { 
            NativeMethods.LVITEM lvItem = new NativeMethods.LVITEM();
            UpdateStateToListView(index, ref lvItem, true); 
        }

        /// 
        ///     Called when we have just pushed this item into a list view and we need 
        ///     to configure the list view's state for the item.  Use a valid index
        ///     if you can, or use -1 if you can't. 
        ///  
        internal void UpdateStateToListView(int index, ref NativeMethods.LVITEM lvItem, bool updateOwner) {
 
            Debug.Assert(listView.IsHandleCreated, "Should only invoke UpdateStateToListView when handle is created.");

            if (index == -1) {
                index = Index; 
            }
            else { 
                lastIndex = index; 
            }
 
            // Update Item state in one shot
            //
            int itemState = 0;
            int stateMask = 0; 

            if (StateSelected) { 
                itemState |= NativeMethods.LVIS_SELECTED; 
                stateMask |= NativeMethods.LVIS_SELECTED;
            } 

            if (SavedStateImageIndex > -1) {
                itemState |= ((SavedStateImageIndex + 1) << 12);
                stateMask |= NativeMethods.LVIS_STATEIMAGEMASK; 
            }
 
            lvItem.mask |= NativeMethods.LVIF_STATE; 
            lvItem.iItem = index;
            lvItem.stateMask |= stateMask; 
            lvItem.state |= itemState;

            if (listView.GroupsEnabled) {
                lvItem.mask |= NativeMethods.LVIF_GROUPID; 
                lvItem.iGroupId = listView.GetNativeGroupId(this);
 
                Debug.Assert(!updateOwner || listView.SendMessage(NativeMethods.LVM_ISGROUPVIEWENABLED, 0, 0) != IntPtr.Zero, "Groups not enabled"); 
                Debug.Assert(!updateOwner || listView.SendMessage(NativeMethods.LVM_HASGROUP, lvItem.iGroupId, 0) != IntPtr.Zero, "Doesn't contain group id: " + lvItem.iGroupId.ToString(CultureInfo.InvariantCulture));
            } 

            if (updateOwner) {
                UnsafeNativeMethods.SendMessage(new HandleRef(listView, listView.Handle), NativeMethods.LVM_SETITEM, 0, ref lvItem);
            } 
        }
 
        internal void UpdateStateFromListView(int displayIndex, bool checkSelection) { 
            if (listView != null && listView.IsHandleCreated && displayIndex != -1) {
 
                // Get information from comctl control
                //
                NativeMethods.LVITEM lvItem = new NativeMethods.LVITEM();
                lvItem.mask = NativeMethods.LVIF_PARAM | NativeMethods.LVIF_STATE | NativeMethods.LVIF_GROUPID; 

                if (checkSelection) { 
                    lvItem.stateMask = NativeMethods.LVIS_SELECTED; 
                }
 

                // we want to get all the information, including the state image mask
                lvItem.stateMask |= NativeMethods.LVIS_STATEIMAGEMASK;
 
                if (lvItem.stateMask == 0) {
                    // perf optimization: no work to do. 
                    // 
                    return;
                } 


                lvItem.iItem = displayIndex;
                UnsafeNativeMethods.SendMessage(new HandleRef(listView, listView.Handle), NativeMethods.LVM_GETITEM, 0, ref lvItem); 

                // Update this class' information 
                // 
                if (checkSelection) {
                    StateSelected = (lvItem.state & NativeMethods.LVIS_SELECTED) != 0; 
                }
                SavedStateImageIndex = ((lvItem.state & NativeMethods.LVIS_STATEIMAGEMASK) >> 12) - 1;

                // a-jegros: bug 154131 - group needs to be updated, too! 
                group = null;
                foreach (ListViewGroup lvg in ListView.Groups) { 
                    if (lvg.ID == lvItem.iGroupId) { 
                        group = lvg;
                        break; 
                    }
                }
            }
        } 

        ///  
        ///  
        /// 
        ///  
        internal void UnHost(bool checkSelection) {
            UnHost(Index, checkSelection);
        }
 
        internal void UnHost(int displayIndex, bool checkSelection) {
            UpdateStateFromListView(displayIndex, checkSelection); 
 
            if (this.listView != null && (this.listView.Site == null || !this.listView.Site.DesignMode) && this.group != null) {
                this.group.Items.Remove(this); 
            }

            // Make sure you do these last, as the first several lines depends on this information
            ID = -1; 
            listView = null;
        } 
 
        /// 
        ///  
        ///    [To be supplied.]
        /// 
        public virtual void Remove() {
            if (listView != null) { 
                listView.Items.Remove(this);
            } 
        } 

        ///  
        /// 
        ///    [To be supplied.]
        /// 
        protected virtual void Deserialize(SerializationInfo info, StreamingContext context) { 

            bool foundSubItems = false; 
 
            string imageKey = null;
            int imageIndex = -1; 

            foreach (SerializationEntry entry in info) {
                if (entry.Name == "Text") {
                    Text = info.GetString(entry.Name); 
                }
                else if (entry.Name == "ImageIndex") { 
                    imageIndex = info.GetInt32(entry.Name); 
                }
                else if (entry.Name == "ImageKey") { 
                    imageKey = info.GetString(entry.Name);
                }
                else if (entry.Name == "SubItemCount") {
                    SubItemCount = info.GetInt32(entry.Name); 
                    // foundSubItems true only if count > 0
                    if (SubItemCount > 0) 
                    { 
                        foundSubItems = true;
                    } 
                }
                else if (entry.Name == "BackColor") {
                    BackColor = (Color)info.GetValue(entry.Name, typeof(Color));
                } 
                else if (entry.Name == "Checked") {
                    Checked = info.GetBoolean(entry.Name); 
                } 
                else if (entry.Name == "Font") {
                    Font = (Font)info.GetValue(entry.Name, typeof(Font)); 
                }
                else if (entry.Name == "ForeColor") {
                    ForeColor = (Color)info.GetValue(entry.Name, typeof(Color));
                } 
                else if (entry.Name == "UseItemStyleForSubItems") {
                    UseItemStyleForSubItems = info.GetBoolean(entry.Name); 
                } 
                else if (entry.Name == "Group") {
                    ListViewGroup group = (ListViewGroup) info.GetValue(entry.Name, typeof(ListViewGroup)); 
                    this.groupName = group.Name;
                }
            }
 
            // let image key take precidence
            if (imageKey != null) { 
                ImageKey = imageKey; 
            }
            else if (imageIndex != -1) { 
                ImageIndex = imageIndex;
            }

            if (foundSubItems) { 
                ListViewSubItem[] newItems = new ListViewSubItem[SubItemCount];
                for (int i = 1; i < SubItemCount; i++) { 
                    // SEC 
                    ListViewSubItem newItem = (ListViewSubItem)info.GetValue("SubItem" + i.ToString(CultureInfo.InvariantCulture), typeof(ListViewSubItem));
                    newItem.owner = this; 
                    newItems[i] = newItem;
                }
                newItems[0] = subItems[0];
                subItems = newItems; 
            }
        } 
 
        /// 
        ///  
        ///     Saves this ListViewItem object to the given data stream.
        /// 
        /// SECREVIEW: Since ISerializable.GetObjectData and Deserialize require SerializationFormatter - locking down.
       	[SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.SerializationFormatter), 		 
         SecurityPermission(SecurityAction.InheritanceDemand, Flags=SecurityPermissionFlag.SerializationFormatter)]
        protected virtual void Serialize(SerializationInfo info, StreamingContext context) { 
            info.AddValue("Text", Text); 
            info.AddValue("ImageIndex", ImageIndexer.Index);
            if (!String.IsNullOrEmpty(ImageIndexer.Key)) { 
                info.AddValue("ImageKey", ImageIndexer.Key);
            }
            if (SubItemCount > 1) {
                info.AddValue("SubItemCount", SubItemCount); 
                for (int i = 1; i < SubItemCount; i++) {
                    info.AddValue("SubItem" + i.ToString(CultureInfo.InvariantCulture), subItems[i], typeof(ListViewSubItem)); 
                } 
            }
            info.AddValue("BackColor", BackColor); 
            info.AddValue("Checked", Checked);
            info.AddValue("Font", Font);
            info.AddValue("ForeColor", ForeColor);
            info.AddValue("UseItemStyleForSubItems", UseItemStyleForSubItems); 
            if (this.Group != null) {
                info.AddValue("Group", this.Group); 
            } 
        }
 
        // we need this function to set the index when the list view is in virtual mode.
        // the index of the list view item is used in ListView::set_TopItem property
        internal void SetItemIndex(ListView listView, int index) {
            Debug.Assert(listView != null && listView.VirtualMode, "ListViewItem::SetItemIndex should be used only when the list is virtual"); 
            Debug.Assert(index > -1, "can't set the index on a virtual list view item to -1");
            this.listView = listView; 
            this.lastIndex = index; 
        }
 
        /// 
        internal bool ShouldSerializeText() {
            return false;
        } 

        private bool ShouldSerializePosition() { 
            return !this.position.Equals(new Point(-1,-1)); 
        }
 
        /// 
        /// 
        ///    [To be supplied.]
        ///  
        public override string ToString() {
            return "ListViewItem: {" + Text + "}"; 
        } 

        // The ListItem's state (or a SubItem's state) has changed, so invalidate the ListView control 
        internal void InvalidateListView() {
            if (listView != null && listView.IsHandleCreated) {
                listView.Invalidate();
            } 
        }
 
        internal void UpdateSubItems(int index){ 
            UpdateSubItems(index, SubItemCount);
        } 

        internal void UpdateSubItems(int index, int oldCount){
            if (listView != null && listView.IsHandleCreated) {
                int subItemCount = SubItemCount; 

                int itemIndex = Index; 
 
                if (index != -1) {
                    listView.SetItemText(itemIndex, index, subItems[index].Text); 
                }
                else {
                    for(int i=0; i < subItemCount; i++) {
                        listView.SetItemText(itemIndex, i, subItems[i].Text); 
                    }
                } 
 
                for (int i = subItemCount; i < oldCount; i++) {
                    listView.SetItemText(itemIndex, i, string.Empty); 
                }
            }
        }
 
        /// 
        ///  
        [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.SerializationFormatter)] 
        void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) {
            Serialize(info, context); 
        }

        /// 
        ///  
        ///    [To be supplied.]
        ///  
        [ 
            TypeConverterAttribute(typeof(ListViewSubItemConverter)),
            ToolboxItem(false), 
            DesignTimeVisible(false),
            DefaultProperty("Text"),
            Serializable
        ] 
        public class ListViewSubItem {
 
            [NonSerialized] 
            internal ListViewItem owner;
 
            private string text;

            [OptionalField(VersionAdded=2)]
            private string name = null; 

            private SubItemStyle style; 
 
            [OptionalField(VersionAdded=2)]
            private object userData; 

            /// 
            /// 
            ///    [To be supplied.] 
            /// 
            public ListViewSubItem() { 
            } 

            ///  
            /// 
            ///    [To be supplied.]
            /// 
            public ListViewSubItem(ListViewItem owner, string text) { 
                this.owner = owner;
                this.text = text; 
            } 

            ///  
            /// 
            ///    [To be supplied.]
            /// 
            public ListViewSubItem(ListViewItem owner, string text, Color foreColor, Color backColor, Font font) { 
                this.owner = owner;
                this.text = text; 
                this.style = new SubItemStyle(); 
                this.style.foreColor = foreColor;
                this.style.backColor = backColor; 
                this.style.font = font;
            }

 
            /// 
            ///  
            ///    [To be supplied.] 
            /// 
            public Color BackColor { 
                get {
                    if (style != null && style.backColor != Color.Empty) {
                        return style.backColor;
                    } 

                    if (owner != null && owner.listView != null) { 
                        return owner.listView.BackColor; 
                    }
 
                    return SystemColors.Window;
                }
                set {
                    if (style == null) { 
                        style = new SubItemStyle();
                    } 
 
                    if (style.backColor != value) {
                        style.backColor = value; 
                        if (owner != null) {
                            owner.InvalidateListView();
                        }
                    } 
                }
            } 
            ///  
            [Browsable(false)]
            public Rectangle Bounds { 
                get {
                    if(owner != null && owner.listView != null && owner.listView.IsHandleCreated) {
                        return owner.listView.GetSubItemRect(owner.Index, owner.SubItems.IndexOf(this));
                    } else { 
                        return Rectangle.Empty;
                    } 
                } 
            }
 
            internal bool CustomBackColor {
                get {
                    return style != null && !style.backColor.IsEmpty;
                } 
            }
 
            internal bool CustomFont { 
                get {
                    return style != null && style.font != null; 
                }
            }

            internal bool CustomForeColor { 
                get {
                    return style != null && !style.foreColor.IsEmpty; 
                } 
            }
 
            internal bool CustomStyle {
                get {
                    return style != null;
                } 
            }
 
            ///  
            /// 
            ///    [To be supplied.] 
            /// 
            [
            Localizable(true)
            ] 
            public Font Font {
                get { 
                    if (style != null && style.font != null) { 
                        return style.font;
                    } 

                    if (owner != null && owner.listView != null) {
                        return owner.listView.Font;
                    } 

                    return Control.DefaultFont; 
                } 
                set {
                    if (style == null) { 
                        style = new SubItemStyle();
                    }

                    if (style.font != value) { 
                        style.font = value;
                        if (owner != null) { 
                            owner.InvalidateListView(); 
                        }
                    } 
                }
            }

            ///  
            /// 
            ///    [To be supplied.] 
            ///  
            public Color ForeColor {
                get { 
                    if (style != null && style.foreColor != Color.Empty) {
                        return style.foreColor;
                    }
 
                    if (owner != null && owner.listView != null) {
                        return owner.listView.ForeColor; 
                    } 

                    return SystemColors.WindowText; 
                }
                set {
                    if (style == null) {
                        style = new SubItemStyle(); 
                    }
 
                    if (style.foreColor != value) { 
                        style.foreColor = value;
                        if (owner != null) { 
                            owner.InvalidateListView();
                        }
                    }
                } 
            }
 
            ///  
            [
            SRCategory(SR.CatData), 
            Localizable(false),
            Bindable(true),
            SRDescription(SR.ControlTagDescr),
            DefaultValue(null), 
            TypeConverter(typeof(StringConverter)),
            ] 
            public object Tag { 
                get {
                    return userData; 
                }
                set {
                    userData = value;
                } 
            }
 
            ///  
            /// 
            ///    [To be supplied.] 
            /// 
            [
            Localizable(true)
            ] 
            public string Text {
                get { 
                    return text == null ? "" : text; 
                }
                set { 
                    text = value;
                    if (owner != null) {
                        owner.UpdateSubItems(-1);
                    } 
                }
            } 
 
            /// 
            ///  
            ///    [To be supplied.]
            /// 
            [
            Localizable(true) 
            ]
            public string Name { 
                get { 
                    return (name == null) ? "": name;
                } 
                set {
                    name = value;
                    if (owner != null) {
                        owner.UpdateSubItems(-1); 
                    }
                } 
            } 

            // 
            // Fix for Serialization Breaking change from v1.* to v2.0
            //
            // see http://devdiv/SpecTool/SHADOW/Documents/Whidbey/Versioning/VersionTolerantSerializationGuidelines(1.1).doc
            // 
            [OnDeserializing]
            private void OnDeserializing(StreamingContext ctx) { 
            } 

            [OnDeserialized] 
            [SuppressMessage("Microsoft.Performance", "CA1801:AvoidUnusedParameters")]
            private void OnDeserialized(StreamingContext ctx) {
                this.name = null;
                this.userData = null; 
            }
 
            [OnSerializing] 
            private void OnSerializing(StreamingContext ctx) {
            } 

            [OnSerialized]
            private void OnSerialized(StreamingContext ctx) {
            } 

            // 
            // End fix for Serialization Breaking change from v1.* to v2.0 
            //
 
            /// 
            /// 
            ///    [To be supplied.]
            ///  
            public void ResetStyle() {
                if (style != null) { 
                    style = null; 
                    if (owner != null) {
                        owner.InvalidateListView(); 
                    }
                }
            }
 
            /// 
            ///  
            ///    [To be supplied.] 
            /// 
            public override string ToString() { 
                return "ListViewSubItem: {" + Text + "}";
            }

            [Serializable] 
            private class SubItemStyle {
                public Color backColor = Color.Empty; 
                public Color foreColor = Color.Empty; 
                public Font font = null;
            } 
        }

        /// 
        ///  
        ///    [To be supplied.]
        ///  
        public class ListViewSubItemCollection : IList { 
            private ListViewItem owner;
 

            /// A caching mechanism for key accessor
            /// We use an index here rather than control so that we don't have lifetime
            /// issues by holding on to extra references. 
            private int lastAccessedIndex = -1;
 
 
            /// 
            ///  
            ///    [To be supplied.]
            /// 
            public ListViewSubItemCollection(ListViewItem owner) {
                this.owner = owner; 
            }
 
            ///  
            /// 
            ///     Returns the total number of items within the list view. 
            /// 
            [Browsable(false)]
            public int Count {
                get { 
                    return owner.SubItemCount;
                } 
            } 

            ///  
            /// 
            object ICollection.SyncRoot {
                get {
                    return this; 
                }
            } 
 
            /// 
            ///  
            bool ICollection.IsSynchronized {
                get {
                    return true;
                } 
            }
 
            ///  
            /// 
            bool IList.IsFixedSize { 
                get {
                    return false;
                }
            } 

            ///  
            ///  
            ///    [To be supplied.]
            ///  
            public bool IsReadOnly {
                get {
                    return false;
                } 
            }
 
            ///  
            /// 
            ///     Returns a ListViewSubItem given it's zero based index into the ListViewSubItemCollection. 
            /// 
            public ListViewSubItem this[int index] {
                get {
                    if (index < 0 || index >= Count) 
                        throw new ArgumentOutOfRangeException("index", SR.GetString(SR.InvalidArgument, "index", (index).ToString(CultureInfo.CurrentCulture)));
 
                    return owner.subItems[index]; 
                }
                set { 
                    if (index < 0 || index >= Count)
                        throw new ArgumentOutOfRangeException("index", SR.GetString(SR.InvalidArgument, "index", (index).ToString(CultureInfo.CurrentCulture)));

                    owner.subItems[index] = value; 
                    owner.UpdateSubItems(index);
                } 
            } 

            ///  
            /// 
            object IList.this[int index] {
                get {
                    return this[index]; 
                }
                set { 
                    if (value is ListViewSubItem) { 
                        this[index] = (ListViewSubItem)value;
                    } 
                    else {
                        throw new ArgumentException(SR.GetString(SR.ListViewBadListViewSubItem),"value");
                    }
                } 
            }
            ///  
            ///  
            ///     Retrieves the child control with the specified key.
            ///  
            public virtual ListViewSubItem this[string key] {
                get {
                    // We do not support null and empty string as valid keys.
                    if (string.IsNullOrEmpty(key)){ 
                        return null;
                    } 
 
                    // Search for the key in our collection
                    int index = IndexOfKey(key); 
                    if (IsValidIndex(index)) {
                        return this[index];
                    }
                    else { 
                        return null;
                    } 
 
                }
            } 

            /// 
            /// 
            ///    [To be supplied.] 
            /// 
            public ListViewSubItem Add(ListViewSubItem item) { 
                EnsureSubItemSpace(1, -1); 
                item.owner = this.owner;
                owner.subItems[owner.SubItemCount] = item; 
                owner.UpdateSubItems(owner.SubItemCount++);
                return item;
            }
 
            /// 
            public ListViewSubItem Add(string text) { 
                ListViewSubItem item = new ListViewSubItem(owner, text); 
                Add(item);
                return item; 
            }

            /// 
            public ListViewSubItem Add(string text, Color foreColor, Color backColor, Font font) { 
                ListViewSubItem item = new ListViewSubItem(owner, text, foreColor, backColor, font);
                Add(item); 
                return item; 
            }
 
            /// 
            public void AddRange(ListViewSubItem[] items) {
                if (items == null) {
                    throw new ArgumentNullException("items"); 
                }
                EnsureSubItemSpace(items.Length, -1); 
 
                foreach(ListViewSubItem item in items) {
                    if (item != null) { 
                        owner.subItems[owner.SubItemCount++] = item;
                    }
                }
 
                owner.UpdateSubItems(-1);
            } 
 
            /// 
            public void AddRange(string[] items) { 
                if (items == null) {
                    throw new ArgumentNullException("items");
                }
                EnsureSubItemSpace(items.Length, -1); 

                foreach(string item in items) { 
                    if (item != null) { 
                        owner.subItems[owner.SubItemCount++] = new ListViewSubItem(owner, item);
                    } 
                }

                owner.UpdateSubItems(-1);
            } 

            ///  
            public void AddRange(string[] items, Color foreColor, Color backColor, Font font) { 
                if (items == null) {
                    throw new ArgumentNullException("items"); 
                }
                EnsureSubItemSpace(items.Length, -1);

                foreach(string item in items) { 
                    if (item != null) {
                        owner.subItems[owner.SubItemCount++] = new ListViewSubItem(owner, item, foreColor, backColor, font); 
                    } 
                }
 
                owner.UpdateSubItems(-1);
            }

            ///  
            /// 
            int IList.Add(object item) { 
                if (item is ListViewSubItem) { 
                    return IndexOf(Add((ListViewSubItem)item));
                } 
                else {
                    throw new ArgumentException(SR.GetString(SR.ListViewSubItemCollectionInvalidArgument));
                }
            } 

            ///  
            ///  
            ///    [To be supplied.]
            ///  
            public void Clear() {
                int oldCount = owner.SubItemCount;
                if (oldCount > 0) {
                    owner.SubItemCount = 0; 
                    owner.UpdateSubItems(-1, oldCount);
                } 
            } 

            ///  
            /// 
            ///    [To be supplied.]
            /// 
            public bool Contains(ListViewSubItem subItem) { 
                return IndexOf(subItem) != -1;
            } 
 

            ///  
            /// 
            bool IList.Contains(object subItem) {
                if (subItem is ListViewSubItem) {
                    return Contains((ListViewSubItem)subItem); 
                }
                else { 
                    return false; 
                }
            } 

            /// 
            /// 
            ///     Returns true if the collection contains an item with the specified key, false otherwise. 
            /// 
            public virtual bool ContainsKey(string key) { 
                return IsValidIndex(IndexOfKey(key)); 
            }
 
            /// 
            ///     Ensures that the sub item array has the given
            ///     capacity.  If it doesn't, it enlarges the
            ///     array until it does.  If index is -1, additional 
            ///     space is tacked onto the end.  If it is a valid
            ///     insertion index into the array, this will move 
            ///     the array data to accomodate the space. 
            /// 
            private void EnsureSubItemSpace(int size, int index) { 

                // Range check subItems.
                if (owner.SubItemCount == ListViewItem.MAX_SUBITEMS) {
                    throw new InvalidOperationException(SR.GetString(SR.ErrorCollectionFull)); 
                }
 
                if (owner.SubItemCount + size > owner.subItems.Length) { 

                    // must grow array.  Don't do it just by size, though; 
                    // chunk it for efficiency.

                    if (owner.subItems == null) {
                        int newSize = (size > 4) ? size : 4; 
                        owner.subItems = new ListViewSubItem[newSize];
                    } 
                    else { 
                        int newSize = owner.subItems.Length * 2;
                        while(newSize - owner.SubItemCount < size) { 
                            newSize *= 2;
                        }

                        ListViewSubItem[] newItems = new ListViewSubItem[newSize]; 

                        // Now, when copying to the member variable, use index 
                        // if it was provided. 
                        //
                        if (index != -1) { 
                            Array.Copy(owner.subItems, 0, newItems, 0, index);
                            Array.Copy(owner.subItems, index, newItems, index + size, owner.SubItemCount - index);
                        }
                        else { 
                            Array.Copy(owner.subItems, newItems, owner.SubItemCount);
                        } 
                        owner.subItems = newItems; 
                    }
                } 
                else {

                    // We had plenty of room.  Just move the items if we need to
                    // 
                    if (index != -1) {
                        for(int i = owner.SubItemCount - 1; i >= index; i--) { 
                            owner.subItems[i + size] = owner.subItems[i]; 
                        }
                    } 
                }
            }

            ///  
            /// 
            ///    [To be supplied.] 
            ///  
            public int IndexOf(ListViewSubItem subItem) {
                for(int index=0; index < Count; ++index) { 
                    if (owner.subItems[index] == subItem) {
                        return index;
                    }
                } 
                return -1;
            } 
 
            /// 
            ///  
            int IList.IndexOf(object subItem) {
                if (subItem is ListViewSubItem) {
                    return IndexOf((ListViewSubItem)subItem);
                } 
                else {
                    return -1; 
                } 
            }
            ///  
            /// 
            ///     The zero-based index of the first occurrence of value within the entire CollectionBase, if found; otherwise, -1.
            /// 
            public virtual int  IndexOfKey(String key) { 
                  // Step 0 - Arg validation
                  if (string.IsNullOrEmpty(key)){ 
                        return -1; // we dont support empty or null keys. 
                  }
 
                // step 1 - check the last cached item
                if (IsValidIndex(lastAccessedIndex))
                {
                    if (WindowsFormsUtils.SafeCompareStrings(this[lastAccessedIndex].Name, key, /* ignoreCase = */ true)) { 
                        return lastAccessedIndex;
                    } 
                } 

                // step 2 - search for the item 
                for (int i = 0; i < this.Count; i ++) {
                    if (WindowsFormsUtils.SafeCompareStrings(this[i].Name, key, /* ignoreCase = */ true)) {
                        lastAccessedIndex = i;
                        return i; 
                    }
                } 
 
                // step 3 - we didn't find it.  Invalidate the last accessed index and return -1.
                lastAccessedIndex = -1; 
                return -1;
            }

            ///  
            /// 
            ///     Determines if the index is valid for the collection. 
            ///  
            /// 
            private bool IsValidIndex(int index) { 
                return ((index >= 0) && (index < this.Count));
            }

            ///  
            /// 
            ///    [To be supplied.] 
            ///  
            public void Insert(int index, ListViewSubItem item) {
 
                if (index < 0 || index > Count) {
                    throw new ArgumentOutOfRangeException("index");
                }
 
                item.owner = owner;
 
                EnsureSubItemSpace(1, index); 

                // Insert new item 
                //
                owner.subItems[index] = item;
                owner.SubItemCount++;
                owner.UpdateSubItems(-1); 
            }
 
            ///  
            /// 
            void IList.Insert(int index, object item) { 
                if (item is ListViewSubItem) {
                    Insert(index, (ListViewSubItem)item);
                }
                else { 
                    throw new ArgumentException(SR.GetString(SR.ListViewBadListViewSubItem),"item");
                } 
            } 

            ///  
            /// 
            ///    [To be supplied.]
            /// 
            public void Remove(ListViewSubItem item) { 
                int index = IndexOf(item);
                if (index != -1) { 
                    RemoveAt(index); 
                }
            } 

            /// 
            /// 
            void IList.Remove(object item) { 
                if (item is ListViewSubItem) {
                    Remove((ListViewSubItem)item); 
                } 
            }
 
            /// 
            /// 
            ///    [To be supplied.]
            ///  
            public void RemoveAt(int index) {
 
                if (index < 0 || index >= Count) { 
                    throw new ArgumentOutOfRangeException("index");
                } 

                // Collapse the items
                for (int i = index + 1; i < owner.SubItemCount; i++) {
                    owner.subItems[i - 1] = owner.subItems[i]; 
                }
 
                int oldCount = owner.SubItemCount; 
                owner.SubItemCount--;
                owner.subItems[owner.SubItemCount] = null; 
                owner.UpdateSubItems(-1, oldCount);
            }

          ///  
          /// 
          ///     Removes the child control with the specified key. 
          ///  
          public virtual void RemoveByKey(string key) {
                int index = IndexOfKey(key); 
                if (IsValidIndex(index)) {
                    RemoveAt(index);
                 }
           } 

            ///  
            ///  
            void ICollection.CopyTo(Array dest, int index) {
                if (Count > 0) { 
                    System.Array.Copy(owner.subItems, 0, dest, index, Count);
                }
            }
 
            /// 
            ///  
            ///    [To be supplied.] 
            /// 
            public IEnumerator GetEnumerator() { 
                if (owner.subItems != null) {
                    return new WindowsFormsUtils.ArraySubsetEnumerator(owner.subItems, owner.SubItemCount);
                }
                else 
                {
                    return new ListViewSubItem[0].GetEnumerator(); 
                } 

            } 
        }
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

/* 
 */ 
namespace System.Windows.Forms {
    using System.Runtime.Serialization; 
    using System.Runtime.Serialization.Formatters;

    using System.Diagnostics;
    using System.Diagnostics.CodeAnalysis; 
    using System.Security;
    using System.Security.Permissions; 
    using System; 
    using System.Drawing;
    using System.Drawing.Design; 
    using System.ComponentModel;
    using System.IO;
    using Microsoft.Win32;
    using System.Collections; 
    using System.Collections.Specialized;
    using System.Runtime.Remoting; 
    using System.Runtime.InteropServices; 
    using System.ComponentModel.Design.Serialization;
    using System.Reflection; 
    using System.Globalization;

    /// 
    ///  
    ///    
    ///       Implements an item of a . 
    ///     
    /// 
    [ 
    TypeConverterAttribute(typeof(ListViewItemConverter)),
    ToolboxItem(false),
    DesignTimeVisible(false),
    DefaultProperty("Text"), 
    Serializable,
    SuppressMessage("Microsoft.Usage", "CA2240:ImplementISerializableCorrectly") 
    ] 
    public class ListViewItem : ICloneable, ISerializable {
 
        private const int MAX_SUBITEMS = 4096;

        private static readonly BitVector32.Section StateSelectedSection         = BitVector32.CreateSection(1);
        private static readonly BitVector32.Section StateImageMaskSet            = BitVector32.CreateSection(1, StateSelectedSection); 
        private static readonly BitVector32.Section StateWholeRowOneStyleSection = BitVector32.CreateSection(1, StateImageMaskSet);
        private static readonly BitVector32.Section SavedStateImageIndexSection  = BitVector32.CreateSection(15, StateWholeRowOneStyleSection); 
        private static readonly BitVector32.Section SubItemCountSection          = BitVector32.CreateSection(MAX_SUBITEMS, SavedStateImageIndexSection); 

        private int indentCount = 0; 
        private Point position = new Point(-1,-1);

        internal ListView listView;
 
        internal ListViewGroup group;
        private string groupName; 
 
        private ListViewSubItemCollection listViewSubItemCollection = null;
        private ListViewSubItem[] subItems; 

        // we stash the last index we got as a seed to GetDisplayIndex.
        private int lastIndex = -1;
 
        // An ID unique relative to a given list view that comctl uses to identify items.
        internal int ID = -1; 
 
        private BitVector32 state = new BitVector32();
        private ListViewItemImageIndexer imageIndexer; 
        private String toolTipText = String.Empty;
        object userData;

        // We need a special way to defer to the ListView's image 
        // list for indexing purposes.
        internal class ListViewItemImageIndexer : ImageList.Indexer { 
           private ListViewItem owner; 

 
           /// 
            public ListViewItemImageIndexer(ListViewItem item) {
              owner = item;
            } 

 
           public override ImageList ImageList { 
                get {
                        if (owner != null) { 
                            return owner.ImageList;
                        }
                        return null;
                    } 
                set { Debug.Assert(false, "We should never set the image list"); }
            } 
        } 

 
        /// 
        /// 
        ///    [To be supplied.]
        ///  
        public ListViewItem() {
            StateSelected = false; 
            UseItemStyleForSubItems = true; 
            SavedStateImageIndex = -1;
        } 

        /// 
        /// 
        ///     Creates a ListViewItem object from an Stream. 
        ///     The Serialization constructor is protected, as per FxCop Microsoft.Usage, CA2229 Rule.
        ///  
        [ 
            SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")  // Changing Deserialize to be non-virtual
                                                                                                    // would be a breaking change. 
        ]
        protected ListViewItem(SerializationInfo info, StreamingContext context) : this() {
            Deserialize(info, context);
        } 

        ///  
        ///  
        ///    [To be supplied.]
        ///  
        public ListViewItem(string text) : this(text, -1) {
        }

        ///  
        /// 
        ///    [To be supplied.] 
        ///  
        public ListViewItem(string text, int imageIndex) : this() {
            this.ImageIndexer.Index = imageIndex; 
            Text = text;
        }

        ///  
        /// 
        ///    [To be supplied.] 
        ///  
        public ListViewItem(string[] items) : this(items, -1) {
        } 

        /// 
        /// 
        ///    [To be supplied.] 
        /// 
        public ListViewItem(string[] items, int imageIndex) : this() { 
 
            this.ImageIndexer.Index = imageIndex;
            if (items != null && items.Length > 0) { 
                this.subItems = new ListViewSubItem[items.Length];
                for (int i = 0; i < items.Length; i++) {
                    subItems[i] = new ListViewSubItem(this, items[i]);
                } 
                this.SubItemCount = items.Length;
            } 
        } 

        ///  
        /// 
        ///    [To be supplied.]
        /// 
        public ListViewItem(string[] items, int imageIndex, Color foreColor, Color backColor, Font font) : this(items, imageIndex) { 
            this.ForeColor = foreColor;
            this.BackColor = backColor; 
            this.Font = font; 
        }
 
        /// 
        /// 
        ///    [To be supplied.]
        ///  
        public ListViewItem(ListViewSubItem[] subItems, int imageIndex) : this() {
 
            this.ImageIndexer.Index = imageIndex; 
            this.subItems = subItems;
            this.SubItemCount = this.subItems.Length; 

            // Update the owner of these subitems
            //
            for(int i=0; i < subItems.Length; ++i) { 
                subItems[i].owner = this;
            } 
        } 

        ///  
        /// 
        ///    [To be supplied.]
        /// 
        public ListViewItem(ListViewGroup group) : this() { 
            this.Group = group;
        } 
 
        /// 
        ///  
        ///    [To be supplied.]
        /// 
        public ListViewItem(string text, ListViewGroup group) : this(text) {
            this.Group = group; 
        }
 
        ///  
        /// 
        ///    [To be supplied.] 
        /// 
        public ListViewItem(string text, int imageIndex, ListViewGroup group) : this(text, imageIndex) {
            this.Group = group;
        } 

        ///  
        ///  
        ///    [To be supplied.]
        ///  
        public ListViewItem(string[] items, ListViewGroup group) : this(items) {
            this.Group = group;
        }
 
        /// 
        ///  
        ///    [To be supplied.] 
        /// 
        public ListViewItem(string[] items, int imageIndex, ListViewGroup group) : this(items, imageIndex) { 
            this.Group = group;
        }

        ///  
        /// 
        ///    [To be supplied.] 
        ///  
        public ListViewItem(string[] items, int imageIndex, Color foreColor, Color backColor, Font font, ListViewGroup group) :
            this(items, imageIndex, foreColor, backColor, font) { 
            this.Group = group;
        }

        ///  
        /// 
        ///    [To be supplied.] 
        ///  
        public ListViewItem(ListViewSubItem[] subItems, int imageIndex, ListViewGroup group) : this(subItems, imageIndex) {
            this.Group = group; 
        }

        /// 
        ///  
        ///    [To be supplied.]
        ///  
        public ListViewItem(string text, string imageKey) : this() { 
            this.ImageIndexer.Key = imageKey;
            Text = text; 
        }

        /// 
        ///  
        ///    [To be supplied.]
        ///  
        public ListViewItem(string[] items, string imageKey) : this() { 

            this.ImageIndexer.Key = imageKey; 
            if (items != null && items.Length > 0) {
                this.subItems = new ListViewSubItem[items.Length];
                for (int i = 0; i < items.Length; i++) {
                    subItems[i] = new ListViewSubItem(this, items[i]); 
                }
                this.SubItemCount = items.Length; 
            } 
        }
 
        /// 
        /// 
        ///    [To be supplied.]
        ///  
        public ListViewItem(string[] items, string imageKey, Color foreColor, Color backColor, Font font) : this(items, imageKey) {
            this.ForeColor = foreColor; 
            this.BackColor = backColor; 
            this.Font = font;
        } 

        /// 
        /// 
        ///    [To be supplied.] 
        /// 
        public ListViewItem(ListViewSubItem[] subItems, string imageKey) : this() { 
 
            this.ImageIndexer.Key = imageKey;
            this.subItems = subItems; 
            this.SubItemCount = this.subItems.Length;

            // Update the owner of these subitems
            // 
            for(int i=0; i < subItems.Length; ++i) {
                subItems[i].owner = this; 
            } 
        }
 
        /// 
        /// 
        ///    [To be supplied.]
        ///  
        public ListViewItem(string text, string imageKey, ListViewGroup group) : this(text, imageKey) {
            this.Group = group; 
        } 

        ///  
        /// 
        ///    [To be supplied.]
        /// 
        public ListViewItem(string[] items, string imageKey, ListViewGroup group) : this(items, imageKey) { 
            this.Group = group;
        } 
 
        /// 
        ///  
        ///    [To be supplied.]
        /// 
        public ListViewItem(string[] items, string imageKey, Color foreColor, Color backColor, Font font, ListViewGroup group) :
            this(items, imageKey, foreColor, backColor, font) { 
            this.Group = group;
        } 
 
        /// 
        ///  
        ///    [To be supplied.]
        /// 
        public ListViewItem(ListViewSubItem[] subItems, string imageKey, ListViewGroup group) : this(subItems, imageKey) {
            this.Group = group; 
        }
 
        ///  
        /// 
        ///     The font that this item will be displayed in. If its value is null, it will be displayed 
        ///     using the global font for the ListView control that hosts it.
        /// 
        [
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), 
        SRCategory(SR.CatAppearance)
        ] 
        public Color BackColor { 
            get {
                if (SubItemCount == 0) { 
                    if (listView != null) {
                        return listView.BackColor;
                    }
                    return SystemColors.Window; 
                }
                else { 
                    return subItems[0].BackColor; 
                }
            } 
            set {
                SubItems[0].BackColor = value;
            }
        } 

        ///  
        ///  
        ///     Returns the ListViewItem's bounding rectangle, including subitems. The bounding rectangle is empty if
        ///     the ListViewItem has not been added to a ListView control. 
        /// 
        [Browsable(false)]
        public Rectangle Bounds {
            get { 
                if (listView != null) {
                    return listView.GetItemRect(Index); 
                } 
                else
                    return new Rectangle(); 
            }
        }

        ///  
        /// 
        ///    [To be supplied.] 
        ///  
        [
        DefaultValue(false), 
        RefreshPropertiesAttribute(RefreshProperties.Repaint),
        SRCategory(SR.CatAppearance)
        ]
        public bool Checked { 
            get {
                return StateImageIndex > 0; 
            } 

            set { 
                if (Checked != value) {
                    if (listView != null && listView.IsHandleCreated) {
                        StateImageIndex = value ? 1 : 0;
 
                        // the setter for StateImageIndex calls ItemChecked handler
                        // thus need to verify validity of the listView again 
                        if ((this.listView != null) && !this.listView.UseCompatibleStateImageBehavior) { 
                            if (!listView.CheckBoxes) {
                                listView.UpdateSavedCheckedItems(this, value); 
                            }
                        }

                    } 
                    else {
                        SavedStateImageIndex = value ? 1 : 0; 
                    } 
                }
            } 
        }

        /// 
        ///  
        ///     Returns the focus state of the ListViewItem.
        ///  
        [ 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
        Browsable(false) 
        ]
        public bool Focused {
            get {
                if (listView != null && listView.IsHandleCreated) { 
                    return(listView.GetItemState(Index, NativeMethods.LVIS_FOCUSED) != 0);
                } 
                else return false; 
            }
 
            set {
                if (listView != null && listView.IsHandleCreated) {
                    listView.SetItemState(Index, value ? NativeMethods.LVIS_FOCUSED : 0, NativeMethods.LVIS_FOCUSED);
                } 
            }
        } 
 
        /// 
        ///  
        ///    [To be supplied.]
        /// 
        [
        Localizable(true), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
        SRCategory(SR.CatAppearance) 
        ] 
        public Font Font {
            get { 
                if (SubItemCount == 0) {
                    if (listView != null) {
                        return listView.Font;
                    } 
                    return Control.DefaultFont;
                } 
                else { 
                    return subItems[0].Font;
                } 
            }
            set {
                SubItems[0].Font = value;
            } 
        }
 
        ///  
        /// 
        ///    [To be supplied.] 
        /// 
        [
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
        SRCategory(SR.CatAppearance) 
        ]
        public Color ForeColor { 
            get { 
                if (SubItemCount == 0) {
                    if (listView != null) { 
                        return listView.ForeColor;
                    }
                    return SystemColors.WindowText;
                } 
                else {
                    return subItems[0].ForeColor; 
                } 
            }
            set { 
                SubItems[0].ForeColor = value;
            }
        }
 
        /// 
        ///  
        ///    The group to which this item belongs 
        /// 
        [ 
            DefaultValue(null),
            Localizable(true),
            SRCategory(SR.CatBehavior)
        ] 
        public ListViewGroup Group {
            get 
            { 
                return group;
            } 
            set
            {
                if (group != value) {
                    if (value != null) { 
                        value.Items.Add(this);
                    } 
                    else { 
                        group.Items.Remove(this);
                    } 
                }
                Debug.Assert(this.group == value, "BUG: group member variable wasn't updated!");

                // If the user specifically sets the group then don't use the groupName again. 
                this.groupName = null;
            } 
        } 

        ///  
        /// 
        ///     Returns the ListViewItem's currently set image index
        /// 
        [ 
        DefaultValue(-1),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), 
        Editor("System.Windows.Forms.Design.ImageIndexEditor, " + AssemblyRef.SystemDesign, typeof(UITypeEditor)), 
        Localizable(true),
        RefreshProperties(RefreshProperties.Repaint), 
        SRCategory(SR.CatBehavior),
        SRDescription(SR.ListViewItemImageIndexDescr),
        TypeConverterAttribute(typeof(NoneExcludedImageIndexConverter))
        ] 
        public int ImageIndex {
            get { 
                if (ImageIndexer.Index != -1 && ImageList != null && ImageIndexer.Index >= ImageList.Images.Count) { 
                    return ImageList.Images.Count - 1;
                } 
                return this.ImageIndexer.Index;
            }
            set {
                if (value < -1) { 
                    throw new ArgumentOutOfRangeException("ImageIndex", SR.GetString(SR.InvalidLowBoundArgumentEx, "ImageIndex", value.ToString(CultureInfo.CurrentCulture), (-1).ToString(CultureInfo.CurrentCulture)));
                } 
 
                ImageIndexer.Index = value;
 
                if (listView != null && listView.IsHandleCreated) {
                    listView.SetItemImage(Index, ImageIndexer.ActualIndex);
               }
            } 
        }
 
        internal ListViewItemImageIndexer ImageIndexer { 
            get {
                if (imageIndexer == null)  { 
                    imageIndexer = new ListViewItemImageIndexer(this);
                }
                return imageIndexer;
            } 
        }
 
        ///  
        /// 
        ///     Returns the ListViewItem's currently set image index 
        /// 
        [
        DefaultValue(""),
        TypeConverterAttribute(typeof(ImageKeyConverter)), 
        Editor("System.Windows.Forms.Design.ImageIndexEditor, " + AssemblyRef.SystemDesign, typeof(UITypeEditor)),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), 
        RefreshProperties(RefreshProperties.Repaint), 
        SRCategory(SR.CatBehavior),
        Localizable(true) 
        ]
        public string ImageKey {
            get {
                return this.ImageIndexer.Key; 
            }
            set { 
                   ImageIndexer.Key = value; 

                   if (listView != null && listView.IsHandleCreated) { 
                    listView.SetItemImage(Index, ImageIndexer.ActualIndex);
                   }
            }
        } 

        ///  
        [Browsable(false)] 
        public ImageList ImageList {
            get { 
                if (listView != null) {
                    switch(listView.View) {
                        case View.LargeIcon:
                        case View.Tile: 
                            return listView.LargeImageList;
                        case View.SmallIcon: 
                        case View.Details: 
                        case View.List:
                            return listView.SmallImageList; 
                    }
                }
                return null;
            } 
        }
 
        ///  
        [
        DefaultValue(0), 
        SRDescription(SR.ListViewItemIndentCountDescr),
        SRCategory(SR.CatDisplay)
        ]
        public int IndentCount { 
            get {
                return indentCount; 
            } 
            set {
                if (value == indentCount) 
                    return;
                if (value < 0) {
                    throw new ArgumentOutOfRangeException("IndentCount", SR.GetString(SR.ListViewIndentCountCantBeNegative));
                } 
                indentCount = value;
                if (listView != null && listView.IsHandleCreated) { 
                    listView.SetItemIndentCount(Index, indentCount); 
                }
            } 
        }


        ///  
        /// 
        ///     Returns ListViewItem's current index in the listview, or -1 if it has not been added to a ListView control. 
        ///  
        [Browsable(false)]
        public int Index { 
            get {
                if (listView != null) {
                    // if the list is virtual, the ComCtrl control does not keep any information
                    // about any list view items, so we use our cache instead. 
                    if (!listView.VirtualMode) {
                        lastIndex = listView.GetDisplayIndex(this, lastIndex); 
                    } 
                    return lastIndex;
                } 
                else {
                    return -1;
                }
            } 
        }
 
        ///  
        /// 
        /// Returns the ListView control that holds this ListViewItem. May be null if no 
        /// control has been assigned yet.
        /// 
        [Browsable(false)]
        public ListView ListView { 
            get {
                return listView; 
            } 
        }
 

        /// 
        /// 
        ///     Name associated with this ListViewItem 
        /// 
        [ 
        Localizable(true), 
        Browsable(false),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) 
        ]
        public string Name {
            get {
                if (SubItemCount == 0) { 
                    return string.Empty;
                } 
                else { 
                    return subItems[0].Name;
                } 
            }
            set {
                SubItems[0].Name = value;
            } 
        }
 
        ///  
        [
        SRCategory(SR.CatDisplay), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
        Browsable(false)
        ]
        public Point Position { 
            get {
                if (listView != null && listView.IsHandleCreated) { 
                    position = listView.GetItemPosition(Index); 
                }
                return position; 
            }
            set {
                if (value.Equals(position))
                    return; 
                position = value;
                if (listView != null && listView.IsHandleCreated) { 
                    if (!listView.VirtualMode) { 
                        listView.SetItemPosition(Index, position.X, position.Y);
                    } 
                }
            }
        }
 
        // the listView needs the raw encoding for the state image index when in VirtualMode
        internal int RawStateImageIndex { 
            get { 
                return (this.SavedStateImageIndex + 1) << 12;
            } 
        }

        /// 
        ///     Accessor for our state bit vector. 
        /// 
        private int SavedStateImageIndex { 
            get { 
                // State goes from zero to 15, but we need a negative
                // number, so we store + 1. 
                return state[SavedStateImageIndexSection] - 1;
            }
            set {
                // flag whether we've set a value. 
                //
                state[StateImageMaskSet] = (value == -1 ? 0 : 1); 
 
                // push in the actual value
                // 
                state[SavedStateImageIndexSection] = value + 1;
            }
        }
 
        /// 
        ///  
        ///     Treats the ListViewItem as a row of strings, and returns an array of those strings 
        /// 
        [ 
        Browsable(false),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
        ]
        public bool Selected { 
            get {
                if (listView != null && listView.IsHandleCreated) { 
                    return(listView.GetItemState(Index, NativeMethods.LVIS_SELECTED) != 0); 
                }
                else 
                    return StateSelected;
            }
            set {
                if (listView != null && listView.IsHandleCreated) { 
                    listView.SetItemState(Index, value ? NativeMethods.LVIS_SELECTED: 0, NativeMethods.LVIS_SELECTED);
 
                    // vsw 451976: update comctl32's selection information. 
                    listView.SetSelectionMark(Index);
                } 
                else {
                    StateSelected = value;
                    if (this.listView != null && this.listView.IsHandleCreated) {
                        // APPCOMPAT: set the selected state on the list view item only if the list view's Handle is already created. 
                        // vsw 448052.
                        listView.CacheSelectedStateForItem(this, value); 
                    } 
                }
            } 
        }

        /// 
        ///  
        ///    [To be supplied.]
        ///  
        [ 
        Localizable(true),
        TypeConverterAttribute(typeof(NoneExcludedImageIndexConverter)), 
        DefaultValue(-1),
        SRDescription(SR.ListViewItemStateImageIndexDescr),
        SRCategory(SR.CatBehavior),
        RefreshProperties(RefreshProperties.Repaint), 
        Editor("System.Windows.Forms.Design.ImageIndexEditor, " + AssemblyRef.SystemDesign, typeof(UITypeEditor)),
        RelatedImageList("ListView.StateImageList") 
        ] 
        public int StateImageIndex {
            get { 
                if (listView != null && listView.IsHandleCreated) {
                    int state = listView.GetItemState(Index, NativeMethods.LVIS_STATEIMAGEMASK);
                    return ((state >> 12) - 1);   // index is 1-based
                } 
                else return SavedStateImageIndex;
            } 
            set { 
                if (value < -1 || value > 14)
                    throw new ArgumentOutOfRangeException("StateImageIndex", SR.GetString(SR.InvalidArgument, "StateImageIndex", (value).ToString(CultureInfo.CurrentCulture))); 

                if (listView != null && listView.IsHandleCreated) {
                    this.state[StateImageMaskSet] = (value == -1 ? 0 : 1);
                    int state = ((value + 1) << 12);  // index is 1-based 
                    listView.SetItemState(Index, state, NativeMethods.LVIS_STATEIMAGEMASK);
                } 
                SavedStateImageIndex = value; 
            }
        } 


        internal bool StateImageSet {
            get { 
                return (this.state[StateImageMaskSet] != 0);
            } 
        } 

 
        /// 
        ///     Accessor for our state bit vector.
        /// 
        internal bool StateSelected { 
            get {
                return state[StateSelectedSection] == 1; 
            } 
            set {
                state[StateSelectedSection] = value ? 1 : 0; 
            }
        }

        ///  
        ///     Accessor for our state bit vector.
        ///  
        private int SubItemCount { 
            get {
                return state[SubItemCountSection]; 
            }
            set {
                state[SubItemCountSection] = value;
            } 
        }
 
        ///  
        /// 
        ///    [To be supplied.] 
        /// 
        [
        SRCategory(SR.CatData),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), 
        SRDescription(SR.ListViewItemSubItemsDescr),
        Editor("System.Windows.Forms.Design.ListViewSubItemCollectionEditor, " + AssemblyRef.SystemDesign,typeof(UITypeEditor)), 
        ] 
        public ListViewSubItemCollection SubItems {
            get { 
                if (SubItemCount == 0) {
                    subItems = new ListViewSubItem[1];
                    subItems[0] = new ListViewSubItem(this, string.Empty);
                    SubItemCount = 1; 
                }
 
                if (listViewSubItemCollection == null) { 
                    listViewSubItemCollection = new ListViewSubItemCollection(this);
                } 
                return listViewSubItemCollection;
            }
        }
 
        /// 
        [ 
        SRCategory(SR.CatData), 
        Localizable(false),
        Bindable(true), 
        SRDescription(SR.ControlTagDescr),
        DefaultValue(null),
        TypeConverter(typeof(StringConverter)),
        ] 
        public object Tag {
            get { 
                return userData; 
            }
            set { 
                userData = value;
            }
        }
 
        /// 
        ///  
        ///     Text associated with this ListViewItem 
        /// 
        [ 
        Localizable(true),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
        SRCategory(SR.CatAppearance)
        ] 
        public string Text {
            get { 
                if (SubItemCount == 0) { 
                    return string.Empty;
                } 
                else {
                    return subItems[0].Text;
                }
            } 
            set {
                SubItems[0].Text = value; 
            } 
        }
 
        /// 
        /// 
        ///     Tool tip text associated with this ListViewItem
        ///  
        [
        SRCategory(SR.CatAppearance), 
        DefaultValue("") 
        ]
        public string ToolTipText { 
            get {
                return toolTipText;
            }
            set { 
                if (value == null)
                    value = String.Empty; 
                if (WindowsFormsUtils.SafeCompareStrings(toolTipText, value, false /*ignoreCase*/)) { 
                    return;
                } 

                toolTipText = value;

                // tell the list view about this change 
                if (this.listView != null && this.listView.IsHandleCreated) {
                    this.listView.ListViewItemToolTipChanged(this); 
                } 
            }
        } 

        /// 
        /// 
        ///     Whether or not the font and coloring for the ListViewItem will be used for all of its subitems. 
        ///     If true, the ListViewItem style will be used when drawing the subitems.
        ///     If false, the ListViewItem and its subitems will be drawn in their own individual styles 
        ///     if any have been set. 
        /// 
        [ 
        DefaultValue(true),
        SRCategory(SR.CatAppearance)
        ]
        public bool UseItemStyleForSubItems { 
            get {
                return state[StateWholeRowOneStyleSection] == 1; 
            } 
            set {
                state[StateWholeRowOneStyleSection] = value ? 1 : 0; 
            }
        }

        ///  
        /// 
        ///     Initiate editing of the item's label. 
        ///     Only effective if LabelEdit property is true. 
        /// 
        public void BeginEdit() { 
            if (Index >= 0) {
                ListView lv = ListView;
                if (lv.LabelEdit == false)
                    throw new InvalidOperationException(SR.GetString(SR.ListViewBeginEditFailed)); 
                if (!lv.Focused)
                    lv.FocusInternal(); 
                UnsafeNativeMethods.SendMessage(new HandleRef(lv, lv.Handle), NativeMethods.LVM_EDITLABEL, Index, 0); 
            }
        } 

        /// 
        /// 
        ///    [To be supplied.] 
        /// 
        public virtual object Clone() { 
            ListViewSubItem[] clonedSubItems = new ListViewSubItem[this.SubItems.Count]; 
            for(int index=0; index < this.SubItems.Count; ++index) {
                ListViewSubItem subItem = this.SubItems[index]; 
                clonedSubItems[index] = new ListViewSubItem(null,
                                                            subItem.Text,
                                                            subItem.ForeColor,
                                                            subItem.BackColor, 
                                                            subItem.Font);
                clonedSubItems[index].Tag = subItem.Tag; 
            } 

            Type clonedType = this.GetType(); 
            ListViewItem newItem = null;

            if (clonedType == typeof(ListViewItem)) {
                newItem = new ListViewItem(clonedSubItems, this.ImageIndexer.Index); 
            }
            else { 
                // SECREVIEW : Late-binding does not represent a security thread, see bug#411899 for more info.. 
                //
                newItem = (ListViewItem)Activator.CreateInstance(clonedType); 
            }
            newItem.subItems = clonedSubItems;
            newItem.ImageIndexer.Index = this.ImageIndexer.Index;
            newItem.SubItemCount = this.SubItemCount; 
            newItem.Checked = this.Checked;
            newItem.UseItemStyleForSubItems = this.UseItemStyleForSubItems; 
            newItem.Tag = this.Tag; 

            // Only copy over the ImageKey if we're using it. 
            if (!String.IsNullOrEmpty(this.ImageIndexer.Key)) {
                newItem.ImageIndexer.Key = this.ImageIndexer.Key;
            }
 
            newItem.indentCount = this.indentCount;
            newItem.StateImageIndex = this.StateImageIndex; 
            newItem.toolTipText = this.toolTipText; 
            newItem.BackColor = this.BackColor;
            newItem.ForeColor = this.ForeColor; 
            newItem.Font = this.Font;
            newItem.Text = this.Text;
            newItem.Group = this.Group;
 
            return newItem;
        } 
 
        /// 
        ///  
        ///     Ensure that the item is visible, scrolling the view as necessary.
        /// 
        public virtual void EnsureVisible() {
            if (listView != null && listView.IsHandleCreated) { 
                listView.EnsureVisible(Index);
            } 
        } 

        ///  
        public ListViewItem FindNearestItem(SearchDirectionHint searchDirection) {
            Rectangle r = this.Bounds;

            switch (searchDirection) { 
                case SearchDirectionHint.Up:
                    return this.ListView.FindNearestItem(searchDirection, r.Left, r.Top); 
                case SearchDirectionHint.Down: 
                    return this.ListView.FindNearestItem(searchDirection, r.Left, r.Bottom);
                case SearchDirectionHint.Left: 
                    return this.ListView.FindNearestItem(searchDirection, r.Left, r.Top);
                case SearchDirectionHint.Right:
                    return this.ListView.FindNearestItem(searchDirection, r.Right, r.Top);
                default : 
                    Debug.Fail("we handled all the 4 directions");
                    return null; 
            } 
        }
 
        /// 
        /// 
        ///     Returns a specific portion of the ListViewItem's bounding rectangle.
        ///     The rectangle returned is empty if the ListViewItem has not been added to a ListView control. 
        /// 
        public Rectangle GetBounds(ItemBoundsPortion portion) { 
            if (listView != null && listView.IsHandleCreated) { 
                return listView.GetItemRect(Index, portion);
            } 
            else return new Rectangle();
        }

        ///  
        public ListViewSubItem GetSubItemAt(int x, int y) {
            if (listView != null && listView.IsHandleCreated && listView.View == View.Details) { 
                int iItem = -1; 
                int iSubItem = -1;
 
                listView.GetSubItemAt(x,y, out iItem, out iSubItem);

                // bug in commctl list view:
                // if the user clicks to the RIGHT of the last subitem the commctl returns the index of the subitem which would have fit there 
                // we have to check if iSubItem falls in the sub item collection
                if (iItem == this.Index && iSubItem != -1 && iSubItem < SubItems.Count) { 
                    return SubItems[iSubItem]; 
                } else {
                    return null; 
                }
            } else {
                return null;
            } 
        }
 
        ///  
        /// 
        ///  
        /// 
        internal void Host(ListView parent, int ID, int index) {
            // Don't let the name "host" fool you -- Handle is not necessarily created
            Debug.Assert(this.listView == null || !this.listView.VirtualMode, "ListViewItem::Host can't be used w/ a virtual item"); 
            Debug.Assert(parent == null || !parent.VirtualMode, "ListViewItem::Host can't be used w/ a virtual list");
 
            this.ID = ID; 
            listView = parent;
 
            // If the index is valid, then the handle has been created.
            if (index != -1) {
                UpdateStateToListView(index);
            } 
        }
 
        ///  
        ///     This is used to map list view items w/ their respective groups
        ///     in localized forms. 
        /// 
        internal void UpdateGroupFromName() {
            Debug.Assert(this.listView != null, "This method is used only when items are parented in a list view");
            Debug.Assert(!this.listView.VirtualMode, "we need to update the group only when the user specifies the list view items in localizable forms"); 
            if (String.IsNullOrEmpty(this.groupName)) {
                return; 
            } 

            ListViewGroup group = this.listView.Groups[this.groupName]; 
            this.Group = group;

            // Use the group name only once.
            this.groupName = null; 
        }
 
        internal void UpdateStateToListView(int index) { 
            NativeMethods.LVITEM lvItem = new NativeMethods.LVITEM();
            UpdateStateToListView(index, ref lvItem, true); 
        }

        /// 
        ///     Called when we have just pushed this item into a list view and we need 
        ///     to configure the list view's state for the item.  Use a valid index
        ///     if you can, or use -1 if you can't. 
        ///  
        internal void UpdateStateToListView(int index, ref NativeMethods.LVITEM lvItem, bool updateOwner) {
 
            Debug.Assert(listView.IsHandleCreated, "Should only invoke UpdateStateToListView when handle is created.");

            if (index == -1) {
                index = Index; 
            }
            else { 
                lastIndex = index; 
            }
 
            // Update Item state in one shot
            //
            int itemState = 0;
            int stateMask = 0; 

            if (StateSelected) { 
                itemState |= NativeMethods.LVIS_SELECTED; 
                stateMask |= NativeMethods.LVIS_SELECTED;
            } 

            if (SavedStateImageIndex > -1) {
                itemState |= ((SavedStateImageIndex + 1) << 12);
                stateMask |= NativeMethods.LVIS_STATEIMAGEMASK; 
            }
 
            lvItem.mask |= NativeMethods.LVIF_STATE; 
            lvItem.iItem = index;
            lvItem.stateMask |= stateMask; 
            lvItem.state |= itemState;

            if (listView.GroupsEnabled) {
                lvItem.mask |= NativeMethods.LVIF_GROUPID; 
                lvItem.iGroupId = listView.GetNativeGroupId(this);
 
                Debug.Assert(!updateOwner || listView.SendMessage(NativeMethods.LVM_ISGROUPVIEWENABLED, 0, 0) != IntPtr.Zero, "Groups not enabled"); 
                Debug.Assert(!updateOwner || listView.SendMessage(NativeMethods.LVM_HASGROUP, lvItem.iGroupId, 0) != IntPtr.Zero, "Doesn't contain group id: " + lvItem.iGroupId.ToString(CultureInfo.InvariantCulture));
            } 

            if (updateOwner) {
                UnsafeNativeMethods.SendMessage(new HandleRef(listView, listView.Handle), NativeMethods.LVM_SETITEM, 0, ref lvItem);
            } 
        }
 
        internal void UpdateStateFromListView(int displayIndex, bool checkSelection) { 
            if (listView != null && listView.IsHandleCreated && displayIndex != -1) {
 
                // Get information from comctl control
                //
                NativeMethods.LVITEM lvItem = new NativeMethods.LVITEM();
                lvItem.mask = NativeMethods.LVIF_PARAM | NativeMethods.LVIF_STATE | NativeMethods.LVIF_GROUPID; 

                if (checkSelection) { 
                    lvItem.stateMask = NativeMethods.LVIS_SELECTED; 
                }
 

                // we want to get all the information, including the state image mask
                lvItem.stateMask |= NativeMethods.LVIS_STATEIMAGEMASK;
 
                if (lvItem.stateMask == 0) {
                    // perf optimization: no work to do. 
                    // 
                    return;
                } 


                lvItem.iItem = displayIndex;
                UnsafeNativeMethods.SendMessage(new HandleRef(listView, listView.Handle), NativeMethods.LVM_GETITEM, 0, ref lvItem); 

                // Update this class' information 
                // 
                if (checkSelection) {
                    StateSelected = (lvItem.state & NativeMethods.LVIS_SELECTED) != 0; 
                }
                SavedStateImageIndex = ((lvItem.state & NativeMethods.LVIS_STATEIMAGEMASK) >> 12) - 1;

                // a-jegros: bug 154131 - group needs to be updated, too! 
                group = null;
                foreach (ListViewGroup lvg in ListView.Groups) { 
                    if (lvg.ID == lvItem.iGroupId) { 
                        group = lvg;
                        break; 
                    }
                }
            }
        } 

        ///  
        ///  
        /// 
        ///  
        internal void UnHost(bool checkSelection) {
            UnHost(Index, checkSelection);
        }
 
        internal void UnHost(int displayIndex, bool checkSelection) {
            UpdateStateFromListView(displayIndex, checkSelection); 
 
            if (this.listView != null && (this.listView.Site == null || !this.listView.Site.DesignMode) && this.group != null) {
                this.group.Items.Remove(this); 
            }

            // Make sure you do these last, as the first several lines depends on this information
            ID = -1; 
            listView = null;
        } 
 
        /// 
        ///  
        ///    [To be supplied.]
        /// 
        public virtual void Remove() {
            if (listView != null) { 
                listView.Items.Remove(this);
            } 
        } 

        ///  
        /// 
        ///    [To be supplied.]
        /// 
        protected virtual void Deserialize(SerializationInfo info, StreamingContext context) { 

            bool foundSubItems = false; 
 
            string imageKey = null;
            int imageIndex = -1; 

            foreach (SerializationEntry entry in info) {
                if (entry.Name == "Text") {
                    Text = info.GetString(entry.Name); 
                }
                else if (entry.Name == "ImageIndex") { 
                    imageIndex = info.GetInt32(entry.Name); 
                }
                else if (entry.Name == "ImageKey") { 
                    imageKey = info.GetString(entry.Name);
                }
                else if (entry.Name == "SubItemCount") {
                    SubItemCount = info.GetInt32(entry.Name); 
                    // foundSubItems true only if count > 0
                    if (SubItemCount > 0) 
                    { 
                        foundSubItems = true;
                    } 
                }
                else if (entry.Name == "BackColor") {
                    BackColor = (Color)info.GetValue(entry.Name, typeof(Color));
                } 
                else if (entry.Name == "Checked") {
                    Checked = info.GetBoolean(entry.Name); 
                } 
                else if (entry.Name == "Font") {
                    Font = (Font)info.GetValue(entry.Name, typeof(Font)); 
                }
                else if (entry.Name == "ForeColor") {
                    ForeColor = (Color)info.GetValue(entry.Name, typeof(Color));
                } 
                else if (entry.Name == "UseItemStyleForSubItems") {
                    UseItemStyleForSubItems = info.GetBoolean(entry.Name); 
                } 
                else if (entry.Name == "Group") {
                    ListViewGroup group = (ListViewGroup) info.GetValue(entry.Name, typeof(ListViewGroup)); 
                    this.groupName = group.Name;
                }
            }
 
            // let image key take precidence
            if (imageKey != null) { 
                ImageKey = imageKey; 
            }
            else if (imageIndex != -1) { 
                ImageIndex = imageIndex;
            }

            if (foundSubItems) { 
                ListViewSubItem[] newItems = new ListViewSubItem[SubItemCount];
                for (int i = 1; i < SubItemCount; i++) { 
                    // SEC 
                    ListViewSubItem newItem = (ListViewSubItem)info.GetValue("SubItem" + i.ToString(CultureInfo.InvariantCulture), typeof(ListViewSubItem));
                    newItem.owner = this; 
                    newItems[i] = newItem;
                }
                newItems[0] = subItems[0];
                subItems = newItems; 
            }
        } 
 
        /// 
        ///  
        ///     Saves this ListViewItem object to the given data stream.
        /// 
        /// SECREVIEW: Since ISerializable.GetObjectData and Deserialize require SerializationFormatter - locking down.
       	[SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.SerializationFormatter), 		 
         SecurityPermission(SecurityAction.InheritanceDemand, Flags=SecurityPermissionFlag.SerializationFormatter)]
        protected virtual void Serialize(SerializationInfo info, StreamingContext context) { 
            info.AddValue("Text", Text); 
            info.AddValue("ImageIndex", ImageIndexer.Index);
            if (!String.IsNullOrEmpty(ImageIndexer.Key)) { 
                info.AddValue("ImageKey", ImageIndexer.Key);
            }
            if (SubItemCount > 1) {
                info.AddValue("SubItemCount", SubItemCount); 
                for (int i = 1; i < SubItemCount; i++) {
                    info.AddValue("SubItem" + i.ToString(CultureInfo.InvariantCulture), subItems[i], typeof(ListViewSubItem)); 
                } 
            }
            info.AddValue("BackColor", BackColor); 
            info.AddValue("Checked", Checked);
            info.AddValue("Font", Font);
            info.AddValue("ForeColor", ForeColor);
            info.AddValue("UseItemStyleForSubItems", UseItemStyleForSubItems); 
            if (this.Group != null) {
                info.AddValue("Group", this.Group); 
            } 
        }
 
        // we need this function to set the index when the list view is in virtual mode.
        // the index of the list view item is used in ListView::set_TopItem property
        internal void SetItemIndex(ListView listView, int index) {
            Debug.Assert(listView != null && listView.VirtualMode, "ListViewItem::SetItemIndex should be used only when the list is virtual"); 
            Debug.Assert(index > -1, "can't set the index on a virtual list view item to -1");
            this.listView = listView; 
            this.lastIndex = index; 
        }
 
        /// 
        internal bool ShouldSerializeText() {
            return false;
        } 

        private bool ShouldSerializePosition() { 
            return !this.position.Equals(new Point(-1,-1)); 
        }
 
        /// 
        /// 
        ///    [To be supplied.]
        ///  
        public override string ToString() {
            return "ListViewItem: {" + Text + "}"; 
        } 

        // The ListItem's state (or a SubItem's state) has changed, so invalidate the ListView control 
        internal void InvalidateListView() {
            if (listView != null && listView.IsHandleCreated) {
                listView.Invalidate();
            } 
        }
 
        internal void UpdateSubItems(int index){ 
            UpdateSubItems(index, SubItemCount);
        } 

        internal void UpdateSubItems(int index, int oldCount){
            if (listView != null && listView.IsHandleCreated) {
                int subItemCount = SubItemCount; 

                int itemIndex = Index; 
 
                if (index != -1) {
                    listView.SetItemText(itemIndex, index, subItems[index].Text); 
                }
                else {
                    for(int i=0; i < subItemCount; i++) {
                        listView.SetItemText(itemIndex, i, subItems[i].Text); 
                    }
                } 
 
                for (int i = subItemCount; i < oldCount; i++) {
                    listView.SetItemText(itemIndex, i, string.Empty); 
                }
            }
        }
 
        /// 
        ///  
        [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.SerializationFormatter)] 
        void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) {
            Serialize(info, context); 
        }

        /// 
        ///  
        ///    [To be supplied.]
        ///  
        [ 
            TypeConverterAttribute(typeof(ListViewSubItemConverter)),
            ToolboxItem(false), 
            DesignTimeVisible(false),
            DefaultProperty("Text"),
            Serializable
        ] 
        public class ListViewSubItem {
 
            [NonSerialized] 
            internal ListViewItem owner;
 
            private string text;

            [OptionalField(VersionAdded=2)]
            private string name = null; 

            private SubItemStyle style; 
 
            [OptionalField(VersionAdded=2)]
            private object userData; 

            /// 
            /// 
            ///    [To be supplied.] 
            /// 
            public ListViewSubItem() { 
            } 

            ///  
            /// 
            ///    [To be supplied.]
            /// 
            public ListViewSubItem(ListViewItem owner, string text) { 
                this.owner = owner;
                this.text = text; 
            } 

            ///  
            /// 
            ///    [To be supplied.]
            /// 
            public ListViewSubItem(ListViewItem owner, string text, Color foreColor, Color backColor, Font font) { 
                this.owner = owner;
                this.text = text; 
                this.style = new SubItemStyle(); 
                this.style.foreColor = foreColor;
                this.style.backColor = backColor; 
                this.style.font = font;
            }

 
            /// 
            ///  
            ///    [To be supplied.] 
            /// 
            public Color BackColor { 
                get {
                    if (style != null && style.backColor != Color.Empty) {
                        return style.backColor;
                    } 

                    if (owner != null && owner.listView != null) { 
                        return owner.listView.BackColor; 
                    }
 
                    return SystemColors.Window;
                }
                set {
                    if (style == null) { 
                        style = new SubItemStyle();
                    } 
 
                    if (style.backColor != value) {
                        style.backColor = value; 
                        if (owner != null) {
                            owner.InvalidateListView();
                        }
                    } 
                }
            } 
            ///  
            [Browsable(false)]
            public Rectangle Bounds { 
                get {
                    if(owner != null && owner.listView != null && owner.listView.IsHandleCreated) {
                        return owner.listView.GetSubItemRect(owner.Index, owner.SubItems.IndexOf(this));
                    } else { 
                        return Rectangle.Empty;
                    } 
                } 
            }
 
            internal bool CustomBackColor {
                get {
                    return style != null && !style.backColor.IsEmpty;
                } 
            }
 
            internal bool CustomFont { 
                get {
                    return style != null && style.font != null; 
                }
            }

            internal bool CustomForeColor { 
                get {
                    return style != null && !style.foreColor.IsEmpty; 
                } 
            }
 
            internal bool CustomStyle {
                get {
                    return style != null;
                } 
            }
 
            ///  
            /// 
            ///    [To be supplied.] 
            /// 
            [
            Localizable(true)
            ] 
            public Font Font {
                get { 
                    if (style != null && style.font != null) { 
                        return style.font;
                    } 

                    if (owner != null && owner.listView != null) {
                        return owner.listView.Font;
                    } 

                    return Control.DefaultFont; 
                } 
                set {
                    if (style == null) { 
                        style = new SubItemStyle();
                    }

                    if (style.font != value) { 
                        style.font = value;
                        if (owner != null) { 
                            owner.InvalidateListView(); 
                        }
                    } 
                }
            }

            ///  
            /// 
            ///    [To be supplied.] 
            ///  
            public Color ForeColor {
                get { 
                    if (style != null && style.foreColor != Color.Empty) {
                        return style.foreColor;
                    }
 
                    if (owner != null && owner.listView != null) {
                        return owner.listView.ForeColor; 
                    } 

                    return SystemColors.WindowText; 
                }
                set {
                    if (style == null) {
                        style = new SubItemStyle(); 
                    }
 
                    if (style.foreColor != value) { 
                        style.foreColor = value;
                        if (owner != null) { 
                            owner.InvalidateListView();
                        }
                    }
                } 
            }
 
            ///  
            [
            SRCategory(SR.CatData), 
            Localizable(false),
            Bindable(true),
            SRDescription(SR.ControlTagDescr),
            DefaultValue(null), 
            TypeConverter(typeof(StringConverter)),
            ] 
            public object Tag { 
                get {
                    return userData; 
                }
                set {
                    userData = value;
                } 
            }
 
            ///  
            /// 
            ///    [To be supplied.] 
            /// 
            [
            Localizable(true)
            ] 
            public string Text {
                get { 
                    return text == null ? "" : text; 
                }
                set { 
                    text = value;
                    if (owner != null) {
                        owner.UpdateSubItems(-1);
                    } 
                }
            } 
 
            /// 
            ///  
            ///    [To be supplied.]
            /// 
            [
            Localizable(true) 
            ]
            public string Name { 
                get { 
                    return (name == null) ? "": name;
                } 
                set {
                    name = value;
                    if (owner != null) {
                        owner.UpdateSubItems(-1); 
                    }
                } 
            } 

            // 
            // Fix for Serialization Breaking change from v1.* to v2.0
            //
            // see http://devdiv/SpecTool/SHADOW/Documents/Whidbey/Versioning/VersionTolerantSerializationGuidelines(1.1).doc
            // 
            [OnDeserializing]
            private void OnDeserializing(StreamingContext ctx) { 
            } 

            [OnDeserialized] 
            [SuppressMessage("Microsoft.Performance", "CA1801:AvoidUnusedParameters")]
            private void OnDeserialized(StreamingContext ctx) {
                this.name = null;
                this.userData = null; 
            }
 
            [OnSerializing] 
            private void OnSerializing(StreamingContext ctx) {
            } 

            [OnSerialized]
            private void OnSerialized(StreamingContext ctx) {
            } 

            // 
            // End fix for Serialization Breaking change from v1.* to v2.0 
            //
 
            /// 
            /// 
            ///    [To be supplied.]
            ///  
            public void ResetStyle() {
                if (style != null) { 
                    style = null; 
                    if (owner != null) {
                        owner.InvalidateListView(); 
                    }
                }
            }
 
            /// 
            ///  
            ///    [To be supplied.] 
            /// 
            public override string ToString() { 
                return "ListViewSubItem: {" + Text + "}";
            }

            [Serializable] 
            private class SubItemStyle {
                public Color backColor = Color.Empty; 
                public Color foreColor = Color.Empty; 
                public Font font = null;
            } 
        }

        /// 
        ///  
        ///    [To be supplied.]
        ///  
        public class ListViewSubItemCollection : IList { 
            private ListViewItem owner;
 

            /// A caching mechanism for key accessor
            /// We use an index here rather than control so that we don't have lifetime
            /// issues by holding on to extra references. 
            private int lastAccessedIndex = -1;
 
 
            /// 
            ///  
            ///    [To be supplied.]
            /// 
            public ListViewSubItemCollection(ListViewItem owner) {
                this.owner = owner; 
            }
 
            ///  
            /// 
            ///     Returns the total number of items within the list view. 
            /// 
            [Browsable(false)]
            public int Count {
                get { 
                    return owner.SubItemCount;
                } 
            } 

            ///  
            /// 
            object ICollection.SyncRoot {
                get {
                    return this; 
                }
            } 
 
            /// 
            ///  
            bool ICollection.IsSynchronized {
                get {
                    return true;
                } 
            }
 
            ///  
            /// 
            bool IList.IsFixedSize { 
                get {
                    return false;
                }
            } 

            ///  
            ///  
            ///    [To be supplied.]
            ///  
            public bool IsReadOnly {
                get {
                    return false;
                } 
            }
 
            ///  
            /// 
            ///     Returns a ListViewSubItem given it's zero based index into the ListViewSubItemCollection. 
            /// 
            public ListViewSubItem this[int index] {
                get {
                    if (index < 0 || index >= Count) 
                        throw new ArgumentOutOfRangeException("index", SR.GetString(SR.InvalidArgument, "index", (index).ToString(CultureInfo.CurrentCulture)));
 
                    return owner.subItems[index]; 
                }
                set { 
                    if (index < 0 || index >= Count)
                        throw new ArgumentOutOfRangeException("index", SR.GetString(SR.InvalidArgument, "index", (index).ToString(CultureInfo.CurrentCulture)));

                    owner.subItems[index] = value; 
                    owner.UpdateSubItems(index);
                } 
            } 

            ///  
            /// 
            object IList.this[int index] {
                get {
                    return this[index]; 
                }
                set { 
                    if (value is ListViewSubItem) { 
                        this[index] = (ListViewSubItem)value;
                    } 
                    else {
                        throw new ArgumentException(SR.GetString(SR.ListViewBadListViewSubItem),"value");
                    }
                } 
            }
            ///  
            ///  
            ///     Retrieves the child control with the specified key.
            ///  
            public virtual ListViewSubItem this[string key] {
                get {
                    // We do not support null and empty string as valid keys.
                    if (string.IsNullOrEmpty(key)){ 
                        return null;
                    } 
 
                    // Search for the key in our collection
                    int index = IndexOfKey(key); 
                    if (IsValidIndex(index)) {
                        return this[index];
                    }
                    else { 
                        return null;
                    } 
 
                }
            } 

            /// 
            /// 
            ///    [To be supplied.] 
            /// 
            public ListViewSubItem Add(ListViewSubItem item) { 
                EnsureSubItemSpace(1, -1); 
                item.owner = this.owner;
                owner.subItems[owner.SubItemCount] = item; 
                owner.UpdateSubItems(owner.SubItemCount++);
                return item;
            }
 
            /// 
            public ListViewSubItem Add(string text) { 
                ListViewSubItem item = new ListViewSubItem(owner, text); 
                Add(item);
                return item; 
            }

            /// 
            public ListViewSubItem Add(string text, Color foreColor, Color backColor, Font font) { 
                ListViewSubItem item = new ListViewSubItem(owner, text, foreColor, backColor, font);
                Add(item); 
                return item; 
            }
 
            /// 
            public void AddRange(ListViewSubItem[] items) {
                if (items == null) {
                    throw new ArgumentNullException("items"); 
                }
                EnsureSubItemSpace(items.Length, -1); 
 
                foreach(ListViewSubItem item in items) {
                    if (item != null) { 
                        owner.subItems[owner.SubItemCount++] = item;
                    }
                }
 
                owner.UpdateSubItems(-1);
            } 
 
            /// 
            public void AddRange(string[] items) { 
                if (items == null) {
                    throw new ArgumentNullException("items");
                }
                EnsureSubItemSpace(items.Length, -1); 

                foreach(string item in items) { 
                    if (item != null) { 
                        owner.subItems[owner.SubItemCount++] = new ListViewSubItem(owner, item);
                    } 
                }

                owner.UpdateSubItems(-1);
            } 

            ///  
            public void AddRange(string[] items, Color foreColor, Color backColor, Font font) { 
                if (items == null) {
                    throw new ArgumentNullException("items"); 
                }
                EnsureSubItemSpace(items.Length, -1);

                foreach(string item in items) { 
                    if (item != null) {
                        owner.subItems[owner.SubItemCount++] = new ListViewSubItem(owner, item, foreColor, backColor, font); 
                    } 
                }
 
                owner.UpdateSubItems(-1);
            }

            ///  
            /// 
            int IList.Add(object item) { 
                if (item is ListViewSubItem) { 
                    return IndexOf(Add((ListViewSubItem)item));
                } 
                else {
                    throw new ArgumentException(SR.GetString(SR.ListViewSubItemCollectionInvalidArgument));
                }
            } 

            ///  
            ///  
            ///    [To be supplied.]
            ///  
            public void Clear() {
                int oldCount = owner.SubItemCount;
                if (oldCount > 0) {
                    owner.SubItemCount = 0; 
                    owner.UpdateSubItems(-1, oldCount);
                } 
            } 

            ///  
            /// 
            ///    [To be supplied.]
            /// 
            public bool Contains(ListViewSubItem subItem) { 
                return IndexOf(subItem) != -1;
            } 
 

            ///  
            /// 
            bool IList.Contains(object subItem) {
                if (subItem is ListViewSubItem) {
                    return Contains((ListViewSubItem)subItem); 
                }
                else { 
                    return false; 
                }
            } 

            /// 
            /// 
            ///     Returns true if the collection contains an item with the specified key, false otherwise. 
            /// 
            public virtual bool ContainsKey(string key) { 
                return IsValidIndex(IndexOfKey(key)); 
            }
 
            /// 
            ///     Ensures that the sub item array has the given
            ///     capacity.  If it doesn't, it enlarges the
            ///     array until it does.  If index is -1, additional 
            ///     space is tacked onto the end.  If it is a valid
            ///     insertion index into the array, this will move 
            ///     the array data to accomodate the space. 
            /// 
            private void EnsureSubItemSpace(int size, int index) { 

                // Range check subItems.
                if (owner.SubItemCount == ListViewItem.MAX_SUBITEMS) {
                    throw new InvalidOperationException(SR.GetString(SR.ErrorCollectionFull)); 
                }
 
                if (owner.SubItemCount + size > owner.subItems.Length) { 

                    // must grow array.  Don't do it just by size, though; 
                    // chunk it for efficiency.

                    if (owner.subItems == null) {
                        int newSize = (size > 4) ? size : 4; 
                        owner.subItems = new ListViewSubItem[newSize];
                    } 
                    else { 
                        int newSize = owner.subItems.Length * 2;
                        while(newSize - owner.SubItemCount < size) { 
                            newSize *= 2;
                        }

                        ListViewSubItem[] newItems = new ListViewSubItem[newSize]; 

                        // Now, when copying to the member variable, use index 
                        // if it was provided. 
                        //
                        if (index != -1) { 
                            Array.Copy(owner.subItems, 0, newItems, 0, index);
                            Array.Copy(owner.subItems, index, newItems, index + size, owner.SubItemCount - index);
                        }
                        else { 
                            Array.Copy(owner.subItems, newItems, owner.SubItemCount);
                        } 
                        owner.subItems = newItems; 
                    }
                } 
                else {

                    // We had plenty of room.  Just move the items if we need to
                    // 
                    if (index != -1) {
                        for(int i = owner.SubItemCount - 1; i >= index; i--) { 
                            owner.subItems[i + size] = owner.subItems[i]; 
                        }
                    } 
                }
            }

            ///  
            /// 
            ///    [To be supplied.] 
            ///  
            public int IndexOf(ListViewSubItem subItem) {
                for(int index=0; index < Count; ++index) { 
                    if (owner.subItems[index] == subItem) {
                        return index;
                    }
                } 
                return -1;
            } 
 
            /// 
            ///  
            int IList.IndexOf(object subItem) {
                if (subItem is ListViewSubItem) {
                    return IndexOf((ListViewSubItem)subItem);
                } 
                else {
                    return -1; 
                } 
            }
            ///  
            /// 
            ///     The zero-based index of the first occurrence of value within the entire CollectionBase, if found; otherwise, -1.
            /// 
            public virtual int  IndexOfKey(String key) { 
                  // Step 0 - Arg validation
                  if (string.IsNullOrEmpty(key)){ 
                        return -1; // we dont support empty or null keys. 
                  }
 
                // step 1 - check the last cached item
                if (IsValidIndex(lastAccessedIndex))
                {
                    if (WindowsFormsUtils.SafeCompareStrings(this[lastAccessedIndex].Name, key, /* ignoreCase = */ true)) { 
                        return lastAccessedIndex;
                    } 
                } 

                // step 2 - search for the item 
                for (int i = 0; i < this.Count; i ++) {
                    if (WindowsFormsUtils.SafeCompareStrings(this[i].Name, key, /* ignoreCase = */ true)) {
                        lastAccessedIndex = i;
                        return i; 
                    }
                } 
 
                // step 3 - we didn't find it.  Invalidate the last accessed index and return -1.
                lastAccessedIndex = -1; 
                return -1;
            }

            ///  
            /// 
            ///     Determines if the index is valid for the collection. 
            ///  
            /// 
            private bool IsValidIndex(int index) { 
                return ((index >= 0) && (index < this.Count));
            }

            ///  
            /// 
            ///    [To be supplied.] 
            ///  
            public void Insert(int index, ListViewSubItem item) {
 
                if (index < 0 || index > Count) {
                    throw new ArgumentOutOfRangeException("index");
                }
 
                item.owner = owner;
 
                EnsureSubItemSpace(1, index); 

                // Insert new item 
                //
                owner.subItems[index] = item;
                owner.SubItemCount++;
                owner.UpdateSubItems(-1); 
            }
 
            ///  
            /// 
            void IList.Insert(int index, object item) { 
                if (item is ListViewSubItem) {
                    Insert(index, (ListViewSubItem)item);
                }
                else { 
                    throw new ArgumentException(SR.GetString(SR.ListViewBadListViewSubItem),"item");
                } 
            } 

            ///  
            /// 
            ///    [To be supplied.]
            /// 
            public void Remove(ListViewSubItem item) { 
                int index = IndexOf(item);
                if (index != -1) { 
                    RemoveAt(index); 
                }
            } 

            /// 
            /// 
            void IList.Remove(object item) { 
                if (item is ListViewSubItem) {
                    Remove((ListViewSubItem)item); 
                } 
            }
 
            /// 
            /// 
            ///    [To be supplied.]
            ///  
            public void RemoveAt(int index) {
 
                if (index < 0 || index >= Count) { 
                    throw new ArgumentOutOfRangeException("index");
                } 

                // Collapse the items
                for (int i = index + 1; i < owner.SubItemCount; i++) {
                    owner.subItems[i - 1] = owner.subItems[i]; 
                }
 
                int oldCount = owner.SubItemCount; 
                owner.SubItemCount--;
                owner.subItems[owner.SubItemCount] = null; 
                owner.UpdateSubItems(-1, oldCount);
            }

          ///  
          /// 
          ///     Removes the child control with the specified key. 
          ///  
          public virtual void RemoveByKey(string key) {
                int index = IndexOfKey(key); 
                if (IsValidIndex(index)) {
                    RemoveAt(index);
                 }
           } 

            ///  
            ///  
            void ICollection.CopyTo(Array dest, int index) {
                if (Count > 0) { 
                    System.Array.Copy(owner.subItems, 0, dest, index, Count);
                }
            }
 
            /// 
            ///  
            ///    [To be supplied.] 
            /// 
            public IEnumerator GetEnumerator() { 
                if (owner.subItems != null) {
                    return new WindowsFormsUtils.ArraySubsetEnumerator(owner.subItems, owner.SubItemCount);
                }
                else 
                {
                    return new ListViewSubItem[0].GetEnumerator(); 
                } 

            } 
        }
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK