ListViewソート処理について – プログラミング – Home

ListViewソート処理について
 
通知
すべてクリア

[解決済] ListViewソート処理について


C#初心者
 C#初心者
(@C#初心者)
ゲスト
結合: 21年前
投稿: 29
Topic starter  

すみません。ListViewコントロールについて再度教えてください。

ListViewのコントロールプロパティにてSortingプロパティをAscendingとして
セルに追加されたアイテムを昇順ソートするようにしていますが

セルにはString型の配列の中身をFor文でループさせてItem.Addメソッドで追加
しています。

配列の中身が

a[0]・・・7
a[1]・・・8
a[2]・・・9
a[3]・・・10
a[4]・・・11

とString型の数値が格納されているのですがこれをListViewへ追加するとList
Viewの表示順が

10
11
7
8
9

となってしまいます。これを簡単に昇順ソートするにはどのようにすればいい
でしょうか?


引用未解決
トピックタグ
YuO
 YuO
(@YuO)
ゲスト
結合: 21年前
投稿: 320
 

昇順というのが,int型において昇順ソートであると仮定します。
# String型の数値はありえないし,String型の昇順ソートとして結果は正しいので。

Sortingプロパティのヘルプにある通り,ListViewItemSorterを設定してやる必要があり
ます。
http://msdn.microsoft.com/ja-jp/library/
system.windows.forms.listview.sorting.aspx
http://msdn.microsoft.com/ja-jp/library/
system.windows.forms.listview.listviewitemsorter.aspx


返信引用
C#初心者
 C#初心者
(@C#初心者)
ゲスト
結合: 21年前
投稿: 29
Topic starter  

YuOさん

回答ありがとうございました。

>Sortingプロパティのヘルプにある通り,ListViewItemSorterを設定し
>てやる必要があります。

MSDNにて調べたのですがListViewItemSorterを使用するには別クラスを
作成しなければならないのでしょうか?

出来る限り簡単にやりたかったのですが・・。


返信引用
YuO
 YuO
(@YuO)
ゲスト
結合: 21年前
投稿: 320
 

> MSDNにて調べたのですがListViewItemSorterを使用するには別クラスを
> 作成しなければならないのでしょうか?

そうです。

IComparerを継承したクラスを生成するか,
ListViewItemを継承し,IComparable or IComparable<ListViewItem>を継承したクラスを
生成してListViewItemSorterにはComparer.Default等を渡すか,です。

> 出来る限り簡単にやりたかったのですが・・。

難しいところはどこかにありますか?
nullの存在を無視すれば,IComparerの継承クラスなんて数行でしょうに……。

class Comparer : System.Collections.IComparer
{
public static readonly Comparer Default = new Comparer(); //
System.Collections.Comparerなどに倣ってDefaultを用意してみた。
public int Compare (object x, object y)
{
ListViewItem x1 = (ListViewItem)x, y1 = (ListViewItem)y;
int x2 = Int32.Parse(x1.Text), y2 = Int32.Parse(y1.Text);
return x2.CompareTo(y2);
}
}


返信引用
FUKU
 FUKU
(@FUKU)
ゲスト
結合: 17年前
投稿: 73
 

昔作ったサンプルがあったので貼っときます。

using System.Collections;

private void listView1_ColumnClick(object sender, ColumnClickEventArgs e) {
  listView1.ListViewItemSorter = new ListViewItemComparer(e.Column,
sortOrder);
  listView1.Sort();
  // 次回は逆順
  sortOrder *= -1;
  sortColumn = e.Column;
}

class ListViewItemComparer : IComparer {
  private int col;
  private int sortOrder;

  // コンストラクタ
  public ListViewItemComparer(int col, int sortOrder) {
    this.col=col;
    this.sortOrder = sortOrder;
  }
  // 比較メソッド
  public int Compare(object x, object y) {
    int ret = 0;
    switch (col) {
    case 0: // 文字列でソート
      ret = String.Compare(((ListViewItem)x).SubItems[col].Text,
          ((ListViewItem)y).SubItems[col].Text);
      break;
    case 1: // 数値でソート
      ret = int.Parse(((ListViewItem)x).SubItems[col].Text) <
         int.Parse(((ListViewItem)y).SubItems[col].Text) ? -1 : 1;
      break;
    }
    return ret * sortOrder;
  }
}

VC++なら StrCmpLogicalW() という便利なAPIがあるんですけどねぇ


返信引用
C#初心者
 C#初心者
(@C#初心者)
ゲスト
結合: 21年前
投稿: 29
Topic starter  

YuOさん、FUKUさん

ご返事遅くなりすみません。アドバイスありがとうございました。上記の通り
IComparerの継承クラスを作成したところ上手くソートすることが出来ました。
ただ上記のサンプルコードのようにListViewのColumnClickイベントハンドラで
ソート出来るようになっているのでこれをColumnClickではなくフォーム上の
ボタン押下でListViewへアイテムをAddする時にAddされたものをソートしたいの
です。この場合はボタン押下イベントでListViewItemSorterを設定すると思いま
すが

ListView1.ListViewItemSorter = New ListViewItemComparer(e.Column)

上記のe.Columnではこの場合何を渡せばいいのでしょうか?カラムは3列あって
1列目でソートをかけたいと思っています。

IComparerの継承クラスは以下です↓

public class ListViewItemComparer : IComparer
{
private int _column;

/// <summary>
/// ListViewItemComparerクラスのコンストラクタ
/// </summary>
/// <param name=col>並び替える列番号</param>
public ListViewItemComparer(int col)
{
_column = col;
}

//xがyより小さいときはマイナスの数、大きいときはプラスの数、
//同じときは0を返す
public int Compare(object x, object y)
{
//ListViewItemの取得
ListViewItem itemx = (ListViewItem) x;
ListViewItem itemy = (ListViewItem) y;

//xとyを文字列として比較する
return string.Compare(itemx.SubItems[_column].Text,
itemy.SubItems[_column].Text);
}
}


返信引用
C#初心者
 C#初心者
(@C#初心者)
ゲスト
結合: 21年前
投稿: 29
Topic starter  

>>上記のe.Columnではこの場合何を渡せばいいのでしょうか?
>>カラムは3列あって1列目でソートをかけたいと思っています。

パラメータの引数がそのまま列番号なのでint colには1を渡せば
いいんですかね。手元に環境が無いので推測になってしまいます
が・・・。


返信引用
YuO
 YuO
(@YuO)
ゲスト
結合: 21年前
投稿: 320
 

添字は0から数えるので,先頭の列でソートしたいのであれば,0を指定する必要がありま
す。


返信引用
C#初心者
 C#初心者
(@C#初心者)
ゲスト
結合: 21年前
投稿: 29
Topic starter  

YuOさん

こんばんは。さっそくの回答ありがとうございます。

>>添字は0から数えるので,先頭の列でソートしたいのであれば,0を指定する
>>必要があります。

そうでした、0始まりでしたね(^^);
連休明けに実機にて確認してまた報告させて頂きます。いろいろとアドバイスありがと
うございました。


返信引用
C#初心者
 C#初心者
(@C#初心者)
ゲスト
結合: 21年前
投稿: 29
Topic starter  

皆様のアドバイスのお陰で実装して問題なくソートできることを
確認しました。

そこで再度お聞きしたいことがありますが

>>ListViewのColumnClickイベントハンドラで
>>ソート出来るようになっているのでこれをColumnClickではなくフォーム上の
>>ボタン押下でListViewへアイテムをAddする時にAddされたものをソートしたいの
>>です。この場合はボタン押下イベントでListViewItemSorterを設定すると思いま
>>すが

この処理は別にボタン押下イベントで記述しなくてもいいのでしょうか?最初に呼ばれ
るコンストラクタで

ListView1.ListViewItemSorter = New ListViewItemComparer();

を定義しても上手くいきました。どちらがコードの記述として正しいのでしょうか?


返信引用
C#初心者
 C#初心者
(@C#初心者)
ゲスト
結合: 21年前
投稿: 29
Topic starter  

すいません、勘違いでした。先程の質問は解決済みです。


返信引用
C#初心者
 C#初心者
(@C#初心者)
ゲスト
結合: 21年前
投稿: 29
Topic starter  

すみません、解決チェック忘れていました・・・。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました