2009-08-18 6 views
7

Ich verwende DataGrid aus der WPF Toolkit und ich muss in der Lage sein, den Fokus auf der Unterseite des Gitters (d. H. Der letzten Zeile) zu halten. Das Problem, das ich gerade habe, ist, dass wenn die Zeilen hinzugefügt werden, die Bildlaufleiste für die DataGrid nicht zusammen mit den neuen Zeilen, die hinzugefügt werden, gescrollt wird. Was ist der beste Weg, dies zu erreichen?WPF DataGrid - Wie konzentriert man sich am unteren Rand des DataGrid, wenn neue Zeilen hinzugefügt werden?

Antwort

6

Sieht aus wie DataGrid.ScrollIntoView(<item>) wird den Fokus auf der Unterseite der DataGrid halten.

+1

Wo nennen Sie diese Methode? – joe

+0

es tut. Rufen Sie einfach an, nachdem Sie Ihre Datenquelle mit dem neuen Element aktualisiert haben. Achten Sie darauf, UpdateLayout() vor ScrollIntoView obwohl! – Vinzz

+2

Warum müssen Sie zuerst UpdateLayout() aufrufen? Ich musste das nicht tun. Ist es aus irgendeinem Grund nur eine Best Practice? –

4

Dies ist ein einfacher Ansatz LoadingRow Ereignis:

void dataGrid_LoadingRow(object sender, System.Windows.Controls.DataGridRowEventArgs e) 
{ 
    dataGrid.ScrollIntoView(e.Row.Item); 
} 

Denken Sie daran, es zu deaktivieren, nachdem das Gitter vollständig geladen ist.

5

Ich habe festgestellt, dass die nützlichste Zeit, um die ScrollIntoView Methode aus dem ScrollViewer.ScrollChanged angefügten Ereignis aufzurufen. Dies kann in XAML wie folgt eingestellt werden:

<DataGrid 
... 
ScrollViewer.ScrollChanged="control_ScrollChanged"> 

Das ScrollChangedEventArgs Objekt verfügt über verschiedene Eigenschaften, die das Layout für die Berechnung hilfreich sein kann und Rollposition (Umfang, Offset, Ansichtsfenster). Beachten Sie, dass diese bei Verwendung der standardmäßigen DataGrid-Virtualisierungseinstellungen normalerweise in Anzahl von Zeilen/Spalten gemessen werden.

Hier ist eine Beispielimplementierung, die das unterste Element im Blick behält, wenn dem DataGrid neue Elemente hinzugefügt werden, es sei denn, der Benutzer verschiebt die Bildlaufleiste, um Elemente im Raster oben anzuzeigen.

private void control_ScrollChanged(object sender, ScrollChangedEventArgs e) 
    { 
     // If the entire contents fit on the screen, ignore this event 
     if (e.ExtentHeight < e.ViewportHeight) 
      return; 

     // If no items are available to display, ignore this event 
     if (this.Items.Count <= 0) 
      return; 

     // If the ExtentHeight and ViewportHeight haven't changed, ignore this event 
     if (e.ExtentHeightChange == 0.0 && e.ViewportHeightChange == 0.0) 
      return; 

     // If we were close to the bottom when a new item appeared, 
     // scroll the new item into view. We pick a threshold of 5 
     // items since issues were seen when resizing the window with 
     // smaller threshold values. 
     var oldExtentHeight = e.ExtentHeight - e.ExtentHeightChange; 
     var oldVerticalOffset = e.VerticalOffset - e.VerticalChange; 
     var oldViewportHeight = e.ViewportHeight - e.ViewportHeightChange; 
     if (oldVerticalOffset + oldViewportHeight + 5 >= oldExtentHeight) 
      this.ScrollIntoView(this.Items[this.Items.Count - 1]); 
    }