Разрешить пользователю сортировать столбцы из запроса LINQ в DataGridView

Я не могу понять, как разрешить DataGridView, заполняемый во время выполнения, сортировать (когда пользователи нажимают на заголовки столбцов), где запрос LINQ из XML является источником данных, через 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

Есть ли простое решение, которое позволит пользователю сортировать эти значения, щелкнув заголовок столбца?

Спасибо!


person user57087    schedule 28.01.2009    source источник


Ответы (6)


Вам нужно получить результаты запроса LINQ во что-то, поддерживающее функцию сортировки. Обычно это делается путем создания класса из BindingList и реализации функциональных возможностей Sorting Core в производном классе.

Есть много примеров реализаций на выбор, и это довольно простая вещь для реализации. Вот пример того, как это сделать в 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
person Brian ONeil    schedule 11.05.2009

Мой подход по умолчанию — скопировать все в DataTable и привязать к нему DataGridView.

Очевидно, что это не сработает, если вы хотите добавить пейджинг.

person Lennaert    schedule 04.02.2009

Вам нужно получить результаты запроса как AsEnumerable().

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

Я должен упомянуть, что обычно я работаю на C#, поэтому, возможно, вам придется немного изменить синтаксис.

person Matthew Talbert    schedule 12.03.2009
comment
Когда данные запроса поступают из ICollection в памяти, это работает для получения данных в DataGridView, но заголовки столбцов по-прежнему не поддаются сортировке. Чтобы сделать их сортируемыми, вам нужно сделать что-то вроде описанного Брайаном с SortableBindingList. - person Eric; 14.12.2009

Да, так что я боролся с этим некоторое время. Все те же ответы о создании собственного универсального списка 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: поток функций

C# datagridview sortable linq to ADO.NET

person CodeSlinger    schedule 17.11.2010

Еще одна ссылка, которая дает полный пример того, как создать SortableBindingList, как описано в Ответ Брайана ONeil можно найти здесь:

Сортируемый список привязок для пользовательских объектов данных

Я смог использовать этот пример почти дословно.

person Eric    schedule 14.12.2009

используйте только класс MySortableBindingList на этой странице Sortable-BindingList-

тогда

вар вашLinqList = ...;

MySortableBindingList sortList = новый MySortableBindingList (вашLinqList);

dataGridView1.DataSource = sortList;

тогда ваш dataGridView должен быть отсортирован при щелчке заголовка ячейки.

person Kemal Duran    schedule 06.08.2013