【问题标题】:wpf set sorting programmatically, so that the header is toggled as sortedwpf 以编程方式设置排序,以便将标题切换为已排序
【发布时间】: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();

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

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

【问题讨论】:

    标签: c# wpf sorting datagrid sortdirection


    【解决方案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;
                        }
                    }
                }
            }
        }
    

    【讨论】:

      猜你喜欢
      • 2012-12-01
      • 1970-01-01
      • 2015-04-04
      • 1970-01-01
      • 1970-01-01
      • 2016-09-30
      • 2013-11-23
      • 2013-06-02
      • 1970-01-01
      相关资源
      最近更新 更多