8

我无法完全弄清楚如何允许在运行时填充的 DataGridView 进行排序(当用户单击列标题时),其中来自 XML 查询的 LINQ 是 DataSource,通过 BindingSource。

    Dim QueryReOrder = From Q In Query _
                       Where ((0 - Q.Qualifier) / cmbTSStakeValue.Text) <= 0.1 _
                       Order By Q.Qualifier Descending _
                       Select Q

    Dim bs As New BindingSource
    bs.DataSource = QueryReOrder
    DGFindMatch.DataSource = bs

DataGridView 的一些属性是:

Sort            Nothing String
SortProperty                Nothing System.ComponentModel.PropertyDescriptor
SupportsAdvancedSorting         False   Boolean
SupportsChangeNotification      True    Boolean
SupportsFiltering           False   Boolean
SupportsSearching           False   Boolean
SupportsSorting             False   Boolean

是否有一个简单的解决方案允许用户通过单击列标题对这些值进行排序?

谢谢!

4

6 回答 6

5

您需要将 LINQ 查询的结果转换为支持排序功能的东西。这通常通过从 BindingList 派生一个类并在派生类中实现排序核心功能来完成。

有许多实现示例可供选择,而且实现起来非常简单。这是在 MSDN 上执行此操作的示例

实现此功能后,您只需将结果放入其中并将其用作数据源,并且网格应允许用户使用列进行排序。

    //I know that you asked the question in VB.NET but I don't know the syntax that well.
    public class SortableBindingList<T> : BindingList<T>
    {
         //override necessary sort core methods
    }

    SortableBindingList<string> list = new SortableBindingList<string>(QueryReOrder.ToList());

    //use list as your DataSource now
于 2009-05-11T03:03:29.010 回答
3

我的默认方法是将所有内容复制到 DataTable 并将 DataGridView 绑定到它。

显然,如果您想添加分页,那将无法正常工作。

于 2009-02-04T13:30:14.077 回答
2

是的,所以我为此挣扎了一段时间。关于为每个类创建自定义通用 IBindingList 的所有相同答案。如果网格视图中的列不是静态的,那将是一项疯狂的工作。我希望能够更改我的 linq 查询,而不必更改或更新实现自定义 IBindingList 的类。所以,这就是我所做的:

1)获取您的IEnumerable查询。

var query = from o in m_ds.Objective

        join ot in m_ds.ObjectiveType on o.ObjectiveTypeId equals ot.Id
        join dst in m_ds.DevelopmentStatusType on o.DevelopmentStatusTypeId equals dst.Id
        join rt in m_ds.ResultType on o.PrecedenceResultTypeId equals rt.Id

        select new
        {
            o.Id,
            type = ot.Description,
            precedence = rt.Description,
            o.Symbol,
            o.Title,
        };

2)将该IEnumerable结果集转换为DataTable

public static DataTable DataTableFromIEnumerable( IEnumerable ien )
{
    DataTable dt = new DataTable();
    foreach ( object obj in ien )
    {
        Type t = obj.GetType();
        PropertyInfo[] pis = t.GetProperties();
        if ( dt.Columns.Count == 0 )
        {
            foreach ( PropertyInfo pi in pis )
            {
                dt.Columns.Add( pi.Name, pi.PropertyType );
            }
        }

        DataRow dr = dt.NewRow();
        foreach ( PropertyInfo pi in pis )
        {
            object value = pi.GetValue( obj, null );
            dr[ pi.Name ] = value;
        }

        dt.Rows.Add( dr );
    }

    return dt;
}

3) 将您的DataGridView绑定到该通用 DataTable对象。

var query = SqlHelper.GetFilteredObjective();
var bs = new BindingSource();
bs.DataSource = Utils.DataTableFromIEnumerable( query );
dgvObjectives.DataSource = bs;

4) 就是这样。一个实用功能,你就完成了:)

向编写上述函数以从 IEnumerable 变为 DataTable 的 Alberto Poblacion 的道具: 函数线程

时间:2019-04-01 标签:c#datagridview sortable linq to ADO.NET

于 2010-11-17T20:29:48.940 回答
2

您需要将查询结果作为 AsEnumerable() 获取。

Dim QueryReOrder = (From Q In Query _ Where ((0 - Q.Qualifier) / cmbTSStakeValue.Text) <= 0.1 _ Order By Q.Qualifier Descending _ Select Q).AsEnumerable()

我应该提到我通常在 C# 中,所以你可能不得不稍微改变语法。

于 2009-03-12T17:28:17.190 回答
1

在此页面中仅使用 MySortableBindingList 类Implementing-a-Sortable-BindingList-

然后

var yourLinqList = ...;

MySortableBindingList sortList = new MySortableBindingList(yourLinqList);

dataGridView1.DataSource = 排序列表;

那么当单元格标题单击时,您的 dataGridView 必须进行排序。

于 2013-08-06T08:03:20.137 回答
1

可以在此处找到另一个链接,该链接提供了如何构造 SortableBindingList 的完整示例,如Brian ONeil 的回答中所述:

自定义数据对象的可排序绑定列表

我几乎可以一字不差地使用这个例子。

于 2009-12-14T18:41:23.350 回答