wpf 以编程方式设置排序,以便将标题切换为已排序

Posted

技术标签:

【中文标题】wpf 以编程方式设置排序,以便将标题切换为已排序【英文标题】:wpf set sorting programmatically, so that the header is toggled as sorted 【发布时间】:2011-03-21 14:45:16 【问题描述】:

我对 wpf 工具包 DataGrid 有疑问。

我有一个包含三列的ItemsSource

名字

姓氏

地址

在 C# 代码隐藏中,我设置了排序方向和要排序的列,如下所示:

ICollectionView view = CollectionViewSource.GetDefaultView(dataGrid1.ItemsSource);
view.SortDescriptions.Clear();
view.SortDescriptions.Add(new SortDescription("LastName", ListSortDirection.Ascending));
view.Refresh();

实际排序没有问题,但标题视觉样式有问题。如果用户通过单击标题对列进行排序,则视觉样式会发生变化,但视觉样式并不表示列排序描述是通过编程设置的。

为什么会这样,如何切换标题以使其显示为已排序?

【问题讨论】:

【参考方案1】:

我之前没有尝试过,但我认为您可以设置列的 SortDirection 属性。

            int columnIndex = 0;
            this.dataGrid1.ColumnFromDisplayIndex(columnIndex).SortDirection = 
                ListSortDirection.Descending;

【讨论】:

很遗憾我收到此错误:给定的 DisplayIndex 超出范围。【参考方案2】:

下面的示例将让您使用组合框对数据网格进行排序,以及直接单击数据网格。

XAML:

<Window x:Class="DataGridDemo.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:Controls="clr-namespace:Microsoft.Windows.Controls;assembly=WPFToolkit"
    xmlns:System="clr-namespace:System;assembly=mscorlib"
    xmlns:ComponentModel="clr-namespace:System.ComponentModel;assembly=System"
    Height="300" Width="300">

    <Window.Resources>
        <ObjectDataProvider MethodName="GetValues" 
            ObjectType="x:Type System:Enum" 
            x:Key="SortDirections">
            <ObjectDataProvider.MethodParameters>
                <x:Type TypeName="ComponentModel:ListSortDirection" />
            </ObjectDataProvider.MethodParameters>
        </ObjectDataProvider>
    </Window.Resources>

    <StackPanel>
        <ComboBox 
            Name="_columnsComboBox"
            ItemsSource="Binding Path=Columns, ElementName=_dataGrid" 
            DisplayMemberPath="Header"
            SelectionChanged="OnSort" />
        <ComboBox 
            Name="_sortDirectionsComboBox"
            ItemsSource="Binding Source=StaticResource SortDirections" 
            SelectionChanged="OnSort" />
        <Controls:DataGrid 
            Name="_dataGrid"
            ItemsSource="Binding Path=PeopleData" />

    </StackPanel>
</Window>

后面的代码:

using System;
using System.ComponentModel;
using System.Data;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using Microsoft.Windows.Controls;

namespace DataGridDemo

    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    
        public Window1()
        
            InitializeComponent();

            PeopleData = new DataTable();
            PeopleData.Columns.Add(new DataColumn("Name", typeof(string)));
            PeopleData.Columns.Add(new DataColumn("Age", typeof(int)));

            var row = PeopleData.NewRow();
            row["Name"] = "Sara";
            row["Age"] = 25;
            PeopleData.Rows.Add(row);

            row = PeopleData.NewRow();
            row["Name"] = "Bob";
            row["Age"] = 37;
            PeopleData.Rows.Add(row);

            row = PeopleData.NewRow();
            row["Name"] = "Joe";
            row["Age"] = 10;
            PeopleData.Rows.Add(row);

            DataContext = this;
        

        public DataTable PeopleData  get; private set;

        private void OnSort(object sender, SelectionChangedEventArgs e)
        
            if (_sortDirectionsComboBox.SelectedIndex == -1 || _columnsComboBox.SelectedIndex == -1)
            
                return;
            

            foreach (DataGridColumn dataColumn in _dataGrid.Columns)
            
                dataColumn.SortDirection = null;
            

            ListSortDirection sortDescription = (ListSortDirection)(_sortDirectionsComboBox.SelectedItem);
            DataGridColumn selectedDataColumn = _columnsComboBox.SelectedItem as DataGridColumn;
            selectedDataColumn.SortDirection = sortDescription;

            ICollectionView view = CollectionViewSource.GetDefaultView(_dataGrid.ItemsSource);
            view.SortDescriptions.Clear();
            view.SortDescriptions.Add(new SortDescription(selectedDataColumn.Header as string, sortDescription));
            view.Refresh();
        
    

【讨论】:

遗憾的是,它并不能帮助我在加载的窗口上对列表进行排序,这是我的问题 只需将OnSort中的代码,做成一个以column进行排序和排序方向的方法。【参考方案3】:

如果您想将有效排序同步到列上的视觉样式,这应该会有所帮助:

  ( (INotifyCollectionChanged)Items.SortDescriptions ).CollectionChanged += new NotifyCollectionChangedEventHandler( OnItemsSortDescriptionsChanged );


 private void OnItemsSortDescriptionsChanged( object sender, NotifyCollectionChangedEventArgs e )
    
        //Synchronize effective sorting in the grid and Visual style on columns
        if ( Items != null )
        
            foreach ( DataGridColumn column in Columns )
            
                column.SortDirection = null;

                foreach ( SortDescription sd in Items.SortDescriptions )
                
                    if ( column.SortMemberPath == sd.PropertyName )
                    
                        column.SortDirection = sd.Direction;
                        break;
                    
                
            
        
    

【讨论】:

以上是关于wpf 以编程方式设置排序,以便将标题切换为已排序的主要内容,如果未能解决你的问题,请参考以下文章

如何以编程方式重新排序primefaces数据表中的列

您如何以编程方式将焦点设置到已具有焦点的 WPF ListBox 中的 SelectedItem?

以编程方式设置网格排序

无法以编程方式为 DataTable 设置初始排序顺序

如何将非通用排序列表保存到文件中,以便可以从文件中加载该排序列表?

如何以编程方式根据排序标准对单元格重新排序 SWIFT 4