WPFヘルパー:GridViewSort.cs – ヘッダークリックでソート機能を付与

コンピュータ

GridViewSort.cs

using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;

namespace Maywork.WPF.Helpers;

public static class GridViewSort
{
    public static readonly DependencyProperty EnableProperty =
        DependencyProperty.RegisterAttached(
            "Enable",
            typeof(bool),
            typeof(GridViewSort),
            new PropertyMetadata(false, OnEnableChanged));

    public static void SetEnable(DependencyObject obj, bool value)
        => obj.SetValue(EnableProperty, value);

    public static bool GetEnable(DependencyObject obj)
        => (bool)obj.GetValue(EnableProperty);

    private static void OnEnableChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (d is not ListView listView) return;

        if ((bool)e.NewValue)
        {
            listView.AddHandler(GridViewColumnHeader.ClickEvent,
                new RoutedEventHandler(OnHeaderClick));
        }
        else
        {
            listView.RemoveHandler(GridViewColumnHeader.ClickEvent,
                new RoutedEventHandler(OnHeaderClick));
        }
    }

    private static GridViewColumnHeader? _lastHeader;
    private static ListSortDirection _lastDirection;

    private static void OnHeaderClick(object sender, RoutedEventArgs e)
    {
        if (e.OriginalSource is not GridViewColumnHeader header)
            return;

        if (header.Column == null) return;

        var listView = (ListView)sender;

        string? sortBy = null;

        // DisplayMemberBinding から取得
        if (header.Column.DisplayMemberBinding is Binding binding)
        {
            sortBy = binding.Path.Path;
        }

        if (sortBy == null) return;

        // 昇順・降順トグル
        var direction = ListSortDirection.Ascending;

        if (_lastHeader == header && _lastDirection == ListSortDirection.Ascending)
        {
            direction = ListSortDirection.Descending;
        }

        ApplySort(listView, sortBy, direction);

        _lastHeader = header;
        _lastDirection = direction;
    }

    private static void ApplySort(ListView listView, string sortBy, ListSortDirection direction)
    {
        var view = CollectionViewSource.GetDefaultView(listView.ItemsSource);

        view.SortDescriptions.Clear();
        view.SortDescriptions.Add(new SortDescription(sortBy, direction));
        view.Refresh();
    }
}
Download

コメント