2011-12-07 15 views
5

Ho bisogno di avere un tipo di evento Sorted per un DataGrid in un'applicazione WPF ma non riesco a trovare un modo per ottenerlo.Come posso essere avvisato se una colonna DataGrid è ordinata (e non ordinata)

Ecco cosa ho provato:

Il DataGrid fornisce un evento Sorting, ma non posso usarlo come viene generato prima l'ordinamento è fatto. Il EventArgs mi fornisce la colonna che è ordinata ma non il modo in cui è ordinata e se ottengo la direzione di ordinamento è impostata sul vecchio valore. Certo, potrei indovinare quale sarà, come so che passa da nessuno ad ascendere e infine a scendere, ma non sarebbe una soluzione in quanto fallirebbe se il comportamento del controllo dovesse cambiare.

secondo tentativo:

Il DataGrid ha una visualizzazione predefinita che fornisce l'accesso ad un SortDescriptionCollection. Questa raccolta contiene tutte le proprietà di smistamento, ma non vedo alcuna possibilità di informarmi sui cambiamenti.

devo dire che sto cercando una soluzione più pulita possibile in quanto verrà utilizzato in un grande progetto su cui non posso usare soluzioni che potrebbero fallire se cambia l'ambiente.

Qualcuno sa per esperienza (o la documentazione?) Come potrei risolvere questo problema?

Edit: Per rendere più chiaro ciò che voglio raggiungere: ho bisogno di essere informato che DataGrid colonna viene ordinata in quale direzione quando un utente sorta una colonna. Non è necessario che queste informazioni arrivino dopo lo smistamento stesso, ma deve essere corretto;)

risposta

14

ho implementato l'Ordinati per l'evento DataGrid me sovrascrivendo il DataGrid come segue:

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

Per poter utilizzare poi tutto quello che dovete fare è questo:

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

Dopo molte ore di tentativi e di lettura sono stato in grado di risolvere il problema da solo. Non sono assolutamente soddisfatto della soluzione, ma funziona per me.

come sto lasciando generare i DataGrid colonne di codice che ho potuto utilizzare la DependencyPropertySortDirection di ogni colonna e aggiungere un metodo che verrà chiamato quando viene modificata la proprietà. Questo viene fatto in questo modo:

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

Nel metodo ColumnSortDirectionChanged ora posso lavorare con i cambiamenti.

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

Se non vorrei generare le colonne me stesso che avrei dovuto usare un DataGrid evento (ad esempio Loaded o AutoGeneratedColumns) e aggiungere la notifica a tutte le colonne esistenti.

+0

Questa è davvero una soluzione del genere. SortDirection cambia nel momento in cui fai clic su Ordina. L'ordinamento effettivo potrebbe richiedere molto più tempo, non si ha alcuna garanzia che la soluzione venga avviata esattamente dopo che l'ordinamento è terminato. – Houman

+0

Quindi hai un'altra idea? Per me questo va bene poiché utilizzo le informazioni per memorizzarle in un file di configurazione per l'avvio successivo dell'applicazione. I tempi non contano molto. Nondimeno, come ho scritto, non sono completamente soddisfatto di questo, quindi sarei felice dei suggerimenti. – MatthiasG

1

ho potuto Non credo che la soluzione di Stephen Lautier funzioni in VB.Net, ma ho trovato un'altra soluzione che può funzionare.

Quando si verifica un'operazione di ordinamento, i seguenti eventi nell'ordine elencato:

  1. Ordinando
  2. UnloadingRow (Per tutte le righe nel DataGrid)
  3. LoadingRow (Per tutte le righe nel DataGrid)
  4. LayoutUpdated

Questo può essere utilizzato nel modo seguente:

Variabili

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

Ordinamento

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

UnloadingRow/Caricamento Row Eventi

'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 youtAggiornato

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

Dove hai trovato le informazioni sull'ordine degli eventi? Sto tentando di utilizzare l'evento LayoutUpdated (quando preceduto da un evento di ordinamento) come trigger per far scorrere il datagrid in alto. Mentre tutte le chiamate rilevanti sembrano essere in esecuzione come previsto, il comportamento finale non sta accadendo - il mio datagrid non sta scorrendo verso l'alto dopo un ordinamento. Invece, sta mantenendo in vista la riga selezionata. –

+0

Vorrei sapere di una fonte di riferimento, ma io no! Invece ho fatto qualche esperimento. Fondamentalmente, in questi scenari cerco di creare vari eventi che sono o ciò che penso io voglio o sono rilevanti. Quindi il listener di eventi invia un messaggio informativo alla console. In questo modo, i rapporti non interferiscono con l'uso della GUI e i messaggi mi informano che un particolare evento è stato attivato. Attraverso prove ed errori posso ottenere un'immagine dell'ordine di accensione, della frequenza, dei modelli o di quanto coerente possa essere con diverse impostazioni e azioni. – PellucidWombat

+0

La situazione sembra dipendere da determinate opzioni impostate nel datagrid o nel codice correlato, come lo scorrimento automatico alla selezione. Quindi se questo non è quello che vuoi, esaminerei come la tua selezione viene mantenuta o ripristinata dopo l'avvio di un ordinamento. Questo può darti un indizio su dove/come cambiare il comportamento. – PellucidWombat

Problemi correlati