切换数据源后AdvancedDataGridView排序与筛选功能失效问题求助
解决AdvancedDataGridView排序筛选失效的问题
这个问题我之前帮不少开发者解决过——核心原因是你替换数据源的方式破坏了AdvancedDataGridView依赖的数据源接口支持:
- 当你用
TableAdapter.Fill填充DataSet的CustomersTransactions表时,BindingSource绑定的是DataTable.DefaultView,它实现了IBindingListView接口,而AdvancedDataGridView的排序、筛选功能正是依赖这个接口提供的能力。 - 但你用LINQ返回的
List<CustomersTransactions>并没有实现IBindingListView,所以控件的高级功能直接失效了。
下面给你两种简单可行的解决方案:
方案一:用DataView筛选(推荐,和原有工作流兼容)
直接利用已填充的DataTable,通过DataView.RowFilter来过滤数据,不需要替换BindingSource的数据源:
private void CustomerComboBox_SelectionChangeCommitted(object sender, EventArgs e) { // 先确保数据已完整填充(你原有的代码) this.customersTransactionsTableAdapter.Fill(this.akDbDataSet.CustomersTransactions); // 绑定DataView到BindingSource(如果之前没绑定的话) if (!(this.customersTransactionsBindingSource.DataSource is DataView)) { this.customersTransactionsBindingSource.DataSource = this.akDbDataSet.CustomersTransactions.DefaultView; } // 设置筛选条件,字符串类型的CustomerId需要加单引号:'customerId' this.akDbDataSet.CustomersTransactions.DefaultView.RowFilter = $"CustomerId = {customerId}"; }
这样BindingSource始终绑定的是支持IBindingListView的DataView,排序和筛选功能就能正常工作,同时也能实现按选中客户过滤数据的需求。
方案二:将LINQ结果转为DataTable绑定
如果你更倾向于用LINQ从数据库直接过滤,可以把LINQ查询结果转为DataTable,再绑定它的DefaultView:
首先添加一个将IEnumerable转为DataTable的扩展方法:
using System.Reflection; public static class EnumerableExtensions { public static DataTable ToDataTable<T>(this IEnumerable<T> items) { var dataTable = new DataTable(typeof(T).Name); PropertyInfo[] props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance); // 创建DataTable列 foreach (var prop in props) { var columnType = Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType; dataTable.Columns.Add(prop.Name, columnType); } // 填充数据行 foreach (var item in items) { object[] values = new object[props.Length]; for (int i = 0; i < props.Length; i++) { values[i] = props[i].GetValue(item) ?? DBNull.Value; } dataTable.Rows.Add(values); } return dataTable; } }
然后在事件中使用:
private void CustomerComboBox_SelectionChangeCommitted(object sender, EventArgs e) { // 用LINQ过滤数据 var filteredTransactions = dbContext.CustomersTransactions .Where(t => t.CustomerId.Equals(customerId)) .ToList(); // 转为DataTable并绑定DefaultView var filteredTable = filteredTransactions.ToDataTable(); this.customersTransactionsBindingSource.DataSource = filteredTable.DefaultView; }
这种方式也能让BindingSource绑定到支持IBindingListView的数据源,恢复排序和筛选功能。
内容的提问来源于stack exchange,提问作者Khalil
相关产品推荐
相关产品推荐

