[...]
It would be more appropriate for you to be explicitly instantiating your
sub-classes, ListViewItem with the appropriate ListViewSubItem attached,
adding the ListViewSubItem explicitly to the ListViewItem's sub-items,
and then adding that ListViewItem explicitly to the ListView. Once
you've done that, then those will be the instances used for drawing,
which you can then reliably cast back to your own sub-classes.
I've posted below an example of what I mean. I've only sub-classed
ListViewSubItem, but the basic idea applies generally. I didn't bother
putting any actual custom behavior in my sub-class, as it's sufficient for
the example to demonstrate that the sub-class is indeed passed in the
DrawListViewSubItemEventArgs class.
Also note that the DrawListViewSubItem event will be raised for each
column in the details view, including the first one representing the item
itself. The ListViewItem's SubItems collection always includes a
ListViewSubItem representing itself as the first element in the
collection. It's possible you could replace this element with your own
sub-class, but I didn't try that and it seems hazardous to me. As long as
in your handler for DrawListViewSubItem you make sure that you're dealing
with that case properly, by only casting to your own class when
appropriate, I don't think it's necessary to replace the ListViewSubItem
that the ListViewItem puts there itself.
I hope the example helps. As you can see, there's not really any need to
override the various collection and main control classes, if you are not
actually wanting to override the behavior of those classes. Just override
the classes you really need to override, and let the other classes do
their jobs as normal.
Pete
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
namespace TestCustomListView
{
public class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender,EventArgse)
{
if (textBox1.Text != "")
{
ListViewItem lvi = new ListViewItem(textBox1.Text);
lvi.SubItems.Add(new MyListViewSubItem(lvi, "sub item ("
+ textBox1.Text + ")"));
listView1.Items.Add(lvi);
}
}
private void listView1_DrawSubItem(object sender,
DrawListViewSubItemEventArgs e)
{
MyListViewSubItem mysubitem = e.SubItem as MyListViewSubItem;
if (mysubitem != null)
{
Debug.WriteLine("mysubitem class: "
+ mysubitem.GetType().Name);
}
e.DrawBackground();
e.DrawText();
}
private void listView1_DrawColumnHeader(object sender,
DrawListViewColumnHeaderEventArgs e)
{
e.DrawDefault = true;
}
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be
disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
this.textBox1 = new System.Windows.Forms.TextBox();
this.columnHeader1 = new System.Windows.Forms.ColumnHeader();
this.columnHeader2 = new System.Windows.Forms.ColumnHeader();
this.listView1 = new System.Windows.Forms.ListView();
this.SuspendLayout();
//
// button1
//
this.button1.Location = new System.Drawing.Point(13, 13);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(75, 23);
this.button1.TabIndex = 0;
this.button1.Text = "button1";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new
System.EventHandler(this.button1_Click);
//
// textBox1
//
this.textBox1.Location = new System.Drawing.Point(94, 15);
this.textBox1.Name = "textBox1";
this.textBox1.Size = new System.Drawing.Size(100, 20);
this.textBox1.TabIndex = 1;
//
// columnHeader1
//
this.columnHeader1.Text = "Item";
//
// columnHeader2
//
this.columnHeader2.Text = "Sub-Item";
this.columnHeader2.Width = 93;
//
// listView1
//
this.listView1.Anchor =
((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top
| System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.listView1.Columns.AddRange(new
System.Windows.Forms.ColumnHeader[] {
this.columnHeader1,
this.columnHeader2});
this.listView1.Location = new System.Drawing.Point(13, 43);
this.listView1.Name = "listView1";
this.listView1.OwnerDraw = true;
this.listView1.Size = new System.Drawing.Size(399, 254);
this.listView1.TabIndex = 2;
this.listView1.UseCompatibleStateImageBehavior = false;
this.listView1.View = System.Windows.Forms.View.Details;
this.listView1.DrawSubItem += new
System.Windows.Forms.DrawListViewSubItemEventHandler(this.listView1_DrawSubItem);
this.listView1.DrawColumnHeader += new
System.Windows.Forms.DrawListViewColumnHeaderEventHandler(this.listView1_DrawColumnHeader);
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(424, 309);
this.Controls.Add(this.listView1);
this.Controls.Add(this.textBox1);
this.Controls.Add(this.button1);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Button button1;
private System.Windows.Forms.TextBox textBox1;
private System.Windows.Forms.ColumnHeader columnHeader1;
private System.Windows.Forms.ColumnHeader columnHeader2;
private System.Windows.Forms.ListView listView1;
}
class MyListViewSubItem : ListViewItem.ListViewSubItem
{
public MyListViewSubItem(ListViewItem owner, string strItem) :
base(owner, strItem)
{
}
}
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}