1

I need a listview to auto-resize its columns based on both width of the headers and content, and every other answer only does one or the other.

Example:

        listView1.GridLines = true;
        // Create three items and three sets of subitems for each item.
        ListViewItem item1 = new ListViewItem("item1asdfghjkl", 0);
        item1.SubItems.Add("1");
        item1.SubItems.Add("2");
        item1.SubItems.Add("3");
        ListViewItem item2 = new ListViewItem("item2", 1);
        item2.SubItems.Add("4");
        item2.SubItems.Add("5");
        item2.SubItems.Add("6");
        ListViewItem item3 = new ListViewItem("item3", 0);
        item3.SubItems.Add("7");
        item3.SubItems.Add("8");
        item3.SubItems.Add("9");

        // Create columns for the items and subitems. 
        // Width of -2 indicates auto-size.
        listView1.Columns.Add("Item Column", -2, HorizontalAlignment.Left);
        listView1.Columns.Add("Column 2", -2, HorizontalAlignment.Left);
        listView1.Columns.Add("Column 3", -2, HorizontalAlignment.Left);
        listView1.Columns.Add("Column 4", -2, HorizontalAlignment.Left);

        //these two lines
        listView1.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent);
        listView1.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);

        //Add the items to the ListView.
        listView1.Items.AddRange(new ListViewItem[] { item1, item2, item3 });

the note here is that no matter which (or both) resize style, something is cut off, either a header or a content.

There doesn't even seem to be a reliable way to get the display size of the content to manually resize the columns and headers.

crazybmanp
  • 151
  • 3
  • 5
  • 12
  • It should also be noted that the functionality required is the default functionality when you double-click between columns. – crazybmanp Sep 17 '14 at 16:58
  • [AutoResizeColumns.HeaderSize](http://stackoverflow.com/a/24106546/1070452) should resize the columns to the greater of longest Header Text versus longest Content **showing**. If there is longer text scrolled out of sight it is not considered. you cant use them both as the code shows or just the last one is used. – Ňɏssa Pøngjǣrdenlarp Sep 17 '14 at 17:09
  • The question is how to produce the desired effect. it is possible as it is the default double-clock functionality. – crazybmanp Sep 19 '14 at 18:43
  • If the desired effect is to size the columns so that neither the header nor "column" content is clipped, `listview1.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);` is the answer or method to produce it. In spite of the name it is not automatic, it will resize based on the data in the control at that time. If you add an item, it could be clipped; there is nothing automatic about it except that it automatically considers all the LVIs in the control for you. – Ňɏssa Pøngjǣrdenlarp Sep 19 '14 at 19:05
  • This should really be an answer, and it would be useful to see exact test code, as this does not work for me. – crazybmanp Sep 20 '14 at 19:51
  • the code is in your question: `listView1.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);` note that it is a method not a property. It resizes based on the data in the LV now; it is not dynamic which seems like what you expect: `// Width of -2 indicates auto-size` which is wrong. -2 sizes the column to the headertext. since it is a new columnheader you are adding, context text is not considered. – Ňɏssa Pøngjǣrdenlarp Sep 20 '14 at 20:18

2 Answers2

0

Anton Kedrov answer here - ListView AutoResizeColumns based on both Column content and header is best one but in my case i have a listview with more than 50 columns and i update its data frequently in this case i notice listview's this.AutoResizeColumns performs much faster work so i m writing this solution also

First Method by setting with to -2

public void AutoUpdateColumnWidth(ListView lv)
{
    for (int i = 0; i <= lv.Columns.Count - 1; i++) {
        lv.Columns(i).Width = -2;
    }
}

Second method i used (less flicker on multiple calls)

public void AutoUpdateColumnWidth(ListView lv)
{
    ListViewItem nLstItem = new ListViewItem(lv.Columns(0).Text);
    for (int i = 1; i <= lv.Columns.Count - 1; i++) {
        nLstItem.SubItems.Add(lv.Columns(i).Text);
    }
    v.Items.Add(nLstItem);
    lv.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent);
    lv.Items.RemoveAt(nLstItem.Index);
}
Community
  • 1
  • 1
Jack Gajanan
  • 1,596
  • 14
  • 18
  • 1
    First method worked for me. I come from C++ and the C++ way to resize listview headers could be used here. It would take some wonky importing of Win32 functions though. I prefer this method now and the older I get the more I appreciate it and not making myself grind out a wheel everytime... –  Jan 05 '22 at 20:27
0

This is simple (although it took me a while to figure out)...

We know that the width must be at least as great as the column headers, so that we see all of the header text. Beyond that, the width can expand larger to accommodate contents. Hence, we do the following:

  1. Autosize the columns to header.
  2. Iterate through the columns and set the minimum width property for each column to the current column width (which guarantees your columns will never get too small to see the header).
  3. From now on, autosize columns by content.

EDIT: My apologies, I forgot that I was not using the standard listview, but instead the 3rd party product BetterListView (a free version is available). The standard listview columns don't appear to support minimum width. I do recommend BetterListView highly as a great alternative (much better feature set and performance).

Ben W.
  • 23
  • 1
  • 6