【问题标题】:Allow user to sort columns from a LINQ query in a DataGridView允许用户对 DataGridView 中的 LINQ 查询中的列进行排序
【发布时间】:2009-01-28 14:44:54
【问题描述】:

我不太清楚如何允许在运行时填充的 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

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

谢谢!

【问题讨论】:

    标签: .net linq data-binding datagridview bindingsource


    【解决方案1】:

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

    有许多实施示例可供选择,实施起来非常简单。 Here is an example 在 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
    

    【讨论】:

      【解决方案2】:

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

      如果你想添加分页,显然这不会很好。

      【讨论】:

        【解决方案3】:

        您需要以 AsEnumerable() 的形式获取查询结果。

        Dim QueryReOrder = (From Q In Query _ 其中 ((0 - Q.Qualifier) / cmbTSStakeValue.Text)

        我应该提到我通常使用 C#,因此您可能需要稍微改变语法。

        【讨论】:

        • 当查询数据来自内存中的 ICollection 时,这可以将数据放入 DataGridView,但列标题仍然不可排序。要使它们可排序,您需要像 Brian 描述的那样使用 SortableBindingList。
        【解决方案4】:

        是的,所以我为此苦苦挣扎了一段时间。关于为每个类创建自定义通用 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 绑定到该 generic DataTable 对象。

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

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

        向编写上述函数以从 IEnumerable 转换为 DataTable 的 Alberto Poblacion 的道具:function thread

        c# datagridview sortable linq to ADO.NET

        【讨论】:

          【解决方案5】:

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

          Sortable Binding List for custom data objects

          我几乎可以逐字使用这个例子。

          【讨论】:

            【解决方案6】:

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

            然后

            var yourLinqList = ...;

            MySortableBindingList sortList = new MySortableBindingList(yourLinqList);

            dataGridView1.DataSource = sortList;

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

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2010-10-15
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2016-10-27
              • 2022-12-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多