Как я могу применить пользовательскую сортировку для WPF DataGrid из стиля? - PullRequest
0 голосов
/ 08 апреля 2019

У меня есть стиль, который я хочу применить к DataGrid. DataGrid должен запускать мой собственный код сортировки вместо сортировки по умолчанию DataGrid. Решение, которое я попробовал, было следующим:

<Style TargetType="{x:Type DataGrid}" x:Key="FilteredDataGrid">
    <EventSetter Event="Sorting" Handler="DataGrid_Sorting"/>
</Style>

А в коде позади:

private void DataGrid_Sorting(object sender, DataGridSortingEventArgs e) {

    e.Handled = true;

    //Here is where I put the code for my custom sort.

}//DataGrid_Sorting

Однако этот код не создается. Мне кажется, что, поскольку событие DataGrid.Sorting не является RoutedEvent, его нельзя использовать в EventSetter.

Как настроить сортировку для любой DataGrid, к которой применен мой стиль?

1 Ответ

1 голос
/ 09 апреля 2019

Существует обходной путь для предоставления перенаправленного события, когда у вас есть только «нормальное» событие:

Создайте вложенное свойство, которое управляет переадресацией события, и вложенное событие, которое должно заменить исходное событие.Для этого создайте класс DataGridEx (какое бы имя класса вы ни выбрали) в качестве контейнера для присоединенного свойства (DataGridEx.EnableSortingEvent) и события (DataGridEx.Sorting).

Также создайте пользовательскийRoutedEventArgs класс, который пересылает исходные аргументы события сортировки

public class DataGridExSortingEventArgs : RoutedEventArgs
{
    public DataGridExSortingEventArgs(RoutedEvent routedEvent, DataGridSortingEventArgs sourceEventArgs) : base(routedEvent)
    {
        SourceEventArgs = sourceEventArgs;
    }

    public DataGridSortingEventArgs SourceEventArgs { get; set; }
}

public static class DataGridEx
{
    public static bool GetEnableSortingEvent(DependencyObject obj)
    {
        return (bool)obj.GetValue(EnableSortingEventProperty);
    }

    public static void SetEnableSortingEvent(DependencyObject obj, bool value)
    {
        obj.SetValue(EnableSortingEventProperty, value);
    }

    // Setting this property to true enables the event forwarding from the DataGrid.Sorting event to the DataGridEx.Sorting RoutedEvent
    public static readonly DependencyProperty EnableSortingEventProperty = DependencyProperty.RegisterAttached(
        "EnableSortingEvent",
        typeof(bool),
        typeof(DataGridEx),
        new FrameworkPropertyMetadata(false, new PropertyChangedCallback(OnEnableSortingChanged)));

    private static void OnEnableSortingChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (d is DataGrid dg)
        {
            if ((bool)e.NewValue)
                dg.Sorting += Dg_Sorting;
            else
                dg.Sorting -= Dg_Sorting;
        }
    }

    // When DataGrid.Sorting is called and DataGridEx.EnableSortingEvent is true, raise the DataGridEx.Sorting event
    private static void Dg_Sorting(object sender, DataGridSortingEventArgs e)
    {
        if (sender is DataGrid dg && GetEnableSortingEvent(dg))
        {
            dg.RaiseEvent(new DataGridExSortingEventArgs(SortingEvent, e));
        }
    }

    // When DataGridEx.EnableSortingEvent is true, the DataGrid.Sorting event will be forwarded to this routed event
    public static readonly RoutedEvent SortingEvent = EventManager.RegisterRoutedEvent(
        "Sorting",
        // only effective on the DataGrid itself
        RoutingStrategy.Direct,
        typeof(RoutedEventHandler),
        typeof(DataGridEx));

    public static void AddSortingHandler(DependencyObject d, RoutedEventHandler handler)
    {
        if (d is DataGrid dg)
            dg.AddHandler(SortingEvent, handler);
    }

    public static void RemoveSortingHandler(DependencyObject d, RoutedEventHandler handler)
    {
        if (d is DataGrid dg)
            dg.RemoveHandler(SortingEvent, handler);
    }
}

Теперь используйте их в своем стиле (local - это xmlns для пространства имен, в котором определен DataGridEx):

<Style TargetType="DataGrid">
    <Setter Property="local:DataGridEx.EnableSortingEvent" Value="True"/>
    <EventSetter Event="local:DataGridEx.Sorting" Handler="DataGrid_Sorting"/>
</Style>

Обработчик

private void DataGrid_Sorting(object sender, RoutedEventArgs e)
{
    if (e is DataGridExSortingEventArgs args)
    {
        // will prevent datagrid default sorting
        args.SourceEventArgs.Handled = true;
    }

    // More stuff
}

Надеюсь, это то, что вам нужно.Пришлось освежить мою память о прикрепленном материале:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...