以前作成した記事のソート部分をコードビハインドで書き直してみました。
C#のWPFでリストビューでアイテムの選択とコンテキストメニュー2「ヘッダークリックでソート」
前回の問題点として右クリックで表示するコンテキストメニューやダブルクリックの検出がリストビューのアイテム以外でも動作してしまう点がありました。ネット検索して解決方法を探しプログラムに組み込んでみました。また、リストビューの項目のヘッダーをク...
ソースコード
<Window x:Class="ListViewSort01.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:ListViewSort01"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<ListView ItemsSource="{Binding Files}">
<ListView.View>
<GridView>
<GridViewColumn Width="200">
<GridViewColumnHeader
x:Name="HeadName1"
Content="名前" />
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock
Width="100"
TextAlignment="Left"
Text="{Binding Name}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Width="200">
<GridViewColumnHeader
x:Name="HeadLength1"
Content="長さ" />
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock
Width="100"
TextAlignment="Right"
Text="{Binding Length}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</Grid>
</Window>
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
using System.Windows.Automation.Peers;
using System.Diagnostics;
using System.ComponentModel;
namespace ListViewSort01;
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public class FilesItem
{
public string Name { get; set; } = "";
public int Length { get; set; } = 0;
}
public ObservableCollection<FilesItem> Files { get; set; } = [];
public MainWindow()
{
InitializeComponent();
Files.Add(new FilesItem(){Name = "abc.txt", Length = 600 });
Files.Add(new FilesItem(){Name = "def.txt", Length = 300 });
Files.Add(new FilesItem(){Name = "ghi.txt", Length = 50 });
HeadName1.Click += (s, e) =>
{
//Debug.Print("HeadName1 Click");
const string propertyName = "Name";
var collectionView = CollectionViewSource.GetDefaultView(Files);
if (collectionView.SortDescriptions.Any() == false || collectionView.SortDescriptions[0].PropertyName != propertyName)
{
collectionView.SortDescriptions.Clear();
collectionView.SortDescriptions.Add(new SortDescription(propertyName, ListSortDirection.Descending));
return;
}
var d = collectionView.SortDescriptions[0].Direction == ListSortDirection.Ascending ? ListSortDirection.Descending : ListSortDirection.Ascending;
collectionView.SortDescriptions.Clear();
collectionView.SortDescriptions.Add(new SortDescription(propertyName, d));
};
DataContext = this;
}
}
実行
ヘッダーの「名前」をクリックすると
ソートされます。
説明
ソートの部分のみをコードビハインドで書き直したら、ソースコードが短くなって理解しやすくなるのではと期待しましたが、それほど短くはなりませんでした。XAMLのネストの深さは辟易します。
ソートのコード部分をみると、
データソースのFilesからcollectionViewを生成し、
var collectionView = CollectionViewSource.GetDefaultView(Files);
既存のソートの条件?をクリアし、
collectionView.SortDescriptions.Clear();
そのオブジェクトにソートのキーとなる項目を追加
collectionView.SortDescriptions.Add(new SortDescription(propertyName, ListSortDirection.Descending));
すると、バインド先のListViewが並べ替えられるように見受けられます。
コメント