WPF DataGrid 默认排序不起作用 [英] WPF DataGrid default sort not working

查看:31
本文介绍了WPF DataGrid 默认排序不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 DataGrid,其中包含 XAML 列:

I have a DataGrid, with columns XAML as such:

<DataGridTextColumn Header="Time" Binding="{Binding Date, StringFormat='yyyy-MM-dd  HH:mm:ss'}" SortMemberPath="Date" SortDirection="Descending" Width="130" CanUserResize="True" />
<DataGridTextColumn Header="Level" Binding="{Binding Level}" Width="60" CanUserResize="True" />
<DataGridTextColumn Header="Source" Binding="{Binding Logger}" Width="150" CanUserResize="True" />
<DataGridTextColumn Header="Message" Binding="{Binding Message}" Width="*" CanUserResize="True" />

我将它绑定到一个 ObservableCollection,其中 EalsLogEvent.Date 的类型是 DateTime:

I bind this to an ObservableCollection<EalsLogEvent>, where EalsLogEvent.Date is typed DateTime:

public ObservableCollection<EalsLogEvent> LogEvents 
{
    get
    {
        return _logEvents;
    }
}

网格视图模型使用计时器来刷新自身,网格看起来一切正常,除了在应用程序启动时首次加载时.然后,Time 列似乎按降序排序,但按升序排序.

The grid viewmodel uses a timer to refresh itself, and everything seems fine with the grid, except when it first loads, on app startup. Then, the Time column appears to be sorted descending, but is sorted ascending.

要正确排序,我必须单击列标题两次;第一次将顺序更改为升序,现在与列的内容匹配.第二次点击列标题将其排序顺序改回降序,这次它正确地对列内容进行排序,即降序.

To get the sort right, I must click the column header twice; the first time changes the order to ascending, which now matches the content of the column. The second click on the column header changes its sort order back to descending, and this time it sorts the column contents properly, i.e. descending.

如果我在 _logEvents 刷新时使用 LINQ 对集合进行排序,我会丢失用户通过单击列标题为该列设置的任何顺序.如果我必须让视图告诉模型 LINQ 排序应该使用哪个顺序,那么有些东西会很糟糕.

If I use LINQ to order the collection when _logEvents gets refreshed, I lose whichever order the user had set for the column by clicking its header. If I have to have the view tell the model which order the LINQ sort should use, something smells bad.

推荐答案

您可以在 XAML 中使用 CollectionViewSource 来定义默认排序.

You could use a CollectionViewSource in your XAML to define the default sorting.

假设我们有一个视图模型:

Assuming we have a view model:

public class ViewModel : INotifyPropertyChanged
{
    public ObservableCollection<Item> Items { get; private set; }
}

我们可以为 Items 集合创建一个自定义的 CollectionView:

We can create a custom CollectionView for the Items collection:

<Window xmlns:l="clr-namespace:YourNamespace"
        xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase">
    <Window.DataContext>
        <l:ViewModel/>
    </Window.DataContext>
    <Window.Resources>
        <CollectionViewSource Source="{Binding Items}" x:Key="GridItems">
            <CollectionViewSource.SortDescriptions>
                <scm:SortDescription PropertyName="Date" Direction="Descending"/>
            </CollectionViewSource.SortDescriptions>
        </CollectionViewSource>
    </Window.Resources>
    <DataGrid ItemsSource="{Binding Source={StaticResource GridItems}}" AutoGenerateColumns="False">
        <DataGrid.Columns>                    
            <DataGridTextColumn Header="Time" Binding="{Binding Date, StringFormat='yyyy-MM-dd  HH:mm:ss'}" Width="130" CanUserResize="True" />
            <DataGridTextColumn Header="Level" Binding="{Binding Level}" Width="60" CanUserResize="True" />
            <DataGridTextColumn Header="Source" Binding="{Binding Logger}" Width="150" CanUserResize="True" />
            <DataGridTextColumn Header="Message" Binding="{Binding Message}" Width="*" CanUserResize="True" />
        </DataGrid.Columns>
    </DataGrid>
</Window>

使用这种方法,您的底层源集合(在此示例中为Items)不会受到影响,排序仅发生在视图中.

With this approach, your underlying source collection (Items in this example) will not be affected, the sorting occurs only in the view.

正如您在 MSDN:

您可以将集合视图视为绑定之上的层源集合,允许您导航和显示基于排序、过滤和分组查询的集合,所有这些都没有必须操作底层源集合本身.如果源集合实现了 INotifyCollectionChanged 接口,CollectionChanged 事件引发的更改将传播到意见.

You can think of a collection view as the layer on top of the binding source collection that allows you to navigate and display the collection based on sort, filter, and group queries, all without having to manipulate the underlying source collection itself. If the source collection implements the INotifyCollectionChanged interface, the changes raised by the CollectionChanged event are propagated to the views.

您还应该注意以下几点:

You should also note the following:

所有集合都有一个默认的 CollectionView.WPF 总是绑定到查看而不是集合.如果你直接绑定到一个集合,WPF 实际上绑定到该集合的默认视图.

All collections have a default CollectionView. WPF always binds to a view rather than a collection. If you bind directly to a collection, WPF actually binds to the default view for that collection.

因此,使用 CollectionViewSource,您只需为您的集合定义自定义视图.

So, using the CollectionViewSource, you're just defining a custom view for your collection.

这篇关于WPF DataGrid 默认排序不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆