net eventos application c# sorting datagridview

c# - eventos - ¿Cómo implemento la clasificación automática de DataGridView?



row cells vb net (3)

Creo que encontré la respuesta. Mi fuente de datos implementa IList<T> . Aparentemente, necesita implementar IBindingList<T> . Lamentablemente, no puedo probar esto.

Estoy agregando columnas programáticamente a DataGridView y luego vinculando a una lista. Por defecto, el Modo de ordenación de las columnas es Automático. Pero cuando ejecuto mi aplicación, al hacer clic en los encabezados no hago nada. Las flechas arriba / abajo no se muestran. Al leer MSDN, no se dice mucho sobre la clasificación automática. Entran en más detalles sobre clasificación programática. Entonces, supongo que la manera automática debería ser fácil. MSDN continúa diciendo " A menos que los encabezados de las columnas se utilicen para la selección , al hacer clic en el encabezado de la columna se ordena automáticamente el DataGridView por esta columna y se muestra un glifo que indica el orden de clasificación". ¿Qué significa eso exactamente? ¿Podría estar configurando una propiedad de cuadrícula que entra en conflicto con la ordenación? ¿Qué me estoy perdiendo?

AutoGenerateColumns = false; AllowUserToAddRows = false; AllowUserToDeleteRows = false; AllowUserToResizeRows = false; AllowUserToResizeColumns = false; ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing; ReadOnly = true; MultiSelect = false; RowHeadersVisible = false; SelectionMode = DataGridViewSelectionMode.FullRowSelect; CellBorderStyle = DataGridViewCellBorderStyle.None; DataGridViewTextBoxColumn idColumn = new DataGridViewTextBoxColumn(); idColumn.HeaderText = "ID"; idColumn.DataPropertyName = "IDNumber"; DataGridViewTextBoxColumn nameColumn = new DataGridViewTextBoxColumn(); nameColumn.HeaderText = "Name"; nameColumn.DataPropertyName = "Description"; DataGridViewTextBoxColumn lastModifiedColumn = new DataGridViewTextBoxColumn(); lastModifiedColumn.HeaderText = "Last Modified"; lastModifiedColumn.DataPropertyName = "Date"; Columns.Add(idColumn); Columns.Add(nameColumn); Columns.Add(lastModifiedColumn); List<IMyObject> bindingList = GetMyList(); DataSource = bindingList;


La mejor solución que he encontrado:

EDITAR: desde la publicación encontré que esta implementación de SortableBindingList(Of T) es la mejor solución, con la excepción de que modifiqué la línea 52 para que fuera IEnumerable lugar de ICollection , ya que el constructor está lanzando de todos modos y funciona.

Alternativamente, la solución a continuación no necesita una clase personalizada:

DataGridView se puede ordenar sin implementar una clase personalizada. Tenga en cuenta que mi código está en VB.NET, pero debe traducirse. Los datos primero deben agregarse a la grid.Rows :

For Each item In dataList grid.Rows.Add(item.Id, item.Name, item.DateProperty) Next

Luego implementa estos controladores de eventos. El segundo es asegurar que la clasificación de fechas funcione. Solo lo necesita si su cuadrícula tendrá una columna de fecha ordenable:

Private Sub grid_ColumnHeaderMouseClick(ByVal sender As Object, ByVal e As DataGridViewCellMouseEventArgs) Handles grid.ColumnHeaderMouseClick Dim col = grid.Columns(e.ColumnIndex) Dim dir As System.ComponentModel.ListSortDirection Select Case col.HeaderCell.SortGlyphDirection Case SortOrder.None, SortOrder.Ascending dir = System.ComponentModel.ListSortDirection.Ascending Case Else dir = System.ComponentModel.ListSortDirection.Descending End Select grid.Sort(col, dir) End Sub Private Sub grid_SortCompare(ByVal sender As Object, ByVal e As DataGridViewSortCompareEventArgs) Handles grid.SortCompare ''This event occurs only when the DataSource property is not set and the VirtualMode property value is false. If e.Column.Name = "DateProperty" Then e.SortResult = Date.Compare(CType(e.CellValue1, Date), CType(e.CellValue2, Date)) e.Handled = True End If End Sub

Una cosa importante a tener en cuenta es que solo las propiedades que agrega a la fila son parte del objeto resultante, ya que no hay ningún enlace. Para mantener todo su objeto, deberá agregar columnas para cada propiedad, estableciendo las columnas Visible = False para cualquiera que no deba mostrarse.


Usamos BindingListView para vincular List <T> s a DataGridViews, y funcionó maravillosamente para nosotros.

Aquí hay un ejemplo muy simple de crear una vista de una lista de objetos (en C #):

List<Customer> customers = GetCustomers(); BindingListView<Customer> view = new BindingListView<Customer>(customers); dataGridView1.DataSource = view;

Visite https://.com/a/17952576/116891 para obtener más detalles sobre la clasificación y enlace de datos de DGV.

Si no desea agregar algo tan pesado, puede probar esta implementación de SortableBindingList <T> ( con actualizaciones ).

Ambos le ofrecen una ordenación inmediata, y BindingListView es incluso más rápido que DataViews, de acuerdo con sus puntos de referencia.