在列表< T>中排序Datagridview数据源其中T是匿名的 [英] Sorting Datagridview datasource on List<T> where T is anonymous

查看:135
本文介绍了在列表< T>中排序Datagridview数据源其中T是匿名的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

一个比较简单的问题。我有一个datagridview,它所做的是显示统计信息。没有行的编辑/添加/删除。 datagridview绑定到列表。所有我想要实现的是让用户能够对列进行排序。

 类市场
{
public int Location {get; set;}
public float Value {get; set;}
// ...
}
class City
{
public String Name {get; set;}
// ...
}

列表<市场> _市场
列表< City> _cities;
//列表已填充。

dataGridView1.DataSource = _markets.Select(market =>
new {_cities [market.Location] .Name,market.Value})。ToList();

如预期的那样,列不可排序,但显示的信息是所需的。我的问题是如何使DataGridView基于列类型排序最少,代码数量最少,因为代码将被多次使用。



应用程序用于使用具有视图的DataBase。然后,这些视图填充了DataGridViews。意见仍然存在,所以可能的解决方案可能是:

  DataBase.ViewMarketValue temp = new DataBase.ViewMarketValue()

_markets.ForEach(market => temp.AddViewMarketValueRow(_cities [market.Location] .Name,market.Value);
dataGridView1.DataSource = temp;

这将导致所需的:具有所有信息的datagridview可排序,唯一的问题是使用视图似乎是错误的在这方面,那么该怎么办?

解决方案

为了能够在 DataGridView ,需要一个实现 IBindingListView 的集合,在BCL中,实现此接口的唯一类是 DataView BindingSource (但后者仅支持排序,如果底层数据源也支持它)。



所以,你有几个选择:




  • 创建一个 DataTable 来保存数据,并将其绑定到 DataGridView (它将实际绑定到 DataTable DefaultView

  • 创建自己的实现的集合类 IBindingListView

  • 使用现有的实现,如 AdvancedList< T> 这篇文章。您还需要添加一个构造函数来从查询结果构建列表:

      public AdvancedList(IEnumerable< T>集合)
    {
    foreach(集合中的var项目)
    {
    添加(项目);
    }
    }




由于您的查询结果是匿名类型,您将无法直接调用构造函数。解决问题的最简单方法是通过创建一个将创建列表的通用方法来利用类型推断。为方便起见,您可以创建一个扩展方法:

  public static AdvancedList< T> ToAdvancedList< T>(该IEnumerable< T>源)
{
返回新的AdvancedList< T(源);
}

然后您可以使用它:

  dataGridView1.DataSource = _markets.Select(market => 
new {_cities [market.Location] .Name,market.Value})。ToAdvancedList ();


A relatively simple question. I have a datagridview, which all it does is displays statistics. There is no editing/adding/deleting of rows. The datagridview is bound to a List. All I want to achieve is to have the user be able to sort the columns.

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();

As expected, the columns are not sortable, but the information that is displayed is what is wanted. My question is how to make the DataGridView sort based on the column type with the least complicated and least amount of code, as the code will be used multiple times throughout.

This application used to use a DataBase that had views. These views then populated the DataGridViews. The views are still around, so a possible solution could be:

DataBase.ViewMarketValue temp = new DataBase.ViewMarketValue()

_markets.ForEach(market => temp.AddViewMarketValueRow(_cities[market.Location].Name, market.Value);
dataGridView1.DataSource = temp;

This results in the desired: a datagridview that has all the information and it is sortable. The only problem is that it seems wrong to use views in this aspect. So what should I do?

解决方案

In order to be able to sort the data automatically in the DataGridView, you need a collection that implements IBindingListView. In the BCL, the only classes that implement this interface are DataView and BindingSource (but the latter only supports sorting if the underlying datasource supports it too).

So, you have several options:

  • create a DataTable to hold the data, and bind it to the DataGridView (it will actually bind to the DefaultView of the DataTable)
  • create your own collection class that implements IBindingListView
  • use an existing implementation, like the AdvancedList<T> class posted by Marc Gravell in this post. You will also need to add a constructor to build the list from the result of your query:

    public AdvancedList(IEnumerable<T> collection)
    {
        foreach (var item in collection)
        {
            Add(item);
        }
    }
    

Since the result of your query is an anonymous type, you won't be able to call the constructor directly. The easiest way to work around the issue is to take advantage of type inference, by creating a generic method that will create the list. For convenience, you can create it as an extension method:

public static AdvancedList<T> ToAdvancedList<T>(this IEnumerable<T> source)
{
    return new AdvancedList<T>(source);
}

You can then use it like that:

dataGridView1.DataSource = _markets.Select(market => 
    new { _cities[market.Location].Name, market.Value}).ToAdvancedList();

这篇关于在列表&lt; T&gt;中排序Datagridview数据源其中T是匿名的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆