2011-03-26 40 views
8

Tengo un WPF DataGrid con algunos datos vinculados a las clases de entidad LINQ to SQL. Una columna es un reloj que muestra el tiempo nacido en el aire de un vuelo dado, que se calcula usando la lógica en la clase parcial de Vuelo. Tengo un temporizador que llama a datagrid.Items.Refresh cada 2 segundos para actualizar el reloj.Actualice WPF DataGrid sin perder el foco de celda

La actualización funciona bien, pero ahora estoy agregando atajos de teclado. Navegar por las celdas con las flechas del teclado funciona bien con el temporizador apagado, pero con el temporizador de actualización habilitado, la celda enfocada (en realidad toda la cuadrícula de datos) pierde el foco.

Necesito mantener de alguna manera el enfoque (preferido) o desactivar el temporizador cada vez que se enfoca DataGrid. Ni siquiera puedo hacer que este último trabaje. He intentado:

if (!dataGrid.IsFocused) 
    dataGrid.Items.Refresh(); 

y

if (!dataGrid.IsKeyboardFocused) 
     dataGrid.Items.Refresh(); 

para el temporizador, pero estas propiedades return false incluso cuando la cuadrícula de datos se concentra.

¿Alguna idea?

+0

simplemente almacene el índice de la fila seleccionada, establezca selectedIndex después de actualizar – Hukam

+0

¿Por qué no invocar PropertyChanged de forma asincrónica en la definición de la entidad vinculada y cambiar la propiedad de invocación del temporizador (o de alguna lógica en la clase de entidad parcial). Entonces solo puedes usar UpdateSource.OnPropertyChanged para su enlace DataGridColumn, que debería (en teoría) evitar que toda la DG se actualice y solo actualice las entidades modificadas (y así resolver su problema de enfoque Y conducir a, de esta manera, un mejor rendimiento). ¿Me estoy perdiendo de algo? – William

Respuesta

0

pienso que usted puede conseguir el enfoque actual y después de rejilla se actualiza dar a la celda seleccionada hacia atrás su enfoque algo así como

int index = 11; 
myDataGrid.SelectedItem = myDataGrid.Items[index]; 
myDataGrid.ScrollIntoView(myDataGrid.Items[index]); 
DataGridRow dgrow = (DataGridRow)myDataGrid.ItemContainerGenerator.ContainerFromItem(myDataGrid.Items[index]); 
dgrow.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next)); 

también comprobar this cabo puede ayudarle a

+1

¿Cómo se obtiene el índice inicialmente? – Anders

+0

si estoy en lo correcto está pidiendo que se obtenga el índice antes de actualizar, si ese es el caso, entonces lo que hago es declarar una variable y mantenerla en leftmousedown o up event handler y comprobar que si 'datagrid.SelectedIndex> = 0' then actualizar la variable de esta manera hubiera actualizado el índice –

2

La mejor manera de no se para usar dataGrid.Items.Refresh() como mecanismo de actualización. Parece que los objetos subyacentes ya están actualizados por separado. Si implementan INotifyPropertyChanged, usted debe tratar de establecer el modo vinculante para la Colum como TwoWay Encuadernación:

<DataGridTextColumn Binding="{Binding xyz, Mode=TwoWay}"/> 
0

Sus células pierden el enfoque, porque cambia la colección subyacente (ItemsSource). No hay una manera hermosa, por lo que recuerdo, de obtener la célula. Para la fila:

Si trabaja con MVVM, puede memorizar su SelectedItem o SelectedIndex y restaurarlo después de que la recarga se realiza mediante enlace. Eso te pondrá en la fila correcta, para empezar. Ambos tienen diferentes inconvenientes:

  • SelectedItem requiere un poco más de trabajo. Asegúrese de anular Equals y GetHashCode en los objetos subyacentes si lo usa. Si su artículo fue el número 5 en la colección y durante la recarga aparece otra fila antes, usted terminará en la línea derecha
  • SelectedIndex es la solución más rápida, pero es solo una posición numérica. Si selecciona el número de entrada 5 y la recarga se fusiona en filas anteriores, terminará con la fila seleccionada incorrecta.

Como dije, no he intentado con las celdas, pero puede leer this para empezar. Tal vez puedas aplicarlo a tu problema.

Cuestiones relacionadas