2011-06-24 80 views
14

如何设置我的WPF数据网格对多列进行排序,类似于有两个可排序列,单击第一列的标题进行主排序,然后单击SHIFT的标题第二列为第二类。我希望在用户单击第一列的标题时自动发生多列排序,而不必按SHIFT单击第二列标题。有没有办法在xaml中完全做到这一点?如果不是,我怎么能在后面的代码中做到这一点?目前使用VB.Net,但如果您有一个C#代码片段,则可以接受。谢谢!对WPF数据网格中的多列进行排序

回答

17

您可以通过添加System.ComponentModel命名空间是这样做的:

xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase" 

那么CollectionViewSource XAML中添加新的SortDescriptions这样的:

<CollectionViewSource … > 
      <CollectionViewSource.SortDescriptions> 
       <scm:SortDescription PropertyName="Column1"/> 
       <scm:SortDescription PropertyName="Column2"/> 
      </CollectionViewSource.SortDescriptions> 
</CollectionViewSource> 

这将在column1,column2上对datagrid排序。

编辑:

也这样使用C#代码背后,是很容易的:

private void btnSort_Click(object sender, RoutedEventArgs e) 
    { 
     System.Windows.Data.CollectionViewSource myViewSource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("The_ViewSource_Name"))); 
     myViewSource.SortDescriptions.Add(new SortDescription("Column1", ListSortDirection.Ascending)); 
     myViewSource.SortDescriptions.Add(new SortDescription("Column2", ListSortDirection.Ascending)); 
    } 

EDIT2:

解决办法,可向赶上列标题点击鼠标左键事件,并防止网格排序在该列上,如下所示:

  • 禁用网格属性命名 CanUserSortColumns

enter image description here

  • 该代码添加到网格 的PreviewMouseLeftButtonUp事件:

    private void myDataGrid_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e) 
    { 
        DependencyObject dep = (DependencyObject)e.OriginalSource; 
        while ((dep != null) && 
        !(dep is DataGridCell) && 
        !(dep is DataGridColumnHeader)) 
        { 
         dep = VisualTreeHelper.GetParent(dep); 
        } 
    
        if (dep == null) 
         return; 
    
        if (dep is DataGridColumnHeader) 
        { 
         DataGridColumnHeader columnHeader = dep as DataGridColumnHeader; 
         // check if this is the wanted column 
         if (columnHeader.Column.Header.ToString() == "The_Wanted_Column_Title") 
         { 
          System.Windows.Data.CollectionViewSource myViewSource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("myViewSource"))); 
          myViewSource.SortDescriptions.Clear(); 
          myViewSource.SortDescriptions.Add(new SortDescription("Column1", ListSortDirection.Ascending)); 
          myViewSource.SortDescriptions.Add(new SortDescription("Column2", ListSortDirection.Ascending)); 
         } 
         else 
         { 
          //usort the grid on clicking on any other columns, or maybe do another sort combination 
          System.Windows.Data.CollectionViewSource myViewSource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("myViewSource"))); 
          myViewSource.SortDescriptions.Clear(); 
         } 
    
        } 
    } 
    

您可以修改和扩展此代码以实现您的要求。

+0

OP询问如何让用户通过点击多列标题来排序网格,而不是如何以编程方式对底层集合进行一次排序。 –

+0

@djacobson我认为我很好的阅读了这个问题,他写道:“有没有办法在xaml中完全做到这一点?” –

+0

@djacobson除了单击多个列标题外,网格会自动在选定的列上排序。 –

11

我希望这会帮助别人。我的解决方案保留了默认的排序功能,并允许在多列上排序。

在你的代码放在一个排序的事件对你的DataGrid

<DataGrid x:Name="dataGridName" Sorting="dataGridName_Sorting"> 

现在落后

private void dataGridName_Sorting(object sender, DataGridSortingEventArgs e) 
{ 
    var dgSender = (DataGrid) sender; 
    var cView = CollectionViewSource.GetDefaultView(dgSender.ItemsSource); 

    //Alternate between ascending/descending if the same column is clicked 
    ListSortDirection direction = ListSortDirection.Ascending; 
    if (cView.SortDescriptions.FirstOrDefault().PropertyName == e.Column.SortMemberPath) 
     direction = cView.SortDescriptions.FirstOrDefault().Direction == ListSortDirection.Descending ? ListSortDirection.Ascending : ListSortDirection.Descending; 

    cView.SortDescriptions.Clear(); 
    AddSortColumn((DataGrid)sender, e.Column.SortMemberPath, direction); 
    //To this point the default sort functionality is implemented 

    //Now check the wanted columns and add multiple sort 
    if (e.Column.SortMemberPath == "WantedColumn") 
    { 
     AddSortColumn((DataGrid)sender, "SecondColumn", direction); 
    } 
    e.Handled = true; 
} 

private void AddSortColumn(DataGrid sender, string sortColumn, ListSortDirection direction) 
{ 
    var cView = CollectionViewSource.GetDefaultView(sender.ItemsSource); 
    cView.SortDescriptions.Add(new SortDescription(sortColumn, direction)); 
    //Add the sort arrow on the DataGridColumn 
    foreach (var col in sender.Columns.Where(x => x.SortMemberPath == sortColumn)) 
    { 
     col.SortDirection = direction; 
    } 
} 

上的DataGridColumn的sortDirection允许显示网格上的箭头。

相关问题