2011-01-27 68 views
10

En una aplicación WinForm, C# 4.0, tengo un DataGridView vinculado a una SortableBindingList. Por lo tanto, se puede ordenar haciendo clic en la columna del encabezado; todo bien hasta ahora ;-)Filas seleccionadas al ordenar DataGridView en la aplicación WinForm

El problema es que las filas seleccionadas parecen "recordadas" por el número de fila. Esto es lo que sucede:

A* <- "Selected" 
B 
C 

Ahora ordenando descendente, C en la parte superior y seleccionado. Me gustaría tener todavía A seleccionado:

C* <- "Selected" 
B 
A <- "Want have" 

Lo mismo sucede con varias filas seleccionadas. ¿Hay una solución para esto?

+0

Usted está correcto. Las filas seleccionadas son 'recordadas' por el índice de fila y no por los valores de fila. –

+0

ASP .NET 4 ha introducido la propiedad EnablePersistedSelection para GridView. Pero no parece que esté disponible para WinForms. http://www.asp.net/learn/whitepapers/aspnet4#0.2__Toc253429262 –

Respuesta

11

Puede solucionar este problema almacenando el valor de la fila (o filas) seleccionada actualmente antes de ordenar y luego volver a seleccionar la fila después.

Debe usar el evento CellMouseDown - es necesario utilizar este evento ya que es el único que se dispara antes de que ocurra la clasificación. Eventos alternativos como ColumnHeaderMouseClick son demasiado tarde.

En el controlador de eventos CellMouseDown, compruebe que el índice de la fila sea -1 para asegurarse de que se seleccionaron los encabezados.

void dataGridView1_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e) 
{ 
    if (e.RowIndex == -1) 
    { 
     selected = dataGridView1.SelectedRows[0].Cells[0].Value.ToString(); 
    } 
} 

que tienen un campo de nivel de clase selected que utilizo para almacenar el identificador único de la columna que se ha seleccionado. Si no tiene una identificación única, puede agregar una columna para este propósito y ocultarla.

Luego, en el Sorted eventhandler del DataGridView puede utilizar el método .find() de origen de enlace de la red:

void dataGridView1_Sorted(object sender, EventArgs e) 
{ 
    if (!string.IsNullOrEmpty(selected)) 
    { 
     int itemFound = _bindingSource.Find("name", selected); 
     _bindingSource.Position = itemFound; 
    } 
} 

Si bien la investigación de este encontré la siguiente post en los foros de MSDN donde los usos de respuesta el evento DataBindingComplete: no estoy al 100% de por qué lo consideraron necesario ya que mi enfoque ha funcionado para todas mis pruebas, pero podría encontrarlo como una referencia útil.

3

Aquí es mi enfoque en VB.NET

Private cSelectedRow As String 

Private Sub DataGridView1_CellMouseDown(sender As Object, e As DataGridViewCellMouseEventArgs) Handles DataGridView1.CellMouseDown 
    If e.RowIndex = -1 AndAlso DataGridView1.SelectedRows.Count > 0 Then 
     cSelectedRow = DataGridView1.SelectedRows(0).Cells("ID").Value.ToString() 
    End If 
End Sub 

utilicé los mismos eventos que David Hall, pero no usamos la BindingSource. Así que recorro todas las líneas de la cuadrícula para encontrar la que fue seleccionada antes.

Private Sub DataGridView1_Sorted() Handles DataGridView1.Sorted 
    DataGridView1.ClearSelection() 
    For Each xRow As DataGridViewRow In DataGridView1.Rows 
     If xRow.Cells("ID").Value = cSelectedRow Then 
      DataGridView1.CurrentCell = xRow.Cells(0) 
      'Line Found. No need to loop through the rest. 
      Exit For 
     End If 
    Next 
End Sub 
Cuestiones relacionadas