Reputation: 1011
currently I am working on WPF's datagrid. I got an issue with automatic sorting. Here is my xaml:
<DataGrid x:Name="customTasksDataGrid" Margin="10,10,10,38" Grid.Column="1" IsReadOnly="True" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="ID" Binding="{Binding ID}"/>
<DataGridTextColumn Header="Client" Binding="{Binding Client.Names}"/>
...
<DataGridTextColumn Header="DueDate" Binding="{Binding DueDate, StringFormat=\{0:dd.MM.yy HH:mm\}}" SortDirection="Ascending">
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Foreground" Value="{Binding Path=., Converter={StaticResource converter}}"/>
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
...
</DataGrid.Columns>
The problem is: when I update my datagrid's ItemsSource, the datagrid is sorted by ID
column, not DueDate
as desirable. How to implement autosorting by DueDate
when any update action on my datagrid is performed?
I tried with: [ImplementPropertyChanged]
tag from PropertyChanged.Fody
and put it before my CustomTask
class, but this approach was not working at all ( don't even know if it is needed).
EDIT:
It can be done with:
customTasksDataGrid.ItemsSource = model;
customTasksDataGrid.Items.SortDescriptions.Add(new SortDescription("DueDate", ListSortDirection.Ascending));
Upvotes: 2
Views: 10959
Reputation: 1505
or use xaml extensions:
<UserControl xmlns:e="clr-namespace:Xaml.Extensions">
<DataGrid e:DataGridExtensions.DefaultSorting="A:Date">
<DataGrid e:DataGridExtensions.DefaultSorting="D:Time">
</UserControl>
using System;
using System.Windows;
using System.Windows.Controls;
using System.ComponentModel;
#nullable enable
namespace Xaml.Extensions
{
public static class DataGridExtensions
{
#region DefaultSorting
public static readonly DependencyProperty DefaultSortingProperty =
DependencyProperty.RegisterAttached(
nameof(DefaultSortingProperty).Replace("Property", string.Empty),
typeof(string),
typeof(DataGridExtensions),
new PropertyMetadata(string.Empty, OnDefaultSortingChanged));
public static string? GetDefaultSorting(DependencyObject element)
{
return (string?)element.GetValue(DefaultSortingProperty);
}
public static void SetDefaultSorting(DependencyObject element, string? value)
{
element.SetValue(DefaultSortingProperty, value);
}
private static void OnDefaultSortingChanged(
DependencyObject element,
DependencyPropertyChangedEventArgs args)
{
if (element is not DataGrid dataGrid)
{
throw new ArgumentException("Element should be DataGrid.");
}
if (args.NewValue is not string sorting)
{
throw new ArgumentException("Type should be string.");
}
var values = sorting.Split(':');
if (values.Length != 2)
{
throw new InvalidOperationException("String should be like 'A:Name' or 'D:Name'.");
}
dataGrid.Items.SortDescriptions.Clear();
dataGrid.Items.SortDescriptions.Add(
new SortDescription(
values[1],
values[0] == "D"
? ListSortDirection.Descending
: ListSortDirection.Ascending));
}
#endregion
}
}
This also works in the designer in real time if you specified DesignInstance
.
Upvotes: 0
Reputation: 1868
You can simply sort the datagrid in Code Behind:
datagrid.Items.SortDescriptions.Add(new SortDescription("DueDate", ListSortDirection.Ascending));
Upvotes: 3