0

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

var lMode = ( listView.Items.Count == 0 ) ? ColumnHeaderAutoResizeStyle.HeaderSize : ColumnHeaderAutoResizeStyle.ColumnContent;
foreach ( ColumnHeader lColumnHeader in listView.Columns )
{
    lColumnHeader.AutoResize(lMode);
}

这种技术的问题是,如果我有一列碰巧没有数据,宽度会设置为标题不再可用的点。ColumnHeaderAutoResizeStyle有没有一种根据列中是否有内容有条件地设置的好方法?

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

4

2 回答 2

2

This is a method I've been using for a little while now that does not involve measuring strings.

The bool parameter is because I call the method by itself (and set the parameter to true), and sometimes I call it directly after an Items.AddRange(ListViewItem[]) call, in which I'd wrap both calls in the Begin/End Update calls.

    /// <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();

    }
于 2012-11-06T19:33:28.493 回答
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 );
    }
}

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

于 2012-06-27T15:59:46.800 回答