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 以编程方式设置排序,以便将标题切换为已排序的主要内容,如果未能解决你的问题,请参考以下文章
您如何以编程方式将焦点设置到已具有焦点的 WPF ListBox 中的 SelectedItem?