2011-12-07 34 views
5

Necesito tener un tipo de evento Sorted para DataGrid en una aplicación WPF pero no puedo encontrar la manera de obtenerlo.Cómo puedo recibir una notificación si una columna DataGrid está ordenada (y no ordenada)

Aquí es lo que he intentado:

El DataGrid proporciona un evento Sorting, pero no puedo usarlo, ya que es despedido antes de realizar la clasificación. El EventArgs me da la columna que está ordenada pero no de la manera en que está ordenada, y si obtengo la dirección de clasificación, se establece en el valor anterior. Por supuesto, podría adivinar de qué se trata, ya que sé que cambia de ninguno a ascendente y finalmente a descendente, pero eso no sería una solución ya que fallaría si cambia el comportamiento del control.

Segundo intento:

El DataGrid tiene una vista predeterminada que proporciona acceso a una SortDescriptionCollection. Esta colección contiene todas las propiedades de clasificación, pero no veo ninguna posibilidad de permitirme informar sobre los cambios.

Tengo que decir que estoy buscando una solución lo más limpia posible, ya que se utilizará en un proyecto grande en el que no puedo usar soluciones que podrían fallar si el entorno cambia.

¿Alguien sabe por experiencia (o documentación?) Cómo podría resolver este problema?

Editar: para hacer más claro lo que quiero lograr: Necesito estar informado, que DataGrid columna se ordena en qué dirección cuando un usuario ordenar una columna. No es necesario que esta información venga después de la clasificación, solo tiene que ser correcta;)

Respuesta

14

implementé la clasifican para el evento DataGrid mismo anulando la cuadrícula de datos de la siguiente manera:

public class ValueEventArgs<T> : EventArgs 
{ 
    public ValueEventArgs(T value) 
    { 
     Value = value; 
    } 

    public T Value { get; set; } 

} 

public class DataGridExt : DataGrid 
{ 
    public event EventHandler<ValueEventArgs<DataGridColumn>> Sorted; 

    protected override void OnSorting(DataGridSortingEventArgs eventArgs) 
    { 
     base.OnSorting(eventArgs); 

     if (Sorted == null) return; 
     var column = eventArgs.Column; 
     Sorted(this, new ValueEventArgs<DataGridColumn>(column)); 
    } 
} 

Para utilizar entonces todo lo que tiene que hacer es esto:

private void Initialize() 
    { 
      myGrid.Sorted += OnSorted; 
    } 
    private void OnSorted(object sender, ValueEventArgs<DataGridColumn> valueEventArgs) 
    { 
    // Persist Sort... 
    } 
0

Después de muchas horas de intentar y leer, pude resolver el problema yo mismo. No estoy absolutamente satisfecho con la solución pero funciona para mí.

Como estoy dejando que generan las columnas DataGrid por código que podía usar el DependencyPropertySortDirection de cada columna y añadir un método que será llamado cuando cambia la propiedad. Esto se hace de esta manera:

DataGridBoundColumn column = GetTheColumnIWantToObserve(); 
if (column != null) 
{ 
    // add value changed notification to be informed about changes 
    var desc = DependencyPropertyDescriptor.FromProperty(DataGridColumn.SortDirectionProperty, typeof(DataGridColumn)); 
    desc.AddValueChanged(column, ColumnSortDirectionChanged); 
} 

En el método ColumnSortDirectionChanged ahora puedo trabajar con los cambios.

private void ColumnSortDirectionChanged(object sender, EventArgs eventArgs) 
{ 
    var column = sender as DataGridColumn; 
    if (column != null) 
    { 
     var newSortDirection = column.SortDirection; 
     // Yay, I got it!! 
    } 
} 

Si yo no generar las columnas a mí mismo que tendría que utilizar un evento DataGrid (por ejemplo Loaded o AutoGeneratedColumns) y añadir la notificación a todas las columnas existentes.

+0

Eso es de hecho una tal solución dios. SortDirection cambia el momento en que hace clic en Ordenar. La clasificación real puede llevar mucho más tiempo, no tiene garantía de que su solución se active inmediatamente después de que Sort haya terminado. – Houman

+0

¿Tienes otra idea? Para mí, esto está bien ya que uso la información para almacenarla en un archivo de configuración para el próximo inicio de la aplicación. El tiempo no importa mucho. A pesar de todo, mientras escribía, no estoy completamente satisfecho con esto, por lo que estaría feliz con las sugerencias. – MatthiasG

1

pude No entiendo la solución de Stephen Lautier para trabajar en VB.Net, pero encontré otra solución que puede funcionar.

Siempre que se produce una operación de clasificación, los siguientes eventos en el orden indicado:

  1. Ordenando
  2. UnloadingRow (Para todas las filas de la cuadrícula de datos)
  3. LoadingRow (Para todas las filas de la cuadrícula de datos)
  4. LayoutUpdated

Esto se puede utilizar de la siguiente manera:

variables

Private _updateSorted As Boolean 
Private _tempSender As Object 
Private _rowsLoaded As List(Of DataGridRowEventArgs) 
_rowsLoaded = New List(Of DataGridRowEventArgs) 

Clasificación

Private Sub myDataGrid_Sorting(sender As Object, e As DataGridSortingEventArgs) Handles myDataGrid.Sorting 
    _updateSorted = True 
    _rowsLoaded.Clear() 
    _tempSender = Nothing 
End Sub 

UnloadingRow/Carga de fila Eventos

'Save pre-sorting state here, if desired' 
'Perform operation on pre-sorting rows here, if desired' 
Private Sub myDataGrid_UnloadingRow(sender As Object, e As DataGridRowEventArgs) Handles myDataGrid.UnloadingRow 

End Sub 

'Save post-sorting state here.' 
'Perform operation on post-sorting rows here' 
'In this example, the operation is dependent on the DataGrid updating its layout first so I included items relevant to handling that' 
Private Sub myDataGrid_LoadingRow(sender As Object, e As DataGridRowEventArgs) Handles myDataGrid.LoadingRow 
    Dim myDataGridCell As DataGridCell = GetCellByRowColumnIndex(myDataGrid, e.Row.GetIndex, colIndex) 
    'Or whatever layout-dependent object you are using, perhaps utilizing e As DataGridRowEventArgs' 

     If Not IsNothing(myDataGridCell) Then 
      '~~ Perform operations here ~~' 
     Else 
      If _updateSorted Then 
       'Update has occurred but the updated DataGrid is not yet available' 
       'Save variables to use once the DataGrid is updated' 
       _rowsLoaded.Add(e) 
       _tempSender = sender 
      End If 
     End If 
End Sub 

La youtUpdated

Private Sub myDataGrid_LayoutUpdated(sender As Object, e As EventArgs) Handles myDataGrid.LayoutUpdated 
    If _updateSorted Then 
     Dim rowsLoaded As New List(Of DataGridRowEventArgs) 
     For Each eRow As DataGridRowEventArgs In _rowsLoaded 
      rowsLoaded.Add(eRow) 
     Next 

     For Each eRow As DataGridRowEventArgs In rowsLoaded 
      'Now perform the action to the sorted DataGridRows in the order they were added' 
      myDataGrid_LoadingRow(_tempSender, eRow) 
     Next 
     _updateSorted = False 
    End If 
End Sub 
+0

¿Dónde encontraste la información sobre el orden de los eventos? Estoy intentando usar el evento LayoutUpdated (cuando está precedido por un evento de clasificación) como mi disparador para desplazar la cuadrícula de datos a la parte superior. Aunque parece que todas las llamadas relevantes se están ejecutando según lo previsto, el comportamiento final no está sucediendo; mi cuadrícula de datos no se desplaza hacia la parte superior después de un ordenamiento. En cambio, mantiene la fila seleccionada a la vista. –

+0

¡Desearía saber de una fuente de referencia, pero no lo sé! En cambio, hice algo de experimentación. Básicamente, en estos escenarios trato de crear varios eventos que son lo que creo que quiero o que son relevantes. Luego hago que el oyente del evento envíe un mensaje informativo a la consola. De esta forma, informar no interfiere con el uso de la GUI, y los mensajes me informan que un evento en particular se activó. A través del método de prueba y error, puedo obtener una imagen del orden de encendido, la frecuencia, los patrones, o qué tan consistente puede ser con diferentes configuraciones y acciones. – PellucidWombat

+0

Parece que su situación depende de ciertas opciones que haya configurado en la cuadrícula de datos o el código relacionado, como desplazarse automáticamente a la selección. Entonces, si eso no es lo que quieres, analizaré cómo se mantiene o restablece tu selección después de iniciar una clasificación. Esto puede darte una pista sobre dónde/cómo cambiar el comportamiento. – PellucidWombat

Cuestiones relacionadas