ListView根据内容是否存在自动调整大小

时间:2012-06-27 15:43:21

标签: c# winforms listview

我有一个ListView,其视图为View.Details,我想自动调整列的大小。我知道ColumnHeader的{​​{1}}方法,目前我只是这样迭代它们:

AutoResize

这种技术的问题在于,如果我的列中恰好没有数据,则宽度设置为标题不再可用的点。有没有一种很好的方法可以根据列中是否有内容有条件地设置var lMode = ( listView.Items.Count == 0 ) ? ColumnHeaderAutoResizeStyle.HeaderSize : ColumnHeaderAutoResizeStyle.ColumnContent; foreach ( ColumnHeader lColumnHeader in listView.Columns ) { lColumnHeader.AutoResize(lMode); }

如果列中有某些内容我想使用ColumnHeaderAutoResizeStyle,但如果列中没有任何内容,我想使用ColumnHeaderAutoResizeStyle.ColumnContent

2 个答案:

答案 0 :(得分:2)

这是我已经使用了一段时间的方法,现在不涉及测量字符串。

bool参数是因为我自己调用该方法(并将参数设置为true),有时我会在Items.AddRange(ListViewItem [])调用之后直接调用它,其中我将两个调用都包含在其中开始/结束更新电话。

    /// <summary>
    /// Set the column widths to the widest of the items
    /// or the column header text.
    /// </summary>
    /// <param name="useUpdate">Whether to use Begin/End Update methods
    /// to pause the drawing of the list view.</param>
    private void SetColumnWidths(bool useUpdate)
    {
        if(useUpdate)
            list.BeginUpdate();

        int width;
        int totalWidth = 0;

        foreach (ColumnHeader col in list.Columns)
        {
            // The last column's width will be the leftover
            //   width of the list view.
            if (list.Columns.Count != col.DisplayIndex)
            {
                col.AutoResize(ColumnHeaderAutoResizeStyle.HeaderSize); 
                width = col.Width;

                col.AutoResize(ColumnHeaderAutoResizeStyle.ColumnContent);
                if (width > col.Width)
                    col.Width = width;

                totalWidth += col.Width;
            }
            else
            {
                col.Width = (list.ClientSize.Width - totalWidth);
            }

        }

        if(useUpdate)
            list.EndUpdate();

    }

答案 1 :(得分:0)

除非找到更好的答案,否则让我至少回答一下我的问题,以防其他人想要这个功能。我能想到的最好方法是手动扫描桌子并自己测量琴弦。我为此创建了一个扩展方法:

public static void AutoResizeAllColumns( this ListView listView )
{
    if ( listView.Columns.Count == 0 ) return;

    var lGraphics = Graphics.FromHwnd( listView.Handle );

    foreach ( ColumnHeader lColumnHeader in listView.Columns )
    {
        var lColumnHeaderTextSize = lGraphics.MeasureString( lColumnHeader.Text, listView.Font );

        var lColumnIndex = lColumnHeader.Index;
        var lAnyContents = listView.Items
            .Cast<ListViewItem>()
            .Select( x => lGraphics.MeasureString( x.SubItems[ lColumnIndex ].Text, listView.Font ) )
            .Any( x => x.Width > lColumnHeaderTextSize.Width );

        lColumnHeader.AutoResize( lAnyContents ? ColumnHeaderAutoResizeStyle.ColumnContent : ColumnHeaderAutoResizeStyle.HeaderSize );
    }
}

我没有测量这种方法的速度或任何东西,但它似乎工作。只是希望找到一个更优雅的解决方案。