.net - filas - Clasificación personalizada de un DataGridView enlazado
datagridview c# ejemplos (5)
Tengo un DataGridView vinculado a una DataTable. Tengo una columna que es un pseudo-int. Conoces el tipo, donde la mayoría de las veces tiene enteros, pero a veces hay un N / A. Esta columna es varchar, pero quiero que se ordene como una columna int, tratando el N / A como -1.
DataGridView proporciona esto, si no está vinculado a una DataTable. Si está vinculado, usa el mecanismo de clasificación del objeto encuadernado, y DataTables no expone esa funcionalidad.
Puedo hacer una columna personalizada en el DataTable con el comportamiento que quiero, pero dado que DataGridView está vinculado a DataTable, ordena por la columna que está mostrando. Puedo hacer una columna personalizada en DataGridView, pero necesito establecer la tabla en modo virtual para ordenarla cuando ya tengo una solución que funciona en su mayoría.
¿Cómo puedo hacer que ordene mi columna pseudo-int como quiero, donde sea posible, ordenando por int? Este escenario parece increíblemente común, y estoy seguro de que está previsto.
Intente vincular a un DataView , no a una DataTable , por ejemplo:
private void SortByTwoColumns()
{
DataView myDataView = DataTable1.DefaultView;
myDataView.Sort = "State, ZipCode DESC";
myGridView.DataSource = myDataView;
}
Tiene algunas opciones para tratar con los datos N / A: instrucción SELECT , evento RowPrePaint y más.
¿Por qué no simplemente cambia la consulta SQL para devolver esta columna como int (-1 para ''N / A'') y luego usa un formateador personalizado para la columna mostrada?
Cuando he tenido que lidiar con problemas de clasificación similares a este, mi método favorito es agregar una columna al DataTable y analizar el pseudo-int en la clasificación int que deseo. Luego, en el enlace de DataGridView puedes simplemente ocultar esa columna de datos, pero debido a que está ahí, aún puedes ordenarla. Agrega un poco de datos extra a la memoria para hacer esto, por lo que dependiendo del rendimiento alcanzado y el tamaño de los datos ordenados, esto podría ser un problema potencial. Además, cada vez que se modifiquen los datos, necesitarás asegurarte de que esta columna adicional se mantenga en línea.
Tal vez pueda adaptar el código en mi publicación de blog para proporcionar un IComparer específico para su columna int:
http://adamhouldsworth.blogspot.com/2010/01/bound-datagridview-sorting.html
Junto con la respuesta de Joel Etherton hay un evento que puede manejar que le permitirá anular el valor mostrado para una celda.
Entonces, como dijo, querrás dos columnas. Una es una columna numérica fuertemente tipada con -1s para los valores de texto. La otra es una columna de texto oculto con los valores reales (valores numéricos y de texto mixtos). Tal como está, se ordenará correctamente, pero el usuario verá -1 en lugar del valor real.
Para solucionar esto, necesitamos este código:
Private Sub dgDisplay_CellFormatting(ByVal sender As Object, _
ByVal e As System.Windows.Forms.DataGridViewCellFormattingEventArgs) _
Handles dgDisplay.CellFormatting
If Not (e.ColumnIndex = dgDisplay.Columns("NumericColumn").Index _
AndAlso e.RowIndex >= 0) Then Exit Sub
Dim newVal As String = dgDisplay.Item("ActualColumn", e.RowIndex).Value
e.Value = newVal
End Sub
Esto mostrará el valor de texto real que desea ver, aunque el valor en el DataSource
encuadernado sea solo numérico.
Si va a filtrar en el DataView
detrás de DataGridView
, asegúrese de filtrar en la columna oculta.