propiedades por obtener nombre metodos eventos ejemplos datos columns columnas columna codigo agregar c# sorting datagridview dataview

por - C#: tipo personalizado de DataGridView



metodos datagridview c# (5)

Necesito ordenar un DataGridView con Natural Sorting (Like in Explorer) para que los números y el texto (en la misma columna) estén ordenados de forma natural y no alfabéticamente (de modo que "lugar 3" viene antes que "lugar 20", etc.). Tengo un DataGridView, donde he configurado un DataView como DataSource. DataView contiene una DataTable que se crea con algunos valores de una base de datos. Los tipos de columnas son cadenas. Tengo un IComparer, que hace lo que debería, pero no puedo encontrar la forma de usarlo, porque no puedo averiguar cómo hacer la clasificación. El evento DataGridView.SortCompare, que sería perfecto , no funciona ya que está enlazado a datos. El DataView.Sort solo acepta cadenas con nombres de columnas y órdenes de clasificación.

Muy molesto. Intenté leer problemas relacionados aquí en StackOverflow, y busqué montones y lotes de google, pero realmente no puedo encontrar mucho sobre esto. Lo único que realmente encuentro es utilizar ese método Sort (cadena) de la vista de datos, que no funcionará, ya que ordena alfabéticamente.

¿Alguien sabe cómo hacer esto sin demasiados problemas? ¿Hay otros que yo luchando con esto? Realmente no quiero volver a implementar todas las clases datagridview o dataview, solo para obtener una clasificación personalizada ...

Actualización : en caso de que alguien se esté preguntando, todavía estoy buscando una buena respuesta a este problema. Aunque, mientras tanto, terminé creando mi propia clase de tabla simple y luego la introduje manualmente en una vista de cuadrícula de datos. Anulando el método SortCompare. Un poco molesto, pero no fue demasiado difícil, ya que solo necesito mostrar valores (sin edición ni nada) y, por lo tanto, podría convertir todo en cadenas.


Puedes crear 2 columnas ocultas. Asigna la parte del texto a la primera columna oculta y la parte del número a la segunda columna oculta. Ahora ordena por estas columnas ocultas (clasificación alfa para la 1ra columna y clasificación numérica para la 2da columna).

De esta manera, puede conservar la columna original para fines de visualización y tener las 2 columnas ocultas para ordenar.


Eche un vistazo a esta página de MSDN y a esta publicación de blog . En principio, debe configurar la ordenación en el origen de datos (ya sea un ObjectDataSource o un SqlDataSource) no en el GridView.

Por lo que puedo decir, la clase DataView no admite nada más que una ordenación ascendente / descendente simple. Sin ver el código donde carga y vincula los datos, es difícil hacer una recomendación específica, pero podría:

  1. Cargue sus datos en una lista en lugar de una tabla de datos, llame al método de clasificación que pasa en su método de comparación y luego vincule a esa lista.
  2. Cree un ObjectDataSource en su código aspx que obtenga los datos directamente de una clase, y configure ese ObjectDataSource para usar su IComparer.


Este código debería funcionar. Es similar al ListViewItemSorter de ListView. Usando IComparer.

Usar:

private void dgv_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e) { MyDataGridHelper.DataGridSort(dgv, e.ColumnIndex); }

MyDataGridHelper.cs:

public class MyDataGridHelper { public static void DataGridSort(DataGridView dgv, int column) { DataGridViewCustomSorter dgvSorter = null; if (dgv.Tag == null || !(dgv.Tag is IComparer)) { dgvSorter = new DataGridViewCustomSorter(dgv); dgv.Tag = dgvSorter; } else { dgvSorter = (DataGridViewCustomSorter)dgv.Tag; } dgvSorter.SortColumn = column; dgv.Sort(dgvSorter); } private class DataGridViewCustomSorter : IComparer { private int ColumnIndex; private SortOrder OrderOfSort; private DataGridView myDataGridView; private TypeCode mySortTypeCode; public DataGridViewCustomSorter(DataGridView dgv) { myDataGridView = dgv; mySortTypeCode = Type.GetTypeCode(Type.GetType("System.String")); ColumnIndex = 0; OrderOfSort = SortOrder.None; } public int Compare(object x, object y) { int result; DataGridViewRow dgvX, dgvY; dgvX = (DataGridViewRow)x; dgvY = (DataGridViewRow)y; string sx = dgvX.Cells[ColumnIndex].Value.ToString(); string sy = dgvY.Cells[ColumnIndex].Value.ToString(); //null handling if (sx == String.Empty && sy == String.Empty) result = 0; else if (sx == String.Empty && sy != String.Empty) result = -1; else if (sx != String.Empty && sy == String.Empty) result = 1; else { switch (mySortTypeCode) { case TypeCode.Decimal: Decimal nx = Convert.ToDecimal(sx); Decimal ny = Convert.ToDecimal(sy); result = nx.CompareTo(ny); break; case TypeCode.DateTime: DateTime dx = Convert.ToDateTime(sx); DateTime dy = Convert.ToDateTime(sy); result = dx.CompareTo(dy); break; case TypeCode.String: result = (new CaseInsensitiveComparer()).Compare(sx, sy); break; default: result = (new CaseInsensitiveComparer()).Compare(sx, sy); break; } } if (OrderOfSort == SortOrder.Descending) result = (-result); return result; } public int SortColumn { set { if (ColumnIndex == value) { OrderOfSort = (OrderOfSort == SortOrder.Descending ? SortOrder.Ascending : SortOrder.Descending); } ColumnIndex = value; try { mySortTypeCode = Type.GetTypeCode(Type.GetType((myDataGridView.Columns[ColumnIndex]).Tag.ToString())); } catch { mySortTypeCode = TypeCode.String; } } get { return ColumnIndex; } } public SortOrder Order { set { OrderOfSort = value; } get { return OrderOfSort; } } } //end class DataGridViewCustomSorter } //end class MyDataGridHelper


Podría mover la lógica de ordenamiento a su consulta de base de datos y hacer que devuelva una columna adicional que tenga el orden de clasificación correcto.

Luego (a lo largo de las líneas de la respuesta de @True C Sharp) podría tener una columna oculta que contenga este valor y ordenar por esta en lugar de por la columna de visualización.

Esto supone que la lógica para determinar el orden de clasificación se puede realizar en SQL. Esto puede no funcionar si el algoritmo para determinar el orden de clasificación es complejo.