2010-01-07 28 views
7

Estoy utilizando simplemente un DataGridView simple para contener un montón de datos (Es curioso).Winform DatagridView Clasificación de columna numérica

Tengo decimales en una columna en particular. Pero cuando se trata de ordenar por esa columna decimal, lo ordena incorrectamente. Por ejemplo:

orden de salida podría ser:

  • 0,56
  • 3,45
  • 500,89
  • 20078,90
  • 1,56
  • 100,29
  • 2,39

El orden final sería:

  • 0,56
  • 100,29
  • 1,56
  • 20078,90
  • 2,39
  • 3,45
  • 500,89

Como puede ver, lo ordena comenzando desde el primer número. Y luego lo ordena de esta manera.

Pensé que posiblemente podría establecer la columna en un "ColumnType" diferente y eso podría hacerlo automáticamente. Pero no hay tipos de columna "Numérico" o "Decimal".

Estaba en MSDN buscando el problema, y ​​pude encontrar el método de "clasificación" que puedo usar en DataGridView. Pero la explicación estaba un poco sobre mi cabeza, y los ejemplos no usaban números, solo texto, así que no podía ver cómo se suponía que debía cambiar las cosas.

Cualquier ayuda sería muy apreciada.

Respuesta

7

Puede resolver esto mediante la adición de un controlador para el evento SortCompare en el DataGridView con el siguiente código:

private void dataGridView1_SortCompare(object sender, DataGridViewSortCompareEventArgs e) 
{ 
    if (e.Column.Index == 0) 
    { 
     if (double.Parse(e.CellValue1.ToString()) > double.Parse(e.CellValue2.ToString())) 
     { 
      e.SortResult = 1; 
     } 
     else if (double.Parse(e.CellValue1.ToString()) < double.Parse(e.CellValue2.ToString())) 
     { 
      e.SortResult = -1; 
     }    
     else 
     { 
      e.SortResult = 0; 
     } 
     e.Handled = true; 
    } 
} 

de MSDN no es esta descripción de los valores SortResult:

Menos que cero si la primera celda se ser ordenados antes de la segunda ce ll; cero si la primera celda y la segunda celda tienen valores equivalentes; mayor que cero si la segunda celda se ordenará antes de la primera celda.

Tenga en cuenta que en mi banco de pruebas la única columna numérica fue la primera (con índice 0) por lo que es por eso que tengo el control en el índice de la columna.

Además, según sus necesidades y datos, es posible que desee refinar mi código; por ejemplo, mi código emitirá una excepción si por algún motivo tiene datos no numéricos en su columna.

Probablemente lo haya visto, pero here es un enlace a la página de MSDN sobre cómo personalizar la clasificación de DataGridView. Como dices, solo tratan con texto.

+0

¡Ooooo el hombre! Sí funcionó perfecto :) Gracias hombre! – MindingData

+0

Ha estado luchando con esto, su código funciona, mientras que los otros que encontré no. Gracias. – user1500403

0

Lo está ordenando por carácter. Debe hacer que el tipo de columna flote para que sepa qué operador de comparación aplicar.

(Eso es lo que necesita para hacer el tipo de columna en su flotador conjunto de datos, creo que va a funcionar.)

+0

No se usa databinding :). – MindingData

+0

¡yikes! ¿Cómo estás obteniendo los datos en la grilla? – Hogan

+0

Bueno ... Tengo una lista de una estructura personalizada. Eso tiene alrededor de 5 elementos de cadena contenidos en él. Por lo tanto, solo puedo usar un forloop, iterar por la lista y agregarlos uno a uno a la cuadrícula de datos. Hacerlo a través de webscraping, y no hay necesidad de "retener" los datos una vez que están en la cuadrícula. No hay manipulación de datos, (excepto para ordenar: P), simplemente usando la cuadrícula de datos para propósitos de visualización. – MindingData

0

Tu problema es datagridview orden por secuencia. Pruebe a enviar el string al float cuando copie esa celda en el datagrid.

6

Tuve el mismo problema. Intenté usar el controlador de eventos como lo mencionó David Hall. Usé la propiedad ValueType al definir DataGridView. Ahora se clasifica como dobles, no hay código de controlador de eventos personalizado necesario

dataGridView1.Columns[int index].ValueType = typeof(double); 

También puede formatear la columna usando

dataGridView2.Columns[int index].DefaultCellStyle.Format = string format; 
+0

Muy buena sugerencia, si funcionaría. Sin embargo, por cualquier razón, para mí esto no funciona. Lo revisé en el Depurador y el ValueType de hecho se da como 'Doble', pero en realidad no se ordena en consecuencia. – Yellow

+0

@ Amarillas, es posible que desee comprobar si está haciendo 'typeof (double)' en lugar de 'typeof (Double)'. Una es una clase y la otra es de tipo variable. Tuve problemas similares al usar la clase def Double también. –

1

tipos numéricos han construido en función de CompareTo, que puede ser utilizado como el SortResult de el evento SortCompare.

private void dataGridView_SortCompare(object sender, DataGridViewSortCompareEventArgs e) 
    { 
     if (e.Column.Index == 0) 
     { 
      e.SortResult = int.Parse(e.CellValue1.ToString()).CompareTo(int.Parse(e.CellValue2.ToString())); 
      e.Handled = true; 
     } 
    } 

Por supuesto, suponiendo que conoce el tipo que se puso en el DataGridView para comenzar.

1

El tipo de columna de la base de datos debe ser int o double o float, no varchar o algo .... Así que debe cambiar su valor-tipo en la base de datos ... No necesita escribir ningún código o algo se ordena directamente cuando hace clic en la columna Encabezado ...

+0

Además, puede cambiar su consulta para convertir el resultado en int, double o float. No necesita cambiar el tipo en la base de datos. –

Cuestiones relacionadas