Можно ли сделать пользовательскую сортировку на GridView - PullRequest
7 голосов
/ 13 января 2010

Мне нужно отсортировать GridView (не DataGridView, это не то же самое), который нуждается в сложной сортировке, и я не знаю, как это можно сделать. У меня есть два столбца, один с датой, а другой с приоритетом.

Если дата меньше или равна сегодняшней дате. Я хочу сделать заказ сначала по приоритету, а затем по дате. Если дата больше сегодняшней, я хочу сначала отсортировать по дате, а затем по приоритету.

Предположим, что это 2010-янв-13, некоторые данные, упорядоченные таким образом, могут выглядеть следующим образом

   date       priority  Explanation
-----------   --------  --------------------------------------------
2010-jan-13      3      This comes first because it has the higer priority of all items whith a date <= today
2010-jan-12      2      Since this items and the next have the same priority they're ordered by date
2010-jan-13      2
2010-jan-14      5      This item and the followings have date > today, so they are ordered by date then by priority.
2010-jan-14      0
2010-jan-15      5
2010-jan-16      5

Есть ли способ сортировки вида сетки вручную или с помощью функтора сравнения?

редактировать: Источником данных является DataTable.

Ответы [ 4 ]

3 голосов
/ 14 января 2010

Вам нужно отсортировать источник данных, а не GridView. (Сообщите нам свой источник данных, и мы можем помочь. Это DataTable, SqlDataSource, бизнес-объекты?)

С Сортировка данных в элементе управления веб-сервера GridView при http://msdn.microsoft.com/en-us/library/hwf94875.aspx.

Выборочная сортировка

Если поведение сортировки по умолчанию не соответствует вашим требованиям, вы можете настроить режим сортировки сетки. Основная техника для пользовательской сортировки - обработка события Sorting. В обработчике вы можете сделать следующее:

  • Настройка выражения сортировки, которое передается в элемент управления источником данных. По умолчанию выражение сортировки - это имя одного столбца. Вы можете изменить выражение сортировки в обработчике событий. Например, если вы хотите отсортировать по двум столбцам, вы можете создать выражение сортировки, которое включает оба. Затем вы можете передать измененное выражение сортировки в элемент управления источником данных. Для получения дополнительной информации см. Свойство GridViewSortEventArgs .. ::. SortExpression.

  • Создайте собственную логику сортировки. Например, если вы работаете с источником данных, который не поддерживает сортировку, вы можете выполнить сортировку в своем собственном коде, а затем привязать сетку к отсортированным данным.

Пример сортировки (не проверено и не используется LINQ [специально))

Dim oDataSet As DataSet = GatherDataSet()
Dim oDataTable As DataTable = oDataSet.Tables(0)
Dim oSort1 As New DataView(oDataTable, "Date > #2010/01/13#", "Date, Priority", DataViewRowState.CurrentRows)
Dim oSort2 As New DataView(oDataTable, "Date <= #2010/01/13#", "Priority, Date", DataViewRowState.CurrentRows)
Dim oGridDataTable As DataTable
oGridDataTable = oSort1.ToTable
oGridDataTable.Merge(oSort2.ToTable)

oGridView.DataSource = oGridDataTable

'...
'you can then merge any changes back into the data set, if needed
oDataSet.Merge(oGridDataTable)
0 голосов
/ 18 января 2010

Да, вы можете сделать это. Вот как ты это делаешь.

Предполагается, что у вас есть GridView, который вызывает записи из метода BusinessLayer. Я возьму пример UserManager как прокси-класс бизнес-уровня.

    [DataObjectAttribute()]
    public static class UserManager
    {
        [DataObjectMethod(DataObjectMethodType.Select, true)]
        public static UserCollection GetUsers()
        {
            return UserDB.GetAll();
        }

        [DataObjectMethod(DataObjectMethodType.Select, false)]
        public static UserCollection GetUsers(string sortExpression)
        {
            UserCollection users = UserDB.GetAll();
            users.Sort(new EntityComparer<User>(sortExpression));
            return users;
        }
    }

Посмотрите на эту строку кода в перегруженном методе GetUsers.

users.Sort(new EntityComparer<User>(sortExpression));

Я написал реализацию Generic Comparer для своих бизнес-объектов. EntityComparer - это просто универсальный класс, который реализует интерфейс IComparer. Вы можете написать свою собственную реализацию Comparer [которая реализует интерфейс IComparer] и вызвать ее как приведенный выше код.

Вот как выглядит мой GridView ..

         <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" 
            DataSourceID="ObjectDataSource1">
            <Columns>
                <asp:BoundField DataField="Id" HeaderText="Id" SortExpression="Id" />
                <asp:BoundField DataField="UserName" HeaderText="UserName" 
                    SortExpression="UserName" />
                <asp:BoundField DataField="Password" HeaderText="Password" 
                    SortExpression="Password" />
                <asp:BoundField DataField="Name" HeaderText="Name" SortExpression="Name" />
                <asp:BoundField DataField="Email" HeaderText="Email" SortExpression="Email" />
                <asp:BoundField DataField="CompanyName" HeaderText="CompanyName" 
                    SortExpression="CompanyName" />
            </Columns>
        </asp:GridView>
        <asp:ObjectDataSource ID="ObjectDataSource1" runat="server" 
            OldValuesParameterFormatString="original_{0}" SelectMethod="GetUsers" 
            TypeName="FilePark.BusinessLayer.UserManager"></asp:ObjectDataSource>

Также обратите внимание, что GridView передаст sortExpression при обратной передаче и вызовет перегруженный метод.

0 голосов
/ 13 января 2010

Салют Матье,

Предполагая, что вы используете DataSource и каждый элемент является классом (вместо, скажем, datarow), вы можете реализовать IComparable для вашего класса. Он добавляет метод CompareTo, в котором вы решаете, как каждый элемент сравнивается друг с другом.

class DatePriority: IComparable
{
    private DateTime date;
    public DateTime Date
    {
        get { return date; }
    }
    private int priority;
    public int Priority
    {
        get { return priority; }
    }

    public DatePriority(DateTime date, int priority)
    {
        this.date = date;
        this.priority = priority;
    }

    public int CompareTo(object obj)
    {
        if (obj is DatePriority)
        {
            DatePriority comparedDatePriority = obj as DatePriority;

            // Comparison logic
            // If the compared elements are today or before today, order by priority in descending order. Same priorities are ordered by date in ascending order
            // If the compared elements are for the future, order by date in ascending order. Same dates are order by priority in descending order
            if ((this.Date <= DateTime.Today && comparedDatePriority.Date <= DateTime.Today))
            {
                if (Priority == comparedDatePriority.Priority)
                    return Date.CompareTo(comparedDatePriority.Date);
                else
                    return -Priority.CompareTo(comparedDatePriority.Priority);
            }
            else
            {                    
                if (Date == comparedDatePriority.date)
                    return -Priority.CompareTo(comparedDatePriority.Priority); // Descending order
                else
                    return Date.CompareTo(comparedDatePriority.Date);
            }
        }
        throw new ArgumentException("Not a DatePriority");
    }
}    
0 голосов
/ 13 января 2010

Процедура сортировки dataGrinView использует процедуру сортировки источника данных. Чтобы вручную отсортировать данные, создайте класс, который реализует IBindingListView, реализуйте метод сортировки так, как вы хотите, и используйте этот класс как DataSource в DataGridView

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...