简体   繁体   中英

ListViewItem implicitly adds ListViewSubItem

Suppose I build ListView with following code:

ListViewItem item1 = new ListViewItem();
item1.Text = "item1";
item1.SubItems.Add(new ListViewItem.ListViewSubItem(item1, "subitem1"));
item1.SubItems.Add(new ListViewItem.ListViewSubItem(item1, "subitem2"));
listView1.Items.Add(item1);

But in fact it will create 3 ListViewSubItem s like this:

ListViewItem 
     |
     -------------------------------------
     |                  |                |
ListViewSubItem  ListViewSubItem  ListViewSubItem
 (Text=item1)    (Text=subitem1)  (Text=subitem2)

In my real program I use custom subitems derived from ListViewItem.ListViewSubItem and OwnerDraw = true

ListViewItem item1 = new ListViewItem();
CustomListViewSubItem subitem1 = new CustomListViewSubItem(item1, "subitem1");
CustomListViewSubItem subitem1 = new CustomListViewSubItem(item1, "subitem1");
listView1.Items.Add(item1);

and the above behavior breaks all the logic while casting in DrawSubItems event:

private void listView1_DrawSubItem(object sender, DrawListViewSubItemEventArgs e)
{
    ListViewItem item = e.Item;
    ListViewItem.ListViewSubItem subitem = item.SubItems[e.ColumnIndex];
    CustomListViewSubItem customsubitem = (CustomListViewSubItem)subitem; // <- System.InvalidCastException here
    ...
}

Sure it will fail only for first subitem which in fact is item but that's not I want. How can I avoid this behavior and create only 2 subitems I need?

Not tested but may work:
By calling listView.SubItems on empty collection it automatically adds one "default" element. My advise would be to remove first element after adding your element like:

listView.SubItems.Add(new MeListViewSubItem( ... ) );
listView.SubItems.RemoveAt(0);

From ReferenceSource :

    /// <include file='doc\ListViewItem.uex' path='docs/doc[@for="ListViewItem.SubItems"]/*' />
    /// <devdoc>
    ///    <para>[To be supplied.]</para>
    /// </devdoc>
    [
    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;
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM