2009-03-18 3 views
7

Ho un WPF DataGrid, che quando ci sono troppe righe da visualizzare sullo schermo ottiene una barra di scorrimento verticale. Quello che vorrei sapere è se c'è un modo per sapere quale sia la riga visibile più in alto quando l'utente sta scorrendo.Controlla le righe visibili in un DataGrid WPF

Idealmente mi piacerebbe essere in grado di cablare un evento per sapere quando l'utente sta scorrendo e su scroll, controllare quale sia la riga visibile più in alto per aggiornare alcune informazioni.

risposta

0

È un modo complicato di farlo, ma potrebbe funzionare. In primo luogo, sottoclassi DataGridRowsPresenter e sostituisci lo OnViewportOffsetChanged method. Quindi, duplicare il modello di controllo standard per il datagrid e sostituire DataGridRowsPresenter con il proprio. Lascio a te i dettagli del test di successo per una riga relativa al viewport ;-).

Che cosa stai cercando di realizzare, in particolare? Forse possiamo trovare un modo migliore, in quanto potrebbe essere molto fragile e richiede un sacco di lavoro extra (ad esempio mantenendo il modello di controllo sincronizzato se lo aggiornano).

+0

Grazie. Ci sono riuscito a ridimensionare ciò che è nella griglia (principalmente i caratteri) usando le animazioni. Non è così semplice, ma fondamentalmente ciò che volevo. –

+0

Ho riscontrato un problema con il ridimensionamento del carattere, che durante il ridimensionamento del font le colonne non verranno ridimensionate automaticamente in modo che abbiano ancora la larghezza della dimensione del carattere più grande. –

+0

C'è purtroppo un bug nella build attuale di WPFToolkit che fa sì che le colonne di ridimensionamento automatico funzionino in modo strano quando vengono mescolate con colonne di dimensioni Star. Vediamo questo comportamento, e non ci siamo mai preoccupati di risolverlo. –

3

utilizzando il seguente metodo ha funzionato per me:

// mHorizontalScrollBar is the HorizontalScrollBar subclass control's instance 

// Get the total item count 
nTotalCount = DataGrid1.Items.Count; 

// Get the first visible row index 
nFirstVisibleRow = mHorizontalScrollBar.Value; 

// Get the last visible row index 
nLastVisibleRow = nFirstVisibleRow + nTotalCount - mHorizontalScrollBar.Maximum; 
+0

@DannyBeckett, modificare rende la risposta del tutto inutile (o, bene, molto chiaro), di ritornare alla risposta originale. – Sinatr

+1

@Sinatr non sono d'accordo e ho rollback la modifica. Se non sei ancora d'accordo, per favore pubblica una domanda Meta Stack Exchange invece di iniziare una guerra di rollback. –

+0

@DannyBeckett, prima che fosse una guida pulita step-by-step (Sono d'accordo con un po 'male la lingua) e sono sicuro upvotes sono stati dati in quel momento. Ora corro nello stesso problema e quando provo questa risposta nello stato attuale non riesco a farlo funzionare e persino a downsarlo. Poi ho individuato la tua modifica e ho letto la risposta originale, che è mooolto più chiara. Lasciamo così com'è. I futuri lettori vedranno comunque il mio commento (ma non tutti saranno in grado di vedere le revisioni credo, non il mio problema;). – Sinatr

2

Come circa la sottoscrizione all'evento ScrollViewer.ScrollChanged sul ScrollViewer del DataGrid? Gli argomenti dell'evento sono piuttosto estesi, descrivendo quanto è stato spostato ScrollViewer e quale è il suo nuovo offset verticale. Inoltre, secondo MSDN:

Se CanContentScroll è vero, i valori delle proprietà ExtentHeight, ScrollableHeight, ViewportHeight e VerticalOffset sono numero di elementi. Se CanContentScroll è falso, i valori di queste proprietà sono Pixel indipendenti dal dispositivo.

CanContentScroll è effettivamente il caso per ScrollViewer per un DataGrid.

Tutto quello che dovete fare è trovare lo ScrollViewer:

ScrollViewer scrollview = FindVisualChild<ScrollViewer>(dataGrid); 

utilizzando un'implementazione di FindVisualChild che possono essere trovati in vari luoghi (come qui: Finding control within WPF itemscontrol).

+0

Questo è in realtà un approccio piacevole e solido. – Gerard

0

Rilevare scrolling è facile come

<DataGrid ScrollViewer.ScrollChanged="DataGrid_ScrollChanged" /> 

Ora è necessario ottenere esempio ScrollViewer:

void DataGrid_ScrollChanged(object sender, RoutedEventArgs e) 
{ 
    var scroll = FindVisualChild<ScrollViewer>((DependencyObject)sender); 
    ... 
} 

(Non sai da dove è all'origine di FindVisualChild, ma ci sono un sacco di implementazioni, ad esempio here)

e poi si può

int firstRow = (int)scroll.VerticalOffset; 
int lastRow = (int)scroll.VerticalOffset + (int)scroll.ViewportHeight + 1;