【问题标题】:DataGrid SortDirection ignored忽略 DataGrid 排序方向
【发布时间】:2012-01-23 06:52:28
【问题描述】:

我想在启动时指定默认排序,但仍允许用户通过单击列标题进行排序。遗憾的是,SortDirection 属性在设置时被忽略 - 即我们得到正确的列标题箭头,但没有排序。

手动单击标题,对数据进行正确排序,因此不是排序本身。这是我正在使用的简化版本:

<DataGrid ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=CurrentView}" AutoGenerateColumns="False">
    <DataGrid.Columns>
        <DataGridTextColumn Header="Header 1" Binding="{Binding ApplicationName}"/>
        <DataGridTextColumn Header="Header 2" 
               Binding="{Binding TotalTime}" SortDirection="Descending"/>
    </DataGrid.Columns>
</DataGrid>

更新:我还尝试按照建议将 SortDescriptions 添加到 ICollectionView,但效果不佳。这可能与我正在向集合中动态添加新项目的事实有关吗? IE。启动时列表是空的并慢慢填充,也许排序描述只应用一次?

【问题讨论】:

    标签: c# wpf xaml datagrid sortdirection


    【解决方案1】:

    看看这个MSDN Blog

    从上面的链接:

    DataGridColumn.SortDirection 实际上并不对列进行排序。
    DataGridColumn.SortDirection 用于将 DataGridColumnHeader 中的可视箭头排列为向上、向下或不显示。要实际对列进行排序,而不是单击 DataGridColumnHeader,您可以通过编程方式设置 DataGrid.Items.SortDescriptions。

    【讨论】:

    • datagrid.Items和我使用的实际ICollectionView都试过了,但结果都是一样的:否定:(
    • 转念一想:也许这与我在列表中动态添加新项目有关?
    • @Voo 你可能想看看这个MSDN Blog。基本上保存 SortDescription 并重新应用它来强制使用。
    • 感谢您的帮助 - 事实证明您的第一个想法是正确的,我只是混淆了属性和标题名称,并且 wpf 对不存在的属性进行排序没有问题叹息。很抱歉。
    • 没问题,我很高兴它有帮助。
    【解决方案2】:

    我没有任何个人经验,但我找到了this rather helpful article

    基本上您需要将SortDescription 添加到DataGrid 绑定到的CollectionViewSource。

    【讨论】:

    • 您创建一个 CVS 并向其中添加排序方向,而不是 ObservableCollection。 OC 使用 Move 方法对行进行排序。
    • @Xcalibur 我担心我的 wpf/xaml/whatever 术语有点有限,所以你能翻译一下吗?无论如何,我尝试将 SortDescriptions 添加到 datagrid.Items 和数据网格用作源的 ICollectionView 中,但没有成功。
    • 这里也是如此,所以这不会丢失:这可能与我动态地将新项目添加到列表中有关吗?
    • 抱歉,没问题。我只是指出您会将 SortDescription 添加到 CollectionViewSource,而不是 ObservableCollection。 Microsoft 在“对 DataGrid 中的项目进行排序”下对此进行了详细介绍:msdn.microsoft.com/en-us/library/ff407126.aspx
    • @Xcalibur37:感谢指正,我已经更新了答案。
    【解决方案3】:

    这篇文章很有帮助。我能够使用它找到一个简单的解决方案。这是我的解决方案的一个 sn-p。

    XAML

            <DataGrid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" 
                AutoGenerateColumns="False" ItemsSource="{Binding LogLister.Logs}"              
                IsReadOnly="True" >
    
                <DataGrid.Columns>                  
    
                    <DataGridTextColumn Binding="{Binding TimeStampLocal}" Header="Time" x:Name="ColTimeStamp" />
    
                    <DataGridTextColumn Binding="{Binding Text}" Header="Text"/>
                </DataGrid.Columns>
            </DataGrid>
    

    代码

        // Using a DependencyProperty as the backing store for ViewModel.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ViewModelProperty =
            DependencyProperty.Register("ViewModel", typeof(LogViewerViewModel), typeof(LogViewerControl),
               new UIPropertyMetadata(null,pf_viewModelChanged));
    
        private static void pf_viewModelChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
        {
            var control = (LogViewerControl)o;
    
            control.ColTimeStamp.SortDirection = ListSortDirection.Descending;
    
            var vm = e.NewValue as LogViewerViewModel;
    
            if (vm != null)
            {   
                ICollectionView collectionView = CollectionViewSource.GetDefaultView(vm.LogLister.Logs);
                collectionView.SortDescriptions.Add(new SortDescription("TimeStampLocal", ListSortDirection.Descending));
            }
        }
    

    【讨论】:

      【解决方案4】:

      它的缺点是没有快速、简单的方法来做到这一点。我编写了自己的自定义排序器,它使用 ObservableCollections 上的 Move 方法。我重写了“DataGridSorting”事件并调用我自己的方法来促进这一点。我不打算在这里发布代码,因为我认为这对你的问题来说太过分了。

      我会说通过使用 CollectionViewSource 和 SortDescription(最初发布的 competent_tech)坚持我的上述评论。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-06-26
        • 1970-01-01
        • 2018-09-21
        • 1970-01-01
        • 2016-12-11
        • 2011-10-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多