ListView の要素をカスタムソートする - C#

ListViewの要素をIComparerを用いてカスタムソートするコードを紹介します。

概要

こちらの記事では、ListViewの要素に情報を保持するためのオブジェクト(クラスのインスタンス)を割り当てる方法を紹介しました。この記事では、割り当てたオブジェクトの値を用いて独自のソートを実装するコードを紹介します。

UI

以下のUIを作成します。こちらで紹介しているプログラムのUIにボタンを一つ追加します。ListView,ImageListのプロパティの設定はこちらの記事を参照してください。

コード

以下のコードを記述します。

FormMain.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace ListViewDemo
{
  public partial class FormObjectAssign : Form
  {
    public FormObjectAssign()
    {
      InitializeComponent();
    }

    private void FormObjectAssign_Load(object sender, EventArgs e)
    {
      ListViewItem lvi;
      ItemInfo ii;

      lvi = new ListViewItem("Penguin",0);
      ii = new ItemInfo();
      ii.Name = "ペンギン";
      ii.Address = "南極";
      ii.Age = 3;
      lvi.Tag = ii;
      listView1.Items.Add(lvi);

      
      lvi = new ListViewItem("Chicken", 1);
      ii = new ItemInfo();
      ii.Name = "にわとり";
      ii.Address = "養鶏所";
      ii.Age = 1;
      lvi.Tag = ii;
      listView1.Items.Add(lvi);
      
      lvi = new ListViewItem("Pig", 2);
      ii = new ItemInfo();
      ii.Name = "ブタ";
      ii.Address = "養豚所";
      ii.Age = 2;
      lvi.Tag = ii;
      listView1.Items.Add(lvi);

      lvi = new ListViewItem("Whale", 3);
      ii = new ItemInfo();
      ii.Name = "クジラ";
      ii.Address = "太平洋";
      ii.Age = 20;
      lvi.Tag = ii;
      listView1.Items.Add(lvi);
    }

    private void listView1_SelectedIndexChanged(object sender, EventArgs e)
    {
      ItemInfo ii =null;

      if (listView1.SelectedItems.Count > 0) {
        ii = (ItemInfo)listView1.SelectedItems[0].Tag;
      }

      if (ii != null) {
        textBox1.Text = ii.Name;
        textBox2.Text = ii.Address;
        textBox3.Text = ii.Age.ToString();
      }
      else {
        textBox1.Text = "";
        textBox2.Text = "";
        textBox3.Text = "";
      }

    }

    private void button1_Click(object sender, EventArgs e)
    {
      listView1.ListViewItemSorter = new ListViewItemComparer();
    }
  }
}
解説
基本は、。こちらで紹介しているプログラムのコードと同じです。追加部分はボタンのClickイベント部分です。

private void button1_Click(object sender, EventArgs e)
{
  listView1.ListViewItemSorter = new ListViewItemComparer();
}
ボタンがクリックされた際にはListViewのListViewItemSorterにIComparerクラスの派生クラスのカスタムソート用クラス(ListViewItemComparer)のインスタンスを設定します。設定するとすぐにソートが実行されます。

ListViewItemComparer.cs

カスタムソート用の要素比較用クラスです。
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace ListViewDemo
{
  class ListViewItemComparer:IComparer
  {

    public ListViewItemComparer()
    {
    }

    public ListViewItemComparer(int column)
    {      
    }

    public int Compare(object x, object y)
    {
      ListViewItem ix = (ListViewItem)x;
      ListViewItem iy = (ListViewItem)y;

      ItemInfo iix = null;
      ItemInfo iiy = null;
      if (ix.Tag !=null){
        iix = (ItemInfo)(ix.Tag);
      }
      if (iy.Tag !=null){
        iiy = (ItemInfo)(iy.Tag);
      }

      if (iix.Age == iiy.Age){
        return 0;
      } 
      else if (iix.Age < iiy.Age){
        return -1;
      }
      else{
        return 1;
      }

    }
  }
}
解説
IComparerクラスを派生してListViewItemComparerクラスを定義します。Compareメソッドを実装します。Compareメソッドでは比較対象のListItemを選択し、Tagプロパティを参照しItemInfoオブジェクトを取得します。ItemInfoオブジェクトのAge変数の値でソートをします。

実行結果

プロジェクトを実行します。起動時は下図の画面が表示されます。アイテムの並びはコードで追加した順になっています。


画面下部の[Custom Sort]ボタンをクリックします。アイテムの並びが下図の状態に変わります。


要素のItemInfoオブジェクトに設定したAgeの昇順でソートされていることが確認できます。


著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用
最終更新日: 2024-01-06
作成日: 2013-06-06
iPentec all rights reserverd.