我以编程方式将列添加到DataGridView,然后绑定到列表。默认情况下,列的SortMode是自动的。但是,当我运行我的应用程序时,单击标题无效。向上/向下箭头未显示。从阅读MSDN,关于自动排序的说法并不多。他们详细介绍了程序化排序。所以,我假设自动方式应该很容易。 MSDN继续说“除非列标题用于选择,单击列标题会自动按此列对DataGridView进行排序,并显示一个指示排序顺序的字形。”这到底是什么意思呢?我可以设置与排序冲突的网格属性吗?我错过了什么?
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;
答案 0 :(得分:21)
我们使用BindingListView将List&lt; T&gt;绑定到DataGridViews,它对我们来说非常有效。
这是一个创建对象列表视图的简单示例(在C#中):
List<Customer> customers = GetCustomers();
BindingListView<Customer> view = new BindingListView<Customer>(customers);
dataGridView1.DataSource = view;
查看https://stackoverflow.com/a/17952576/116891以获取有关DGV排序和数据绑定的更多详细信息。
如果您不想添加繁重的内容,可以尝试SortableBindingList<T>(with updates)的此实现。
根据他们的基准测试,两者都让你开箱即用,BindingListView甚至比DataViews更快。
答案 1 :(得分:2)
编辑:自发布以来,我发现SortableBindingList(Of T)
的这种实现是最佳解决方案,除了我将第52行修改为IEnumerable
而不是ICollection
,因为构造函数是无论如何都要施展它。
可以在不实现自定义类的情况下对DataGridView
进行排序。请注意,我的代码是在VB.NET中,但它应该翻译。必须先将数据添加到grid.Rows
:
For Each item In dataList
grid.Rows.Add(item.Id, item.Name, item.DateProperty)
Next
然后实现这些事件处理程序。第二个是确保日期排序工作。如果您的网格具有可排序的日期列,则只需要它:
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
需要注意的一点是,只有添加到行中的属性才是结果对象的一部分,因为没有绑定。为了维护整个对象,您需要为每个属性添加列,为任何不应显示的列设置列Visible = False
。
答案 2 :(得分:1)
我想我找到了答案。我的数据源实现了IList<T>
。显然它需要实现IBindingList<T>
。不幸的是,我无法测试这个。