2009-10-26 9 views
24

Tengo un DataGrid en la aplicación WPF con varias columnas, incluida una columna Nombre. Si los usuarios cambian a una vista particular, quiero que los datos se ordenen previamente por Nombre (y me gustaría que apareciera una flecha de clasificación en el encabezado Nombre, como si el usuario hubiera hecho clic en ese encabezado). Sin embargo, no puedo encontrar las propiedades esperadas para que esto suceda. Yo estaba buscando algo así como SortColumn, SortColumnIndex, SortDirection, etc.Preordenamiento de un DataGrid en WPF

¿Es posible especificar la columna de la clasificación por defecto y la dirección en el marcado (XAML), o es que no soportado por el WPF Toolkit DataGrid?

+0

Desde WPF no viene con una cuadrícula de datos incorporada, podemos suponer que te refieres a la cuadrícula de datos que viene con WPF Toolkit (http://www.codeplex.com/wpf) ??? –

+0

Sí, puse la etiqueta wpftoolkit, pero supongo que no lo mencioné en mi pregunta. Añadiré eso. – devuxer

Respuesta

38

Suponiendo que está hablando del control WPF Toolkit DataGrid, solo necesita establecer the CanUserSortColumns property en true y luego establecer the SortMemberPath property de cada DataGridColumn en DataGrid.

En cuanto a ordenar la colección inicialmente, debe usar un CollectionViewSource y establecer el orden sobre eso y luego asignar eso como el ItemsSource de su DataGrid. Si usted está haciendo esto en XAML entonces sería tan fácil como:

<Window.Resources> 
    <CollectionViewSource x:Key="MyItemsViewSource" Source="{Binding MyItems}"> 
     <CollectionViewSource.SortDescriptions> 
      <scm:SortDescription PropertyName="MyPropertyName"/> 
     </CollectionViewSource.SortDescriptions> 
    </CollectionViewSource> 
</Window.Resources> 

<DataGrid ItemsSource="{StaticResource MyItemsViewSource}"> 

</DataGrid> 

NOTA: mapas el "SMC" namespace prefix a System.ComponentModel donde vive la clase SortDescription.

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

EDIT: Creo suficientes personas recibieron ayuda de este post, que este comentario upvoted debe ser incluido en esta respuesta:

que tenía que usar esto para conseguir que funcione:

<DataGrid ItemsSource="{Binding Source={StaticResource MyItemsViewSource}}"> 
+0

@Drew, gracias, pero 'SortMemberPath' simplemente especifica qué campo de la fuente de datos va con qué columna en DataGrid. Necesito establecer la columna de clasificación * actual * (y dirección). Por ejemplo, este DataGrid actualmente está ordenado ascendentemente por Nombre. – devuxer

+1

Bueno, cómo resuelves tu "clic en la columna del encabezado y el problema de clasificación". Accidentalmente dejé de ordenar la cuadrícula, añadiré mi respuesta ahora. –

+5

Sí :) Eso está mucho más cerca de lo que estaba buscando, gracias. El único problema es que la flecha de clasificación no aparece en el encabezado de la columna por la que está ordenada la tabla. Puedo vivir con eso, pero una flecha aclararía un poco más al usuario cuál es la columna de clasificación. Solo una nota para cualquiera que intente hacer esto, necesita una referencia a 'WindowsBase' para usar' System.ComponentModel'. Una vez que haya agregado la referencia, necesita esto: 'xmlns: scm =" clr-namespace: System.ComponentModel; assembly = WindowsBase "'. – devuxer

2

Cuando vea ItemsSource doesn't support CollectionViewSource excepción, puede ordenar colección por LINQ antes de hacer referencia a una cuadrícula de datos:

ObservableCollection<MyDataClass> myCollection = new ObservableCollection<MyDataClass>(); 
dataGrid.ItemsSource = from item in myCollection orderby item select item; 

deberá implementar IComparable interfaz para MyDataClass:

public class MyDataClass : IComparable<MyDataClass> { 
    public int CompareTo(Classified other) { 
     return other.Value.CompareTo(this.Value); // DESC 
     return this.Value.CompareTo(other.Value); // ASC 
    } 
} 
+0

Esto realmente funcionó para mí ya que estaba tratando de pedir una lista de encuadernación con Lambda. ¡Esto funcionó, Lambda no lo hizo! – DerpyNerd

4

Cuando vea ItemsSource no admite excepción CollectionViewSource entonces se puede establecer el DataContext de la cuadrícula de datos como 'MyItemsViewSource' y ItemsSource como {Binding} como esto :

<DataGrid DataContext="{StaticResource MyItemsViewSource}" ItemsSource="{Binding}"> 
</DataGrid> 
+1

¡Sigo volviendo a este post (tercera vez este año) porque me olvido de hacer esta parte muy importante del rompecabezas! Gracias por publicarlo. –

19

sé que esto es una entrada antigua pero además de la respuesta de Drew Marsh y en respuesta a la edición de DanM con las flechas de la cabecera de la columna no aparece ... es necesario agregar la propiedad SortDirection a th e DataGridColumn:

<DataGridTextColumn Header="Name" Binding="{Binding Name}" SortDirection="Ascending" /> 

He publicado una pregunta acerca de esto y encontró la respuesta a los pocos días:

ColumnHeader arrows not reflected when sorting a DataGrid in XAML

+0

Esto significa que la propiedad 'SortDirection' debe coincidir manualmente con las columnas en' SortDescription' - ¿hay alguna forma para que DataGrid detecte la ordenación de CollectionViewSource y muestre los indicadores automáticamente? – Dai

0

Esto funciona para mí.

ListSortDirection sortDirection; 
int selectedColumnIndex; 
private void customerDataGrid_Sorting(object sender, DataGridSortingEventArgs e) 
{ 
    selectedColumnIndex = e.Column.DisplayIndex; 
    sortDirection = (e.Column.SortDirection == ListSortDirection.Ascending ? ListSortDirection.Descending: ListSortDirection.Ascending); 
} 

private void applySortDescriptions(ListSortDirection listSortDirection) 
{ 
    //Clear current sort descriptions 
    customerDataGrid.Items.SortDescriptions.Clear(); 

    //Get property name to apply sort based on desired column 
    string propertyName = customerDataGrid.Columns[selectedColumnIndex].SortMemberPath; 

    //Add the new sort description 
    customerDataGrid.Items.SortDescriptions.Add(new SortDescription(propertyName, listSortDirection)); 

    //apply sort 
    applySortDirection(listSortDirection); 

    //refresh items to display sort 
    customerDataGrid.Items.Refresh(); 
} 

private void applySortDirection(ListSortDirection listSortDirection) 
{ 
    customerDataGrid.Columns[selectedColumnIndex].SortDirection = listSortDirection; 
}