BUG: ListView.ColumnHeaderCollection.Add Method Does Not Work with Autosize Width in C# (316572)



The information in this article applies to:

  • Microsoft .NET Framework 1.1
  • Microsoft .NET Framework 1.0
  • Microsoft Visual C# .NET (2003)
  • Microsoft Visual C# .NET (2002)

This article was previously published under Q316572

SYMPTOMS

When you pass -1 or -2 autosize width settings to the ListView.ColumnHeaderCollection.Add method, the ListView control does not display the column as expected.

You expect a -1 setting to set the column header to the size of the largest subitem text in the column, and a -2 setting to set the column header to the size of the text in the column header.

RESOLUTION

To work around this issue, avoid using the -1 and -2 autosize parameters. Instead, pass a predefined column width to the Add() method.

The other available workaround is more involved. The following steps demonstrate how to implement the -1 setting by setting the column width after the column has been created, and how to implement the -2 setting by using GDI+ to measure the string size of the column header text and the subitem text (in pixels).

To do this, follow these steps:
  1. Use C# to start a new Windows application.
  2. Add a ListView control and two Button controls on Form1. These controls will be named listView1, button1, and button2, respectively.
  3. In the Form1_Load event, add the following code:
    listView1.Bounds = new Rectangle(new Point(10,10), new Size(250,100));
    listView1.View = View.Details;
    listView1.Items.Add("This is Item 1");
    listView1.Items[0].SubItems.Add("This is subitem 1 for item 1");
    listView1.Items[0].SubItems.Add("This is subitem 2 for item 1");
    listView1.Items.Add("This is Item 2");
    listView1.Items[1].SubItems.Add("This is subitem 1 for item 2");
    listView1.Items[1].SubItems.Add("This is subitem 2 for item 2");
    listView1.Columns.Add("Column 1", -1, HorizontalAlignment.Left);
    listView1.Columns.Add("Column 2", -2, HorizontalAlignment.Left);
    listView1.Columns.Add("Column 3", -1, HorizontalAlignment.Left);
    					
  4. In the button1_Click event, add the following code:
    //To implement the -1 autosize setting, set the width of columns after the columns are created, as follows:
    listView1.Columns[0].Width = -1;
    listView1.Columns[1].Width = -1;
    listView1.Columns[2].Width = -1;
    					
  5. In the button2_Click event, add the following code:
    //Use GDI+ to implement the -2 autosize setting.
    listView1.Clear();
    string s1 = "Column 1";
    string s2 = "Column 2";
    string s3 = "column 3";
    Graphics newGraphics = Graphics.FromHwnd(listView1.Handle);
    SizeF stringSize1 = new SizeF();
    SizeF stringSize2 = new SizeF();
    SizeF stringSize3 = new SizeF();
    stringSize1 = newGraphics.MeasureString(s1, listView1.Font);
    stringSize2 = newGraphics.MeasureString(s2, listView1.Font);
    stringSize3 = newGraphics.MeasureString(s3, listView1.Font);
    listView1.View = View.Details;
    listView1.Items.Add("This is Item 1");
    listView1.Items[0].SubItems.Add("This is subitem 1 for item 1");
    listView1.Items[0].SubItems.Add("This is subitem 2 for item 1");
    listView1.Items.Add("This is Item 2");
    listView1.Items[1].SubItems.Add("This is subitem 1 for item 2");
    listView1.Items[1].SubItems.Add("This is subitem 2 for item 2");
    listView1.Columns.Add("Column 1", Convert.ToInt16(stringSize1.Width)+ 5, HorizontalAlignment.Left);
    listView1.Columns.Add("Column 2", Convert.ToInt16(stringSize2.Width)+ 5, HorizontalAlignment.Left);
    listView1.Columns.Add("Column 3", Convert.ToInt16(stringSize3.Width)+ 5, HorizontalAlignment.Left);
    					
  6. Press F5 to run the code. Click button1, and then notice that the column width is adjusted according to the size of the largest subitem text in the column. Click button2, and then notice that the column width is adjusted according to the size of the column header text.

STATUS

Microsoft has confirmed that this is a bug in the Microsoft products that are listed at the beginning of this article.

MORE INFORMATION

Steps to Reproduce the Problem

  1. Use C# .NET to start a new Windows application.
  2. On Form1, add a ListView control.
  3. In the Form1_Load event, add the following code:
    listView1.View = View.Details;
    listView1.Items.Add("This is Item 1");
    listView1.Items[0].SubItems.Add("This is subitem 1");
    listView1.Items[0].SubItems.Add("This is subitem 2");
    listView1.Items.Add("This is Item 2");
    listView1.Items[1].SubItems.Add("This is subitem 3");
    listView1.Items[1].SubItems.Add("This is subitem 4");
    listView1.Columns.Add("Column 1", -1, HorizontalAlignment.Left);
    listView1.Columns.Add("Column 2", -2, HorizontalAlignment.Left);
    listView1.Columns.Add("Column 3", -1, HorizontalAlignment.Left);
    					
  4. Press F5 to run the application.

    Notice that the columns are not displayed at all.
  5. Change the -2 and -1 settings to a fixed column width -- for example, 60.
  6. Run the application again. The columns are now displayed.

Modification Type:MajorLast Reviewed:3/24/2004
Keywords:kbListView kbCtrl kbbug kbpending KB316572