[.Net Framework][C#] ListViewで列を自動リサイズする

カラム長を最低幅に自動調整

カラムの文字数や要素の文字数が表示できる最低限のサイズに自動調整するにはListViewの以下のメソッドを使います。

ListView#AutoResizeColumns(スタイル指定)
すべてのカラムに対して適用する。
AutoResizeColumn(カラムインデックス,スタイル指定)
特定のカラムに対して適用する。

提供されているスタイルは2種類です。

ColumnHeaderAutoResizeStyle.HeaderSize
列のヘッダ文字列が最低限表示できるサイズに自動調整する。
ColumnHeaderAutoResizeStyle.ColumnContent
現在の列に含まれる全ての要素(ヘッダ除く)が最低限表示できるサイズに自動調整する。

例:

listView.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);
[/sharp]

<h2>カラム長を最大幅に自動調整</h2>

自動でリストの幅いっぱいのサイズまで埋めた長さに設定する方法は標準で提供されていませんが、
次のように実装することで実現できます。

[csharp]
using System.Windows.Forms;

class FillableListView: ListView
{
        public FillableListView():base(){
            this.ClientSizeChanged += (sender, args) =>
                handleFillColumn();
            // 利用例:最初の列を自動調整する。
            this.AutoFillColumn = 0;
        }

<pre><code>    private int _autoFillColumn = -1;
    /// &lt;summary&gt;
    /// リストの空列を補うよう自動調整を行うカラム番号(0~)。
    /// 負の値やカラム数を超える場合は調整を行わない。
    /// &lt;/summary&gt;
    public int AutoFillColumn
    {
        get { return this._autoFillColumn; }
        set
        {
            this._autoFillColumn = value;
            this.handleFillColumn();
        }
    }

    private void handleFillColumn()
    {
        System.Diagnostics.Debug.Print("fillcolumn:{0},{1}",this._autoFillColumn , this.Columns.Count);
            if (this._autoFillColumn &gt;= 0 &amp;&amp; this._autoFillColumn &lt; this.Columns.Count)
                fillColumnWidth(this, this._autoFillColumn);
    }
    /// &lt;summary&gt;
    /// リストビューの特定のカラム幅を余白を埋める幅に調整する。
    /// &lt;/summary&gt;
    /// &lt;param name="listView"&gt;&lt;/param&gt;
    /// &lt;param name="index"&gt;&lt;/param&gt;
    private static void fillColumnWidth(ListView listView, int index)
    {
        int width = listView.ClientRectangle.Width;
        for (int i = 0; i &lt; listView.Columns.Count; i++)
        {
            if (i == index) { continue; }
            width -= listView.Columns[i].Width;
        }
        listView.BeginUpdate();
        listView.Columns[index].Width = Math.Max(width, 0);
        listView.ResumeLayout(true);
        listView.EndUpdate();
    }
</code></pre>

}

実装時の要点

キモは次の3つ。

  • リサイズへの対応はClientSizeChangedイベントで更新する。
  • カラム長はListView#Widthでなくクライアント領域(listView.ClientRectangle.Width)で計算する。
  • ListView#BeginUpdate()からListView#EndUpdate()の間でリサイズ変更を適用する。

の3つです。
これを守っていればどのように実装しても大丈夫です。

最後に

今回は自前での実装を行いましたが、GPLライセンスで問題なければObjectListViewというライブラリを使うと幸せになるかもしれません。