none
Ordenar un DataGridView / DataGridViewTextColumn por valor numérico RRS feed

  • Pregunta

  • Hola a todos,

    Esta vez vengo con una duda sobre los DataGridViewTextColumn. Tengo un DataGridView con diferentes columnas, y una es un DataGridViewTextColumn que almacena datos numéricos. Este dato numérico almacena direcciones en el siguiente formato: fila.columna. Por ejemplo:

    0.1
    6.7
    11.3
    0.2
    11.8
    6.4

    Cuando hago click en el Header del DataGridViewTextColumn para ordenarlo me ordena por texto de la siguiente manera:

    0.1
    0.2
    11.3
    11.8
    6.4
    6.7

    Lo que me gustaría es que se ordenase por el valor numérico que tiene el texto, así:

    0.1
    0.2
    6.4
    6.7
    11.3
    11.8

    Esto se puede hacer?

    Gracias de antemano. 

    jueves, 14 de abril de 2011 8:12

Respuestas

  • hola

    algo que quizas este pasando es que la configuracion regional afecte en el orden de los valores

    o sea veo que usas el punto como separador, pero si indicas un ValueType del tipo float, puede que si la configuracion regional de tu pc es es-ES toma la coma como separador de decimales lo cual puede traer problema

    quizas debas ir por un custom sorting de esa columna

    o sea tu defines el codigo de como debe resolver la ordenacion de los valores

     

    saludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina
    • Marcado como respuesta Jon 123 jueves, 14 de abril de 2011 13:44
    jueves, 14 de abril de 2011 11:43
  • ¡Gracias por la respuesta Leandro!

    Del enlace que has puesto me he decantado por la Ordenación personalizada mediante el evento SortCompare, capturando el evento con esta función:

     

    void dataGridView1_SortCompare(object sender, DataGridViewSortCompareEventArgs e)
    {
      if (e.Column == this.dgcNumero)
      {
        float v1, v2;
     
        if (e.CellValue1 == null)
          v1 = -1;
        else
        {
          if (!float.TryParse(e.CellValue1.ToString(), NumberStyles.AllowDecimalPoint, CultureInfo.GetCultureInfo("en-GB"), out v1))
            v1 = -1;
        }
    
        if (e.CellValue2 == null)
          v2 = -1;
        else
        {
          if (!float.TryParse(e.CellValue2.ToString(), NumberStyles.AllowDecimalPoint, CultureInfo.GetCultureInfo("en-GB"), out v2))
            v2 = -1;
        }
    
        if (v1 < v2)
          e.SortResult = -1;
        else if (v1 > v2)
          e.SortResult = 1;
        else
          e.SortResult = 0;
    
        e.Handled = true;
      }
    }
    

     

    Primero miro si lo columna que se va a ordenar es la columna de direcciones, y después paso el string a float, para finalmente hacer la comparación.


    • Marcado como respuesta Jon 123 jueves, 14 de abril de 2011 13:44
    jueves, 14 de abril de 2011 13:44

Todas las respuestas

  • Buenas Jon 123.

    Eso te está pasando porque el ValueType es de tipo texto, cambia el ValueType del DataGridViewColumn a tipo numérico.

    Un saludo.


    http://www.lopezatienza.es
    jueves, 14 de abril de 2011 9:52
  • Hola lopezatienza,

    Lo he intentado definiéndolo en el constructor de la siguinete manera, pero me da el mismo resultado. Lo estoy haciendo mal?

     

    InitializeComponent();
    this.dgcNumero.ValueType = typeof(int);
    

     

    También lo he intentado con typeof(float), Type.GetType("System.Int32") y Type.GetType("System.Single"), pero sigue ordenándolo mal.

    He visto también, que el DataGridViewTextBoxColumn tiene una propiedad llamada SortMode, que tiene tres opciones: Automatic, NotSortable y Programmatic. ¿Alguien sabe cómo se utiliza la tercera opción? ¿Cómo le digo qué función usar cuando lo ordene?

     

    jueves, 14 de abril de 2011 10:26
  • Buenas Jon 123.

    Comprueba que el tipo de dato que proviene de la consulta que realizas a la base de datos es de tipo numérico, en este caso al tener decimales debería ser decimal o float.

    Un saludo.


    http://www.lopezatienza.es
    jueves, 14 de abril de 2011 10:40
  • Lo que pasa es que no lo relleno desde una base de datos. Los datos los meto manualmente, cada dirección corresponde a un dispositivo específico, y ellos me mandan su dirección (entre otras cosas) por un puerto COM, y yo lo muestro.
    jueves, 14 de abril de 2011 10:51
  • Buenas Jon 123.

    Personalmente lo que haría sería crearme un DataSet en tiempo de ejecución con las columnas necesarias, e ir insertando registros en este DataSet y aplicandole el DataSource cada vez que inserte un nuevo registro.

    Así te aseguras que el tipo de datos sea numérico ya que parece que sigue siendo de tipo Texto.

    De todos modos te dejo un link de la propia msdn donde se soluciona:

    http://social.msdn.microsoft.com/Forums/en-US/winformsdatacontrols/thread/72f8ba5a-0a93-4d2a-b054-a75e919f1b3d/

    Un saludo.


    http://www.lopezatienza.es
    jueves, 14 de abril de 2011 10:59
  • hola

    algo que quizas este pasando es que la configuracion regional afecte en el orden de los valores

    o sea veo que usas el punto como separador, pero si indicas un ValueType del tipo float, puede que si la configuracion regional de tu pc es es-ES toma la coma como separador de decimales lo cual puede traer problema

    quizas debas ir por un custom sorting de esa columna

    o sea tu defines el codigo de como debe resolver la ordenacion de los valores

     

    saludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina
    • Marcado como respuesta Jon 123 jueves, 14 de abril de 2011 13:44
    jueves, 14 de abril de 2011 11:43
  • ¡Gracias por la respuesta Leandro!

    Del enlace que has puesto me he decantado por la Ordenación personalizada mediante el evento SortCompare, capturando el evento con esta función:

     

    void dataGridView1_SortCompare(object sender, DataGridViewSortCompareEventArgs e)
    {
      if (e.Column == this.dgcNumero)
      {
        float v1, v2;
     
        if (e.CellValue1 == null)
          v1 = -1;
        else
        {
          if (!float.TryParse(e.CellValue1.ToString(), NumberStyles.AllowDecimalPoint, CultureInfo.GetCultureInfo("en-GB"), out v1))
            v1 = -1;
        }
    
        if (e.CellValue2 == null)
          v2 = -1;
        else
        {
          if (!float.TryParse(e.CellValue2.ToString(), NumberStyles.AllowDecimalPoint, CultureInfo.GetCultureInfo("en-GB"), out v2))
            v2 = -1;
        }
    
        if (v1 < v2)
          e.SortResult = -1;
        else if (v1 > v2)
          e.SortResult = 1;
        else
          e.SortResult = 0;
    
        e.Handled = true;
      }
    }
    

     

    Primero miro si lo columna que se va a ordenar es la columna de direcciones, y después paso el string a float, para finalmente hacer la comparación.


    • Marcado como respuesta Jon 123 jueves, 14 de abril de 2011 13:44
    jueves, 14 de abril de 2011 13:44