26

我有一个DataGrid包含多个列的 WPF 应用程序,包括一个名称列。如果用户切换到特定视图,我希望数据按名称预先排序(并且我希望排序箭头出现在名称标题中,就像用户单击该标题一样)。但是,我找不到实现这一点的预期属性。我正在寻找类似SortColumn, SortColumnIndex,SortDirection等的东西。

是否可以在标记 (XAML) 中指定默认的排序列和方向,或者 WPF 工具包不支持DataGrid

4

5 回答 5

47

假设您正在谈论 WPF Toolkit DataGrid 控件,您只需将CanUserSortColumns 属性设置为 true,然后设置DataGrid 中每个 DataGridColumn的 SortMemberPath 属性。

至于最初对集合进行排序,您必须使用 CollectionViewSource 并在其上设置排序,然后将其分配为 DataGrid 的 ItemsSource。如果您在 XAML 中执行此操作,那么它会很简单:

<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>

注意: “scm”命名空间前缀映射到 SortDescription 类所在的 System.ComponentModel。

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

编辑:我认为有足够多的人从这篇文章中得到帮助,这个被赞成的评论应该包含在这个答案中:

我不得不用它来让它工作:

<DataGrid ItemsSource="{Binding Source={StaticResource MyItemsViewSource}}">
于 2009-10-26T20:37:37.920 回答
18

我知道这是一篇旧帖子,但除了 Drew Marsh 的回答和响应 DanM 的问题,列标题的箭头没有出现......您需要将 SortDirection 属性添加到 DataGridColumn:

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

我发布了一个关于此的问题,并在几天后找到了答案:

在 XAML 中对 DataGrid 进行排序时未反映 ColumnHeader 箭头

于 2011-07-29T14:55:03.213 回答
5

当您看到 ItemsSource 不支持 CollectionViewSource 异常时,您可以将 DataGrid 的 DataContext 设置为“MyItemsViewSource”,将 ItemsSource 设置为 {Binding},如下所示:

<DataGrid DataContext="{StaticResource MyItemsViewSource}" ItemsSource="{Binding}">
</DataGrid>
于 2009-12-18T11:43:20.230 回答
3

当您看到ItemsSource doesn't support CollectionViewSource异常时,您可以在将集合引用到 DataGrid 之前按 Linq 对集合进行排序:

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

您必须实现IComparable接口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
    }
}
于 2009-11-11T11:07:57.570 回答
0

这对我有用。

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;
}
于 2017-05-29T08:50:20.747 回答