3
votes

I tried to find a way to configure the wpf DataGrid to loop through sortings: {ascending, descending, no sort} when clicked repeatedly.

I wrote this (but did not love it hence this q):

<DataGrid AutoGenerateColumns="False">
    <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding DayOfWeek}" >
            <DataGridTextColumn.Header>
                <DataGridColumnHeader PreviewMouseLeftButtonDown="DataGridColumnHeaderClick">Day</DataGridColumnHeader>
            </DataGridTextColumn.Header>
        </DataGridTextColumn>
    </DataGrid.Columns>
    <sys:DateTime>1/2/3</sys:DateTime>
    <sys:DateTime>1/2/4</sys:DateTime>
    <sys:DateTime>1/2/5</sys:DateTime>
</DataGrid>
private void DataGridColumnHeaderClick(object sender, RoutedEventArgs e)
{
    var header = (DataGridColumnHeader) sender;
    if (header.SortDirection == ListSortDirection.Descending)
    {
        header.Column.SortDirection = null;
        e.Handled = true;
    }
}

Is there a way to configure the DataGrid to do this without hacking an eventhandler?

1

1 Answers

4
votes

Tried the solution suggested here like this:

<DataGrid AutoGenerateColumns="False" Sorting="DataGridSorting">
    <DataGrid.Columns>
        <DataGridTextColumn Header="Day" Binding="{Binding DayOfWeek}" />
        <DataGridTextColumn Header="Date" Binding="{Binding Date}" />
    </DataGrid.Columns>
    <sys:DateTime>1/1/1</sys:DateTime>
    <sys:DateTime>1/2/1</sys:DateTime>
    <sys:DateTime>1/3/1</sys:DateTime>
</DataGrid>
private void DataGridSorting(object sender, DataGridSortingEventArgs e)
{
    DataGrid dataGrid =(DataGrid) sender;
    string sortPropertyName = e.Column.SortMemberPath;
    if (!string.IsNullOrEmpty(sortPropertyName))
    {
        // sorting is cleared when the previous state is Descending
        if (e.Column.SortDirection.HasValue && e.Column.SortDirection.Value == ListSortDirection.Descending)
        {
            e.Column.SortDirection = null;
            if ((Keyboard.Modifiers & ModifierKeys.Shift) != ModifierKeys.Shift)
            {
                foreach (var sd in dataGrid.Items.SortDescriptions
                    .Where(sd => sd.PropertyName == sortPropertyName).ToList())
                {
                    dataGrid.Items.SortDescriptions.Remove(sd);
                }
            }
            else
            {
                dataGrid.Items.SortDescriptions.Clear();
            }
            dataGrid.Items.Refresh();
            e.Handled = true;
        }
    }
}