2009-08-18 13 views
7

Estoy usando DataGrid del WPF Toolkit y necesito poder mantener el foco en la parte inferior de la cuadrícula (es decir, la última fila). El problema que estoy teniendo ahora es que a medida que se agregan filas, la barra de desplazamiento para el DataGrid no se desplaza junto con las nuevas filas que se agregan. ¿Cuál es la mejor manera de lograr esto?WPF DataGrid: ¿Cómo mantenerse enfocado en la parte inferior de DataGrid a medida que se agregan nuevas filas?

Respuesta

6

Parece que DataGrid.ScrollIntoView(<item>) mantendrá el foco en la parte inferior de DataGrid.

+1

¿A dónde llama este método? – joe

+0

lo hace. Simplemente haga una llamada después de haber actualizado su fuente de datos con el nuevo elemento. ¡Asegúrese de llamar a UpdateLayout() antes de ScrollIntoView though! – Vinzz

+2

¿Por qué necesita llamar a UpdateLayout() primero? No tuve que hacer eso. ¿Es solo una mejor práctica por alguna razón? –

4

Este es un enfoque simple usando evento LoadingRow:

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

Sólo recuerde para desactivarlo después de la carga de red está terminado.

5

He encontrado que el momento más útil para llamar al método ScrollIntoView es desde el evento adjunto ScrollViewer.ScrollChanged. Esto se puede establecer en XAML como sigue:

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

El objeto ScrollChangedEventArgs tiene varias propiedades que pueden ser útiles para el cálculo de la disposición y posición (Extensión, offset, Viewport) desplazamiento. Tenga en cuenta que, por lo general, se miden en números de filas/columnas cuando se usa la configuración de virtualización DataGrid predeterminada.

Aquí hay una implementación de ejemplo que mantiene el elemento inferior a la vista a medida que se agregan nuevos elementos al DataGrid, a menos que el usuario mueva la barra de desplazamiento para ver los elementos más arriba en la cuadrícula.

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