ListView Sort

ListView のカラムクリックでアイテムをソートします。

前田稔(Maeda Minoru)の超初心者のプログラム入門

プログラムの説明

  1. Directory を検索して ListView に「名前,更新日付,サイズ,拡張子」を設定して表示します。
    ListView のカラム(名前,更新日付など)をクリックすると、昇順/降順を切り替えてソートします。
    このプログラムの作成に当たっては、下記のページを参考にさせていただきました。
    ListViewの項目を並び替える
  2. LVSort.cs の全ソースコードです。
    コマンドプロンプトの環境で実行することも出来ます。
    //★ List View Sort
    using System;
    using System.Collections;
    using System.Windows.Forms;
    using System.IO;
    
    public class MyForm : Form
    {
        ListView    ListView1;
        int[]       width = { 150, 120, 60, 40 };
        string[]    head = { "名前", "更新日付", "サイズ", "種類" };
        ListViewSort    LVSort;
    
        public MyForm()
        {
            InitializeComponent();
            Load += new System.EventHandler(MyForm_Load);
        }
    
        private void InitializeComponent()
        {
            this.ListView1 = new System.Windows.Forms.ListView();
            this.SuspendLayout();
            // ListView1
            this.ListView1.Location = new System.Drawing.Point(12, 12);
            this.ListView1.Name = "ListView1";
            this.ListView1.Size = new System.Drawing.Size(380, 232);
            ListView1.View = View.Details;
            ListView1.ColumnClick += new ColumnClickEventHandler(ListView1_ColumnClick);
            // MyForm
            this.ClientSize = new System.Drawing.Size(400, 256);
            this.Controls.Add(this.ListView1);
            this.Name = "MyForm";
            this.ResumeLayout(false);
        }
    
        // ListView の初期化
        private void MyForm_Load(object sender, System.EventArgs e)
        {
            // 列ヘッダの作成
            ColumnHeader[] columnHead = new ColumnHeader[4];
            for(int i=0; i<4; i++)
            {   columnHead[i] = new ColumnHeader();
                columnHead[i].Width = width[i];
                columnHead[i].Text = head[i];
            }
            ListView1.Columns.AddRange(columnHead);
    
            //DirectoryInfoを作成
            DirectoryInfo di = new DirectoryInfo( "C:\\Test" );     //パスを指定
            string[] item = new string[4];
    
            //ファイル一覧の取得
            FileInfo [] fis = di.GetFiles("*.*");   //パターンを指定
            for(int i=0; i<fis.Length; i++)
            {   item[0] = fis[i].FullName;
                item[1] = fis[i].LastWriteTime.ToString();
                item[2] = fis[i].Length.ToString();
                item[3] = fis[i].Extension;
                ListView1.Items.Add(new ListViewItem(item));
            }
    
            //ListViewSort の初期化
            LVSort = new ListViewSort();
            LVSort.ColumnModes = new ListViewSort.ComparerMode[]
            {   ListViewSort.ComparerMode.String,
                ListViewSort.ComparerMode.DateTime,
                ListViewSort.ComparerMode.Integer,
                ListViewSort.ComparerMode.String
            };
    
            //ListView の Sort を指定
            ListView1.ListViewItemSorter = LVSort;
        }
    
        // 列がクリックされたとき
        private void ListView1_ColumnClick(object sender, ColumnClickEventArgs e)
        {
            LVSort.Column = e.Column;
            ListView1.Sort();
        }
    }
    
    //★ ListView カラムソートクラス
    public class ListViewSort : IComparer
    {
        // 比較モード
        public enum ComparerMode
        {
            String,
            Integer,
            DateTime
        };
    
        private ComparerMode[]  _columnModes;
        private ComparerMode    _mode;
        private int             _column;
        private SortOrder       _order;
    
        //☆ Set,Get アクセッサ
        // 各列ごとの比較モードを設定
        public ComparerMode[] ColumnModes
        {
            set
            {   _columnModes = value;  }
        }
    
        // 列がクリックされたときに設定
        public int Column
        {
            set
            {   if (_column == value)       //昇順・降順の切替
                {   if (_order == SortOrder.Ascending)
                        _order = SortOrder.Descending;
                    else if (_order == SortOrder.Descending)
                        _order = SortOrder.Ascending;
                }
                _column = value;
            }
            get
            {   return _column;  }
        }
    
        // ListViewSortクラスのコンストラクタ
        // 並び替える列番号
        // 昇順か降順か
        // 並び替えの方法
        public ListViewSort(int col, SortOrder ord, ComparerMode cmod)
        {
            _column = col;
            _order = ord;
            _mode = cmod;
        }
        public ListViewSort()
        {
            _column = 0;
            _order = SortOrder.Ascending;
            _mode = ComparerMode.String;
        }
    
        // 比較メソッド
        public int Compare(object x, object y)
        {
            int result = 0;
    
            //ListViewItemの取得
            ListViewItem itemx = (ListViewItem) x;
            ListViewItem itemy = (ListViewItem) y;
    
            //並べ替えの方法を決定
            if (_columnModes != null && _columnModes.Length > _column)
                _mode = _columnModes[_column];
    
            //比較モード毎に x と y を比較
            switch (_mode)
            {
                case ComparerMode.String:
                    result = string.Compare(itemx.SubItems[_column].Text,
                        itemy.SubItems[_column].Text);
                    break;
                case ComparerMode.Integer:
                    result = int.Parse(itemx.SubItems[_column].Text) - 
                        int.Parse(itemy.SubItems[_column].Text);
                    break;
                case ComparerMode.DateTime:
                    result = DateTime.Compare(
                        DateTime.Parse(itemx.SubItems[_column].Text), 
                        DateTime.Parse(itemy.SubItems[_column].Text));
                    break;
            }
    
            //降順の時は符号を反転
            if (_order == SortOrder.Descending)
                result = -result;
            else if (_order == SortOrder.None)
                result = 0;
    
            return result;
        }
    }
    
    class form01
    {
        public static void Main()
        {
            MyForm mf = new MyForm();
            Application.Run(mf);
        }
    }
    
  3. プログラムはフォルダ(C:\\Test)を検索して、ファイル一覧をカラム設定で表示しています。
    フォルダ検索とカラムの設定は ListView Directory を参照して下さい。
  4. LVSort が ListView をソートする Class の定義です。
    ComparerMode[] でカラムごとの比較モードを設定します。
    "名前"は String で、"更新日付"は DateTime で、"サイズ"は Integer で、"種類"は String で比較します。
    ListViewItemSorter でソートするクラスを指定します。
    using System.Collections;
    
        ListViewSort    LVSort;
    
            //ListViewSort の初期化
            LVSort = new ListViewSort();
            LVSort.ColumnModes = new ListViewSort.ComparerMode[]
            {   ListViewSort.ComparerMode.String,
                ListViewSort.ComparerMode.DateTime,
                ListViewSort.ComparerMode.Integer,
                ListViewSort.ComparerMode.String
            };
    
            //ListView の Sort を指定
            ListView1.ListViewItemSorter = LVSort;
    
  5. ソートはカラムがクリックされたときに実行されます。
    LVSort.Column = e.Column; でカラム番号を格納します。
    ListView1.Sort(); でソートします。
            ListView1.ColumnClick += new ColumnClickEventHandler(ListView1_ColumnClick);
    
        private void ListView1_ColumnClick(object sender, ColumnClickEventArgs e)
        {
            LVSort.Column = e.Column;
            ListView1.Sort();
        }
    
  6. ListView をソートする Class の定義です。
    _columnModes がカラムごとの比較モードの領域です。
    _mode, _column, _order にソートするパラメータを設定します。
    _mode には、比較モードを設定します。
    _column なは、カラム番号を設定します。
    _order には、昇順/降順を設定します。
    public class ListViewSort : IComparer
    {
        // 比較モード
        public enum ComparerMode
        {
            String,
            Integer,
            DateTime
        };
    
        private ComparerMode[]  _columnModes;
        private ComparerMode    _mode;
        private int             _column;
        private SortOrder       _order;
    
  7. ソートクラスのアクセッサです。
    ColumnModes はカラムごとの比較モードを設定するときに参照されます。
        public ComparerMode[] ColumnModes
        {
            set
            {   _columnModes = value;  }
        }
    
  8. Column は列がクリックされたときに参照されます。
    同じ列の時は、昇順と降順を交互に切り替えます。
        public int Column
        {
            set
            {   if (_column == value)       //昇順・降順の切替
                {   if (_order == SortOrder.Ascending)
                        _order = SortOrder.Descending;
                    else if (_order == SortOrder.Descending)
                        _order = SortOrder.Ascending;
                }
                _column = value;
            }
            get
            {   return _column;  }
        }
    
  9. Compare() が比較するメソッドです。
        // 比較メソッド
        public int Compare(object x, object y)
        {
            ・・・
    
  10. Windows(C++)でも同様のプログラムを作成しています。
    List View を Column でソートする を参照して下さい。

超初心者のプログラム入門(C# Frame Work)