2009-03-18 12 views
7

Ich habe eine WPF DataGrid, die, wenn es zu viele Zeilen zum Anzeigen auf dem Bildschirm gibt es eine vertikale Bildlaufleiste. Ich würde gerne wissen, ob es eine Möglichkeit gibt zu wissen, was die oberste sichtbare Zeile ist, wenn der Benutzer scrollt.Überprüfen Sie sichtbare Zeilen in einem WPF DataGrid

Idealerweise möchte ich in der Lage sein, ein Ereignis zu verkabeln, um zu wissen, wann der Benutzer scrollt und scrollt, was die oberste sichtbare Zeile ist, um einige Informationen zu aktualisieren.

Antwort

0

Es ist eine Art überkomplizierte Art, es zu tun, aber es kann funktionieren. Zuerst Unterklasse DataGridRowsPresenter und überschreiben Sie die OnViewportOffsetChanged method. Kopieren Sie dann die Standardsteuervorlage für das Datagrid, und ersetzen Sie das DataGridRowsPresenter durch Ihr eigenes. Ich überlasse die Details des Treffertests für eine Reihe relativ zum Viewport dir ;-).

Was möchten Sie konkret erreichen? Vielleicht können wir einen besseren Weg finden, da dies sehr spröde sein kann und eine Menge zusätzlicher Arbeit erfordert (d. H. Die Kontrollschablone synchron halten, wenn sie aktualisiert wird).

+0

Danke. Ich habe es geschafft, indem ich nur das, was im Raster ist (hauptsächlich Schriftarten) mit Animationen skaliert. Nicht ganz so einfach, aber im Grunde, was ich wollte. –

+0

Ich stieß auf ein Problem mit der Skalierung der Schriftart, dass beim Skalieren der Schrift die Spalten nicht automatisch skaliert werden, so dass sie immer noch die Breite der größeren Schriftgröße haben. –

+0

Es gibt leider einen Fehler im aktuellen Build des WPFToolkits, der Spalten mit automatischer Größenänderung merkwürdig wirken lässt, wenn sie mit Spalten in Sterngröße gemischt werden. Wir sehen dieses Verhalten auch, und wir haben uns nie darum gekümmert, es zu reparieren. –

3

mit folgenden Methode für mich gearbeitet:

// 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, bearbeiten macht die Antwort völlig nutzlos (oder, naja, sehr unklar), kehrt zur ursprünglichen Antwort zurück. – Sinatr

+1

@Sinatr Ich stimme nicht zu und ich habe Ihre Änderung rückgängig gemacht. Wenn Sie immer noch nicht einverstanden sind, stellen Sie bitte eine Frage Meta Stack Exchange, anstatt einen Rollback-Krieg zu starten. –

+0

@DannyBeckett, bevor es eine saubere Schritt-für-Schritt-Anleitung war (ich stimme etwas schlechter Sprache zu) und ich bin mir sicher, Upvotes wurden zu dieser Zeit gegeben. Ich laufe jetzt auf das gleiche Problem und wenn ich diese Antwort im aktuellen Zustand versuche, schaffe ich es nicht, es zu funktionieren und es sogar zu verwerfen. Dann sehe ich deine Bearbeitung und lese die ursprüngliche Antwort, die viel klarer ist. Lass es so wie es ist. Zukünftige Leser werden meinen Kommentar trotzdem sehen (aber nicht alle von ihnen werden Revisionen sehen, denke ich, nicht mein Problem;). – Sinatr

2

Wie sei es mit dem Scroll des Datagrid an das ScrollViewer.ScrollChanged Ereignis abonniert? Die Ereignisargumente dafür sind sehr umfangreich und beschreiben, wie stark sich der ScrollViewer bewegt hat und was sein neuer vertikaler Versatz ist. Auch nach MSDN:

Wenn CanContentScroll wahr ist, werden die Werte der ExtentHeight, ScrollableHeight, Viewportheight und Vertical Eigenschaften Anzahl der Elemente. Wenn CanContentScroll false ist, sind die Werte dieser Eigenschaften geräteunabhängige Pixel.

CanContentScroll ist in der Tat der Fall für den ScrollViewer für ein DataGrid.

Alles was Sie tun müssen, ist die Scroll zu finden:

ScrollViewer scrollview = FindVisualChild<ScrollViewer>(dataGrid); 

eine Implementierung von FindVisualChild verwenden, die an verschiedenen Orten gefunden werden kann (wie hier: Finding control within WPF itemscontrol).

+0

Dies ist eigentlich eine nette und solide Vorgehensweise. – Gerard

0

Erkennen Scrollen ist so einfach wie

<DataGrid ScrollViewer.ScrollChanged="DataGrid_ScrollChanged" /> 

Nun müssen Sie Scroll Instanz erhalten:

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

(nicht sicher, wo ist Ursprung FindVisualChild, aber es gibt viele Implementierungen, zB here)

Und dann können Sie

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