web-dev-qa-db-fra.com

Tri préalable d'un DataGrid dans WPF

J'ai une DataGrid dans l'application WPF avec plusieurs colonnes, y compris une colonne Nom. Si les utilisateurs basculent vers une vue particulière, je souhaite que les données soient triées par nom (et qu'une flèche de tri apparaisse dans l'en-tête du nom, comme si l'utilisateur avait cliqué sur cet en-tête). Cependant, je ne trouve pas les propriétés attendues pour que cela se produise. Je cherchais quelque chose comme SortColumn, SortColumnIndex, SortDirection, etc.

Est-il possible de spécifier la colonne de tri et la direction par défaut dans le balisage (XAML) ou est-ce que cela n'est pas pris en charge par WPF Toolkit DataGrid?

26
devuxer

En supposant que vous parlez du contrôle DataFrid de WPF Toolkit, il vous suffit de définir la propriété CanUserSortColumns sur true, puis de définir la propriété SortMemberPath de chaque DataGridColumn dans DataGrid.

En ce qui concerne le tri initial de la collection, vous devez utiliser CollectionViewSource et définir le tri sur celui-ci, puis l'affecter à l'élément ItemsSource de votre DataGrid. Si vous faites cela en XAML, ce serait aussi simple que:

<Window.Resources>
    <CollectionViewSource x:Key="MyItemsViewSource" Source="{Binding MyItems}">
        <CollectionViewSource.SortDescriptions>
           <scm:SortDescription PropertyName="MyPropertyName"/>
        </CollectionViewSource.SortDescriptions>
    </CollectionViewSource>
</Window.Resources>

<DataGrid ItemsSource="{StaticResource MyItemsViewSource}">

</DataGrid>

REMARQUE: le préfixe d'espace de noms "scm" est mappé sur System.ComponentModel où réside la classe SortDescription.

xmlns:scm="clr-namespace:System.ComponentModel;Assembly=WindowsBase"

EDIT: Je pense que suffisamment de personnes ont été aidées par ce message pour que ce commentaire voté soit inclus dans cette réponse:

Je devais l'utiliser pour le faire fonctionner:

<DataGrid ItemsSource="{Binding Source={StaticResource MyItemsViewSource}}">
42
Drew Marsh

Je sais qu'il s'agit d'un ancien message, mais en plus de la réponse de Drew Marsh et du problème de DanM avec les flèches de l'en-tête de colonne n'apparaissant pas ... Vous devez ajouter la propriété SortDirection au DataGridColumn:

<DataGridTextColumn Header="Name" Binding="{Binding Name}" SortDirection="Ascending" />

J'ai posté une question à ce sujet et j'ai trouvé la réponse quelques jours plus tard:

Les flèches ColumnHeader ne sont pas reflétées lors du tri d'un DataGrid en XAML

18
Matt

Lorsque vous voyez que ItemsSource ne prend pas en charge l'exception CollectionViewSource, vous pouvez définir le DataContext de DataGrid comme 'MyItemsViewSource' et ItemsSource comme {Binding} comme ceci:

<DataGrid DataContext="{StaticResource MyItemsViewSource}" ItemsSource="{Binding}">
</DataGrid>
4
Sukhjeet

Lorsque vous voyez une exception ItemsSource doesn't support CollectionViewSource, vous pouvez trier la collection par Linq avant de la renvoyer à un DataGrid:

ObservableCollection<MyDataClass> myCollection = new ObservableCollection<MyDataClass>();
dataGrid.ItemsSource = from item in myCollection orderby item select item;

Vous devez implémenter l'interface IComparable pour MyDataClass:

public class MyDataClass : IComparable<MyDataClass> {
    public int CompareTo(Classified other) {
        return other.Value.CompareTo(this.Value); // DESC
        return this.Value.CompareTo(other.Value); // ASC
    }
}
2
Václav Dajbych

Cela fonctionne pour moi.

ListSortDirection sortDirection;
int selectedColumnIndex;
private void customerDataGrid_Sorting(object sender, DataGridSortingEventArgs e)
{
    selectedColumnIndex = e.Column.DisplayIndex;
    sortDirection = (e.Column.SortDirection == ListSortDirection.Ascending ? ListSortDirection.Descending: ListSortDirection.Ascending);
}

private void applySortDescriptions(ListSortDirection listSortDirection)
{
    //Clear current sort descriptions 
    customerDataGrid.Items.SortDescriptions.Clear();

    //Get property name to apply sort based on desired column 
    string propertyName = customerDataGrid.Columns[selectedColumnIndex].SortMemberPath;

    //Add the new sort description 
    customerDataGrid.Items.SortDescriptions.Add(new SortDescription(propertyName, listSortDirection));

    //apply sort 
    applySortDirection(listSortDirection);

    //refresh items to display sort 
    customerDataGrid.Items.Refresh();
}

private void applySortDirection(ListSortDirection listSortDirection)
{
    customerDataGrid.Columns[selectedColumnIndex].SortDirection = listSortDirection;
}
0
Pramod Pawar