C#のListViewのヘッダーをクリックして列をソートする方法
C#のListViewで、列のヘッダーをクリックしたときに、その列の項目で全体をソートする方法です。
目次
ListViewを並び替える手順
準備として、XAMLの方でGridViewColumnHeaderにTagとClickイベントを設定します。Tagは列ごとに別々の文字列を設定します。Clickイベントは、全ての列で同じイベントを呼び出すようにします。つまり、同じイベント名を指定します。
Clickイベント内で下記を行います。
クリックされたヘッダーのTagを調べて、文字列に変換します。
ListView.Items.SortDescriptions.Countプロパティを参照して、SortDescriptionsに登録されているSortDescriptionオブジェクトの数を調べます。
SortDescriptionオブジェクトが0でない場合は、LinqのLastメソッドを使って、コレクションの最後のオブジェクトを取り出して並び順を調べます。
SortDescriptionオブジェクトを作成して、SortDescriptionsコレクションに追加します。このときTagの文字列を使用します。
ListView.Items.SortDescriptionsプロパティに並び順を設定する
ListView.Items.SortDescriptionsプロパティは、アイテムをどのような順番で表示するかを設定するプロパティです。
設定値は、SortDescriptionCollectionオブジェクトです。
SortDescriptionCollectionは、SortDescriptionオブジェクトのコレクションです。
SortDescriptionCollectionにSortDescriptionオブジェクトを追加するときはAddメソッドを、コレクション内のオブジェクトを全削除する場合はClearメソッドを使用します。
より具体的に言うと、ListView.Items.SortDescriptionsプロパティに、並び順を記入したSortDescriptionオブジェクトをAddすることで、アイテムを並び替えます。
SortDescriptionオブジェクト
コンストラクターは下記です。
SortDescription d = new SortDescription(str, direction);
変数 |
型 |
内容 |
---|---|---|
str |
String |
並べ替えに使用するプロパティ |
direction |
ListSortDirection |
並び替え順序 |
d |
SortDescription |
戻り値 |
ListSortDirectionには、下記の値があります。
値 |
内容 |
---|---|
Ascending |
昇順 |
Descending |
降順 |
オブジェクトの並び替え方向を調べるには、SortDescriptionオブジェクトのDirectionプロパティを参照します。 Directionプロパティの型は、ListSortDirectionです。
実施例
XAML
<Window x:Class="listview_test.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:listview_test"
mc:Ignorable="d"
Title="MainWindow" Height="200" Width="200" Loaded="Window_Loaded">
<Grid>
<ListView Name="ListViewMain" ItemsSource="{Binding}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="10" >
<ListView.View>
<GridView>
<GridViewColumn DisplayMemberBinding="{Binding Path=Moji}">
<GridViewColumnHeader Content="文字" Tag="Moji" Click="GridViewColumnHeader_Click" />
</GridViewColumn>
<GridViewColumn DisplayMemberBinding="{Binding Path=Chk}">
<GridViewColumnHeader Content="Check" Tag="Chk" Click="GridViewColumnHeader_Click" />
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</Grid>
</Window>
XAMLの説明
WindowにListViewがあるだけのアプリです。
データのオブジェクトはListViewにバインディングします。そのオブジェクトのMojiプロパティとChkプロパティをそれぞれGridViewColumnにPathで指定してバインドします。
各GridViewColumnHeaderにTagとClickを設定します。Tagは各列それぞれ固有のものを設定します。Clickイベントには全て同じイベントを設定します。ここでは、各列に同じイベントハンドラ(GridViewColumnHeader_Click)を指定しています。
コード
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
namespace listview_test
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
ObservableCollection<Hoge> Piyo = new ObservableCollection<Hoge>();
private void Window_Loaded(object sender, RoutedEventArgs e)
{
Piyo.Add(new Hoge() { Moji = "いろは", Chk = true });
Piyo.Add(new Hoge() { Moji = "にほへと", Chk = false });
Piyo.Add(new Hoge() { Moji = "ちりぬるを", Chk = true });
Piyo.Add(new Hoge() { Moji = "わかよたれそ", Chk = false });
Piyo.Add(new Hoge() { Moji = "つねならむ", Chk = true });
ListViewMain.DataContext = Piyo;
}
private void GridViewColumnHeader_Click(object sender, RoutedEventArgs e)
{
GridViewColumnHeader columnHeader = (GridViewColumnHeader)sender;
string columnTag = columnHeader.Tag.ToString();
if (ListViewMain.Items.Count > 1)
{
ListSortDirection sortDirection;
if (ListViewMain.Items.SortDescriptions.Count == 0)
{
sortDirection = ListSortDirection.Descending;
}
else
{
if (ListViewMain.Items.SortDescriptions.Last().Direction == ListSortDirection.Ascending)
{
sortDirection = ListSortDirection.Descending;
}
else
{
sortDirection = ListSortDirection.Ascending;
}
ListViewMain.Items.SortDescriptions.Clear();
}
ListViewMain.Items.SortDescriptions.Add(new SortDescription(columnTag, sortDirection));
}
}
}
public class Hoge
{
public string Moji { get; set; }
public bool Chk { get; set; }
}
}
コードの説明
データのオブジェクトは、HogeクラスのPiyoとします。
Window_Loadedイベントで、データの中身を作って、PiyoオブジェクトをListViewにバインディングします。
GridViewColumnHeader_Clickメソッドが呼び出されると、まずsenderをGridViewColumnHeaderにキャストして、Tagプロパティを取り出します。これで、クリックされた列のTagが取り出されます。
ListView.Items.CountでListViewにバインドされているコレクション内のアイテムの個数を調べます。これが0や1なら並べ替える必要がありませんので、1を超える場合だけ続きの処理をします。
ListView.Items.SortDescriptions.Countが0の場合は、アイテムの並び替えが行われていないので、初めて並び替えるものとしてListSortDirection.Descendingを選択します。
ListView.Items.SortDescriptions.Countが0以外の場合は、ListView.Items.SortDescriptions.Last().Directionでコレクションの最後のオブジェクトの並び替え方向を調べます。 そして、その方向とは逆の並び替え方向(ListSortDirection.DescendingまたはListSortDirection.Ascending)を選択します。
どの並び順を登録するか決めたら、登録する前にListView.Items.SortDescriptions.Clear()メソッドでコレクション内のオブジェクトを全削除します。
TagとListSortDirectionを使って、SortDescriptionオブジェクトを作成します。そして、そのオブジェクトをListView.Items.SortDescriptionsコレクションにAddメソッドで追加します。
そうすると、ListViewが並び変わります。
実行例
上記のプログラムを実行するとこのようなウィンドウが表示されます。
「文字」のヘッダーをクリックすると、このように並び変わります。
もう一回クリックすると、逆順に並び変わります。
ブール値でもソートできます。
公開日
広告
C#のコントロールカテゴリの投稿
- C#でコレクションの要素の変更をバインド先のコントロールに反映する方法
- C#のComboBoxを使ってみた
- C#のDataGridで右クリックメニューを作ってみた
- C#のDataGridの罫線と背景色を変えてみた
- C#のListBoxでCheckBoxを並べてみた
- C#のListBoxを使ってみた
- C#のListViewで列のタイトルを変える
- C#のListViewで選択したアイテムを取得する方法
- C#のListViewに文字を入力する方法
- C#のListViewのヘッダーをクリックして列をソートする方法
- C#のListViewを使ってみた
- C#のRadioButtonで選択された項目を調べる(foreach編)
- C#のRadioButtonを試してみた
- C#のTextBoxで最下行に自動でスクロールする方法
- C#のWPFのコントロール一覧
- C#のスライダコントロールを試してみた
- C#のタブをコードから切り替える
- C#のメニューのイベントを1つにまとめてみた