2012年03月20日

[C#] ListViewの項目を自動でソートする

 ListViewは、その項目であるListViewItemを自動的に並び替えるためのメンバーを持っています。ListViewItem.ListViewItemSorterプロパティがそれですが、このプロパティのクラスはSystem.Collections.IComparerです。したがって、IComparerを実装クラスを用意して、その実体をListViewItemSorterプロパティに代入すればよいことになります。
人気ブログランキング

 しかし、比較が必要な場面が出てくるたびに1つずつクラスを作っていたのでは面倒なので、比較用メソッドを格納するだけのクラスを作ってしまいます。

// 比較用メソッドを格納しておくクラス
class DelegateComparison : System.Collections.IComparer
{
  // 比較用メソッドの型を表すデリゲート
  public delegate int CompareFunc(object a,object b);

  // 比較用メソッドを格納するフィールド
  CompareFunc func;

  // DelegateComparisonの構築子
  public DelegateComparison(CompareFunc func)
  {
    // 指定されたメソッドを格納するだけ。
    this.func=func;
  }

  // IComparerのCompareメソッドを実装
  public int Compare(object a,object b)
  {
    // 比較用メソッドを呼び出すだけ
    return this.func(a,b);
  }
}

 このクラスのCompareメソッドを呼び出すと、あらかじめ構築子の引数として渡しておいたメソッドを実行します。デリゲートになじみのない方は、「func」はメソッドを代入しておく変数だと思ってください。どんなメソッドでも代入できるわけではなく、返却値の型と、全ての引数の型が一致していなければなりません。

 ここまで実装できれば、あとはDelegateComparisonクラスのオブジェクトを作り、ListViewItem.ListViewItemSorterプロパティに代入するだけです。下記のソースでは、indexフィールドとdescendingフィールドで、ソートに使用する列とソート順(昇順、逆順)を指定しています。

public partial class Form1 : Form
{
  // 実際に比較するメソッド
  int ItemCompare(object a,object b)
  {
    // 単純に型変換
    ListViewItem itemA=(ListViewItem)a;
    ListViewItem itemB=(ListViewItem)b;
    
    // 比較したい列を取得
    string textA=itemA.SubItems[column].Text;
    string textB=itemB.SubItems[column].Text;

    // 比較
    int result=textA.CompareTo(textB);
    
    // 逆順ソートなら-1倍して返す。
    if(descending) return -result;
    else return result;
  }

  // ソートに使用する列
  int column;

  // trueなら逆順ソート
  bool descending;

  // フォームデザイナが生成した構築子
  public Form1()
  {
    InitializeComponent();

    this.column=1;
    this.descending=true;

    // 比較用メソッドを登録する。
    listView.ListViewItemSorter
      =new DelegateComparison(this.ItemCompare);
  }

}

// 比較用メソッドを格納しておくクラス
class DelegateComparison : System.Collections.IComparer
{
  // 比較用メソッドの型を表すデリゲート
  public delegate int CompareFunc(object a,object b);

  // 比較用メソッドを格納するフィールド
  CompareFunc func;

  // DelegateComparisonの構築子
  public DelegateComparison(CompareFunc func)
  {
    // 指定されたメソッドを格納するだけ。
    this.func=func;
  }

  // IComparerのCompareメソッドを実装
  public int Compare(object a,object b)
  {
    // 比較用メソッドを呼び出すだけ
    return this.func(a,b);
  }
}

 実行結果の例です。Column2が逆順にソートされています。
SortResult.png
web拍手 by FC2
posted by 北条利彦 at 16:49 | Comment(0) | TrackBack(0) | C# | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。
この記事へのトラックバックURL
http://blog.seesaa.jp/tb/258929980

この記事へのトラックバック
×

この広告は1年以上新しい記事の投稿がないブログに表示されております。