2011-06-24 18 views
14

¿Cómo puedo configurar mi cuadrícula de datos WPF para ordenar en varias columnas similares a tener dos columnas ordenables, hacer clic en el encabezado de la primera columna para una clasificación principal y luego hacer clic en el encabezado de MAYÚSCULAS la segunda columna para un tipo secundario. Me gustaría que la ordenación de columna múltiple suceda automáticamente cuando el usuario hace clic en el encabezado de la primera columna sin tener que hacer MAYÚSCULAS en el encabezado de la segunda columna. ¿Hay alguna manera de hacer esto completamente en el xaml? Si no, ¿cómo puedo hacer esto en el código? Actualmente, está utilizando VB.Net, pero un fragmento de C# es aceptable si tiene uno. ¡Gracias!Ordenar en varias columnas en la cuadrícula de datos WPF

Respuesta

17

Usted puede hacer esto mediante la adición de System.ComponentModel espacio de nombres de la siguiente manera:

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

entonces dentro de la CollectionViewSource XAML añadir nuevos SortDescriptions así:

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

esta voluntad ordenar datagrid en column1, column2.

Editar:

también hacer esto utilizando el código C# detrás es bastante fácil:

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:

Solución alternativa se puede hacer para coger el encabezado de la columna izquierda, haga clic del ratón evento y evitar que la cuadrícula ordene en esa columna como esta:

  • Desactivar propiedad rejilla nombrados CanUserSortColumns

enter image description here

  • Añadir este código al evento rejilla 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(); 
         } 
    
        } 
    } 
    

Puede modificar y expandir este código para cumplir sus requisitos.

+0

El OP preguntó cómo permitir que un usuario ordene una grilla haciendo clic en múltiples encabezados de columna, no cómo ordenar programáticamente la colección subyacente una vez. –

+0

@djacobson Creo que leí bien la Pregunta, él escribió: "¿Hay alguna manera de hacer esto completamente en el xaml?" –

+0

@djacobson además de hacer clic en varios encabezados de columna, la cuadrícula ordena automáticamente en las columnas seleccionadas. –

11

Espero que esto ayude a los demás. Mi solución mantiene la funcionalidad de clasificación predeterminada y permite ordenar en varias columnas.

Deja un evento de clasificación en su cuadrícula de datos

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

Y ahora en su código detrás

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; 
    } 
} 

El sortDirection en los DataGridColumn permiten que muestra la flecha en la parrilla.

Cuestiones relacionadas