0

ListViewビューがView.Detailsあり、列を AutoSize したいと考えています。ColumnHeaderのメソッドを認識しておりAutoResize、現在、次のように繰り返し処理しています。

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

これは、弦を測定する必要のない、私が少し前から使用している方法です。

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

    }
于 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 に答える