一个相对简单的问题.我有一个datagridview,它所做的只是显示统计信息.没有编辑/添加/删除行. datagridview绑定到List.我想要实现的是让用户能够对列进行排序.
class Market { public int Location {get;set;} public float Value {get;set;} //... } class City { public String Name {get;set;} //... } List<Market> _markets; List<City> _cities; //Lists are populated. dataGridView1.DataSource = _markets.Select(market => new { _cities[market.Location].Name,market.Value}).ToList();
正如所料,列不可排序,但显示的信息是您想要的.我的问题是如何根据具有最少复杂和最少代码量的列类型进行DataGridView排序,因为代码将在整个过程中多次使用.
此应用程序用于使用具有视图的数据库.然后这些视图填充DataGridViews.视图仍然存在,因此可能的解决方案可能是:
DataBase.ViewMarketValue temp = new DataBase.ViewMarketValue() _markets.ForEach(market => temp.AddViewMarketValueRow(_cities[market.Location].Name,market.Value); dataGridView1.DataSource = temp;
这导致了所需的:具有所有信息的数据网格视图,并且它是可排序的.唯一的问题是在这方面使用视图似乎是错误的.所以我该怎么做?
解决方法
为了能够在DataGridView中自动排序数据,您需要一个实现IBindingListView的集合.在BCL中,实现此接口的唯一类是DataView和BindingSource(但后者仅支持基础数据源支持的排序).
所以,你有几个选择:
>创建一个DataTable来保存数据,并将其绑定到DataGridView(它实际上将绑定到DataTable的DefaultView)
>创建自己的实现IBindingListView的集合类
>使用现有的实现,例如AdvancedList< T> Marc Gravell在this post发布的课程.您还需要添加一个构造函数来根据查询结果构建列表:
public AdvancedList(IEnumerable<T> collection) { foreach (var item in collection) { Add(item); } }
由于查询结果是匿名类型,因此您无法直接调用构造函数.解决该问题的最简单方法是通过创建将创建列表的通用方法来利用类型推断.为方便起见,您可以将其创建为扩展方法:
public static AdvancedList<T> ToAdvancedList<T>(this IEnumerable<T> source) { return new AdvancedList<T>(source); }
然后你就可以这样使用它:
dataGridView1.DataSource = _markets.Select(market => new { _cities[market.Location].Name,market.Value}).ToAdvancedList();