RunningCSharp

MS系開発者による、雑多な記事。記事は所属企業とは関係のない、個人の見解です。

WPF:DataGridの列ヘッダークリックによるソートを「昇順」→「降順」→「ソート無し」の繰り返しにカスタム

WPFのデータグリッドの標準的な列ヘッダークリックソートの動きは「昇順」→「降順」→「昇順」…の繰り返しなのですが、 これを「昇順」→「降順」→「ソート無し(データソースの並び順)」→「昇順」…の繰り返しに変更します。

DataGrid向けの添付プロパティを用意します。

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

namespace DataGridSort
{
    public class Attached
    {
        public static bool GetIsSortCustomize(DependencyObject obj)
        {
            return (bool)obj.GetValue(IsSortCustomizeProperty);
        }

        public static void SetIsSortCustomize(DependencyObject obj, bool value)
        {
            obj.SetValue(IsSortCustomizeProperty, value);
        }

        //Trueに設定した場合、ソートを昇順、降順、なしの順で行われるカスタムが施される
        public static readonly DependencyProperty IsSortCustomizeProperty =
            DependencyProperty.RegisterAttached("IsSortCustomize", typeof(bool), typeof(Attached), new PropertyMetadata(OnIsSortCustomizeChanged));

        private static void OnIsSortCustomizeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var datagrid = d as DataGrid;
            if (datagrid == null) return;
            if ((bool)e.NewValue)
            {
                datagrid.Sorting += Datagrid_Sorting;
            }
            else
            {
                datagrid.Sorting -= Datagrid_Sorting;
            }
        }

        private static void Datagrid_Sorting(object sender, DataGridSortingEventArgs e)
        {
            var datagrid = sender as DataGrid;
            if (datagrid.ItemsSource == null) return;

            var listColView = (ListCollectionView)CollectionViewSource.GetDefaultView(datagrid.ItemsSource);
            if (listColView == null) return;

            if (e.Column.SortDirection == ListSortDirection.Descending)
            {
                //ソートを中断
                e.Handled = true;
                //ソートの方向をクリア
                e.Column.SortDirection = null;
                datagrid.Items.SortDescriptions.Clear();
            }
        }
    }
}

上記の添付プロパティを、下記のような形で使用します。

<Window
        xmlns:atpr="clr-namespace:DataGridSort"

><Grid>
        <DataGrid … atpr:Attached.IsSortCustomize="True"/>
    </Grid>
</Window>

上記の実装を行い実行し、

f:id:ys-soniclab:20160827113454p:plain

列ヘッダーをクリックすると、

f:id:ys-soniclab:20160827113544p:plain

昇順ソート、

f:id:ys-soniclab:20160827113631p:plain

降順ソート、

f:id:ys-soniclab:20160827113648p:plain

ソート無し、の順に遷移し、もう一度クリックすると昇順ソートを行います。