Разрешить пользователю сортировать столбцы из запроса LINQ в DataGridView - PullRequest
8 голосов
/ 28 января 2009

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

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

Спасибо!

Ответы [ 6 ]

5 голосов
/ 11 мая 2009

Вам нужно получить результаты запроса 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
3 голосов
/ 04 февраля 2009

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

Очевидно, что это не сработает, если вы захотите добавить подкачку.

2 голосов
/ 17 ноября 2010

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

2 голосов
/ 12 марта 2009

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

Dim QueryReOrder = (Из Q в запросе _ Где ((0 - Q.Qualifier) ​​/ cmbTSStakeValue.Text) <= 0,1 _ Order By Q.Qualifier По убыванию _ Выберите Q) .AsEnumerable () </p>

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

1 голос
/ 14 декабря 2009

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

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

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

0 голосов
/ 06 августа 2013

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

тогда

var yourLinqList = ...;

MySortableBindingList sortList = новый MySortableBindingList (yourLinqList);

dataGridView1.DataSource = sortList;

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

...