23

我们使用这两种方法根据列内容和标题分别调整列长度。

ListView.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent); ListView.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);

但是如何根据两者进行调整呢?即调整到标题和列内容的最长长度。

4

8 回答 8

29

lvw.Columns[0].Width = -2

有关详细信息,请参阅 MSDN 中的备注:http: //msdn.microsoft.com/en-us/library/system.windows.forms.columnheader.width.aspx

另请注意,MSDN 说“要自动调整为列标题的宽度,请将 Width 属性设置为 -2。”,但实际上它适用于列标题和列内容。

下面是一段代码来证明:

    lvw.Columns.Add(new String('x', 25));   // short header
    lvw.Items.Add(new String('x', 100));    // long content

    lvw.Columns[0].Width = -2;
    // in result column width will be set to fit content
于 2013-01-15T15:46:19.840 回答
21

正如这里回答的那样,调用两个调整大小选项都可以完成这项工作:

myListView.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent);
myListView.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);
于 2014-09-04T15:56:27.457 回答
7

这是我用来将列宽调整为内容和标题的方法:

public static void autoResizeColumns(ListView lv)
{
    lv.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent);
    ListView.ColumnHeaderCollection cc = lv.Columns;
    for (int i = 0; i < cc.Count; i++)
    {
        int colWidth = TextRenderer.MeasureText(cc[i].Text, lv.Font).Width + 10;
        if (colWidth > cc[i].Width)
        {
            cc[i].Width = colWidth;
        }
    }
}

示例使用:

autoResizeColumns(listView1);

该方法没有经过很好的测试,但至少它在我使用它的上下文中有效。

于 2013-11-29T14:03:01.160 回答
1

确实可以使用 MeasureText 然后计算剩余的空间并以某种方式在所有列之间分配。但这是我快速编码的快速而肮脏的方法:

    /// <summary>
    /// Enables autoresizing for specific listview.
    /// You can specify how much to scale in columnScaleNumbers array - length of that array
    /// should match column count which you have.
    /// </summary>
    /// <param name="listView">control for which to enable auto-resize</param>
    /// <param name="columnScaleNumbers">Percentage or numbers how much each column will be scaled.</param>
    private void EnableAutoresize(ListView listView, params int[] columnScaleNumbers)
    {
        listView.View = View.Details;
        for( int i = 0; i < columnScaleNumbers.Length; i++ )
        {
            if( i >= listView.Columns.Count )
                break;
            listView.Columns[i].Tag = columnScaleNumbers[i];
        }

        listView.SizeChanged += lvw_SizeChanged;
        DoResize(listView);
    }

    void lvw_SizeChanged(object sender, EventArgs e)
    {
        ListView listView = sender as ListView;
        DoResize(listView);
    }

    bool Resizing = false;
    void DoResize( ListView listView )
    {
        // Don't allow overlapping of SizeChanged calls
        if (!Resizing)
        {
            // Set the resizing flag
            Resizing = true;

            if (listView != null)
            {
                float totalColumnWidth = 0;

                // Get the sum of all column tags
                for (int i = 0; i < listView.Columns.Count; i++)
                    totalColumnWidth += Convert.ToInt32(listView.Columns[i].Tag);

                // Calculate the percentage of space each column should 
                // occupy in reference to the other columns and then set the 
                // width of the column to that percentage of the visible space.
                for (int i = 0; i < listView.Columns.Count; i++)
                {
                    float colPercentage = (Convert.ToInt32(listView.Columns[i].Tag) / totalColumnWidth);
                    listView.Columns[i].Width = (int)(colPercentage * listView.ClientRectangle.Width);
                }
            }
        }

        // Clear the resizing flag
        Resizing = false;            
    }

取决于你有多少列 - 你指定每列“百分比”或简单的数字。例如对于 3 列 - 调用如下所示:

        EnableAutoresize(listView1, 6, 3, 1);

这会将列大小分配为:6 * 100% / (6 + 3 + 1) = 60% 用于第一列,30% 用于下一列,10% 用于剩余。

这在某种程度上是穷人的快速实施。:-)

于 2016-02-03T21:32:08.210 回答
0

就我而言,我通过接下来的步骤(对于两列数据)执行此操作:

  1. 为每一列创建一个 ColumnHeader 对象。
  2. 根据 HeaderSize 通过 AutoResize 设置大小(在两列上)
  3. 将该值存储在整数变量中
  4. 根据 ColumnContent 通过 AutoResize 设置大小(在两列上)
  5. 通过旧值和新值之间的 Max 标准(对于每一列)更新每个 Integer 变量的值。
  6. 为每个 ColumnHeader 对象设置列宽大小。

在 VB.NET 中:

'Create two header objects as ColumnHeader Class
Dim header1, header2 As ColumnHeader

'Construcción de los objetos header
header1 = New ColumnHeader
header1.Text = "ID"
header1.TextAlign = HorizontalAlignment.Right
header1.Width = 10

header2 = New ColumnHeader
header2.Text = "Combinaciones a Procesar"
header2.TextAlign = HorizontalAlignment.Left
header2.Width = 10

'Add two columns using your news headers objects 
ListView.Columns.Add(header1)
ListView.Columns.Add(header2)

'Fill three rows of data, for each column
ListView.Items.Add(New ListViewItem({"A1", "B1"}))
ListView.Items.Add(New ListViewItem({"A2", "B2"}))
ListView.Items.Add(New ListViewItem({"A3", "B3"}))

'Change the size of each column
Dim headsz1, headsz2 As Integer
SelectionInTable.ListView.AutoResizeColumn(0,             ColumnHeaderAutoResizeStyle.HeaderSize)
SelectionInTable.ListView.AutoResizeColumn(1, ColumnHeaderAutoResizeStyle.HeaderSize)
headsz1 = header1.Width
headsz2 = header2.Width
SelectionInTable.ListView.AutoResizeColumn(0, ColumnHeaderAutoResizeStyle.ColumnContent)
SelectionInTable.ListView.AutoResizeColumn(1,     ColumnHeaderAutoResizeStyle.ColumnContent)
headsz1 = Math.Max(headsz1, header1.Width)
headsz2 = Math.Max(headsz2, header2.Width)
header1.Width = headsz1
header2.Width = headsz2
于 2015-05-11T13:53:19.933 回答
0

这是可用于任何 ListView 的 C# 解决方案。它假定您的列数和标题对于任何给定的列表视图都不会改变。如果您想每次都重新计算标题宽度(如果标题更改或列数更改),请摆脱 listViewHeaderWidths 字典。

    private Dictionary<string, int[]> listViewHeaderWidths = new Dictionary<string, int[]>();    
    private void ResizeListViewColumns(ListView lv)
    {
        int[] headerWidths = listViewHeaderWidths.ContainsKey(lv.Name) ? listViewHeaderWidths[lv.Name] : null;

        lv.BeginUpdate();

        if (headerWidths == null)
        {
            lv.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);

            headerWidths = new int[lv.Columns.Count];

            for (int i = 0; i < lv.Columns.Count; i++)
            {
                headerWidths[i] = lv.Columns[i].Width;
            }

            listViewHeaderWidths.Add(lv.Name, headerWidths);
        }

        lv.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent);

        for(int j = 0; j < lv.Columns.Count; j++)
        {
            lv.Columns[j].Width = Math.Max(lv.Columns[j].Width, headerWidths[j]);
        }

        lv.EndUpdate();
    }
于 2015-09-20T18:40:22.257 回答
0

Anton Kedrov 的答案是最好的,但在我的情况下,我有一个超过 50 列的列表视图,我经常更新它的数据在这种情况下我注意到列表视图的 this.AutoResizeColumns 执行更快的工作,所以我也在编写这个解决方案

第一种方法,设置为 -2

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

我使用的第二种方法(多次通话时闪烁较少)

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);
}
于 2016-02-03T07:52:59.037 回答
0

这很简单(虽然我花了一段时间才弄清楚)......

我们知道宽度必须至少与列标题一样大,这样我们才能看到所有标题文本。除此之外,宽度可以扩大更大以容纳内容。因此,我们执行以下操作:

  1. 将列自动调整为标题。
  2. 遍历列并将每列的最小宽度属性设置为当前列宽(这样可以保证您的列永远不会太小而无法看到标题)。
  3. 从现在开始,按内容自动调整列大小。

没有必要像其他海报建议的那样单独跟踪宽度并重新设置它们。设置列的最小宽度可以解决问题,直到标题文本被更改,在这种情况下,您将最小宽度设置为 0,仅自动调整修改后的列,然后再次将最小宽度设置为当前宽度。

编辑:抱歉,我忘记了我没有使用标准列表视图,而是使用了第 3 方产品 BetterListView(提供免费版本)。标准列表视图列似乎不支持最小宽度。我强烈推荐 BetterListView 作为一个很好的选择(更好的功能集和性能)。

于 2016-02-28T04:29:39.460 回答