是否可以在GridView上进行自定义排序

时间:2021-11-06 07:41:24

I need to sort a GridView (Not DataGridView, it's not the same thing) that is in need of a complex sort and I don't know how it can be done. I have two column, one containing a date and another containing a priority.

我需要对需要复杂排序的GridView(Not DataGridView,它不是同一件事)进行排序,我不知道它是如何完成的。我有两列,一列包含日期,另一列包含优先级。

If the date is lesser or equal to today's date. I want to order by priority first, then by date. If the date is greater than today's date, I want to order by date first, then by priority.

如果日期小于或等于今天的日期。我想首先按优先顺序排序,然后按日期排序。如果日期大于今天的日期,我想先按日期排序,然后按优先顺序排序。

Suppose totay is 2010-jan-13, some data ordered this way could look like these

假设总计是2010年1月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

Is there anyway to sort a grid view mannually or by passing a compare functor?

无论如何,还是通过手动或通过传递比较仿函数来对网格视图进行排序?

edit : The datasource is a DataTable.

编辑:数据源是DataTable。

4 个解决方案

#1


3  

You need to sort your data source, not the GridView. (Tell us your data source and we can help. Is it a DataTable, SqlDataSource, business objects?)

您需要对数据源进行排序,而不是GridView。 (告诉我们您的数据源,我们可以提供帮助。它是DataTable,SqlDataSource,业务对象吗?)

From Sorting Data in a GridView Web Server Control at http://msdn.microsoft.com/en-us/library/hwf94875.aspx.

从GridView Web服务器控件中的数据排序,网址为http://msdn.microsoft.com/en-us/library/hwf94875.aspx。

Custom Sorting

If the default sort behavior is not adequate for your requirements, you can customize the grid's sorting behavior. The basic technique for custom sorting is to handle the Sorting event. In the handler, you can do the following:

如果默认排序行为不足以满足您的要求,则可以自定义网格的排序行为。自定义排序的基本技术是处理Sorting事件。在处理程序中,您可以执行以下操作:

  • Customize the sort expression that is passed to the data source control. By default, the sort expression is the name of a single column. You can modify the sort expression in the event handler. For example, if you want to sort by two columns, you can create a sort expression that includes both. You can then pass the modified sort expression to the data source control. For more information, see the GridViewSortEventArgs..::.SortExpression property.

    自定义传递给数据源控件的排序表达式。默认情况下,排序表达式是单个列的名称。您可以在事件处理程序中修改排序表达式。例如,如果要按两列排序,则可以创建包含两者的排序表达式。然后,您可以将修改后的排序表达式传递给数据源控件。有关更多信息,请参阅GridViewSortEventArgs .. ::。SortExpression属性。

  • Create your own sorting logic. For example, if you are working with a data source that does not support sorting, you can perform the sort in your own code and then bind the grid to the sorted data.

    创建自己的排序逻辑。例如,如果您正在使用不支持排序的数据源,则可以在自己的代码中执行排序,然后将网格绑定到排序数据。

Sort Example (Not Tested and Not Using LINQ [on purpose])

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)

#2


0  

Salut Mathieu,

Assuming you are using a DataSource and each element is a class (instead of say, a datarow), you could implement IComparable to your class. It adds the CompareTo method in which you decide how each element compares to each other.

假设您正在使用DataSource并且每个元素都是一个类(而不是数据行),您可以将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");
    }
}    

#3


0  

Yes, You can do it. Here's how you do that.

是的,你可以做到。这是你如何做到的。

Assuming you have a GridView which calls for records from a BusinessLayer method. I will take example of UserManager as business-layer proxy class.

假设您有一个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;
        }
    }

Look at this line of code in over-loaded GetUsers method.

在过载的GetUsers方法中查看这行代码。

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

I have written a Generic Comparer implementation for my business objects. EntityComparer is just a generic class that implements IComparer interface. You can write your own Comparer implementation [that implements IComparer interface] and call it as the code above.

我为业务对象编写了Generic Comparer实现。 EntityComparer只是一个实现IComparer接口的泛型类。您可以编写自己的Comparer实现[实现IComparer接口]并将其称为上面的代码。

Here's how my GridView looks like..

这是我的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>

Also note that GridView will pass the sortExpression upon postback and call the overloaded method.

另请注意,GridView将在回发时传递sortExpression并调用重载方法。

#4


-1  

Sort procedure of dataGrinView uses Sort procedure of data source. To manually sort data create class that implements IBindingListView, implement it sort method like you want and use this class as DataSource in DataGridView

dataGrinView的排序程序使用数据源的Sort程序。要手动排序实现IBindingListView的数据创建类,请按照您的意愿实现它的排序方法,并在DataGridView中将此类用作DataSource

#1


3  

You need to sort your data source, not the GridView. (Tell us your data source and we can help. Is it a DataTable, SqlDataSource, business objects?)

您需要对数据源进行排序,而不是GridView。 (告诉我们您的数据源,我们可以提供帮助。它是DataTable,SqlDataSource,业务对象吗?)

From Sorting Data in a GridView Web Server Control at http://msdn.microsoft.com/en-us/library/hwf94875.aspx.

从GridView Web服务器控件中的数据排序,网址为http://msdn.microsoft.com/en-us/library/hwf94875.aspx。

Custom Sorting

If the default sort behavior is not adequate for your requirements, you can customize the grid's sorting behavior. The basic technique for custom sorting is to handle the Sorting event. In the handler, you can do the following:

如果默认排序行为不足以满足您的要求,则可以自定义网格的排序行为。自定义排序的基本技术是处理Sorting事件。在处理程序中,您可以执行以下操作:

  • Customize the sort expression that is passed to the data source control. By default, the sort expression is the name of a single column. You can modify the sort expression in the event handler. For example, if you want to sort by two columns, you can create a sort expression that includes both. You can then pass the modified sort expression to the data source control. For more information, see the GridViewSortEventArgs..::.SortExpression property.

    自定义传递给数据源控件的排序表达式。默认情况下,排序表达式是单个列的名称。您可以在事件处理程序中修改排序表达式。例如,如果要按两列排序,则可以创建包含两者的排序表达式。然后,您可以将修改后的排序表达式传递给数据源控件。有关更多信息,请参阅GridViewSortEventArgs .. ::。SortExpression属性。

  • Create your own sorting logic. For example, if you are working with a data source that does not support sorting, you can perform the sort in your own code and then bind the grid to the sorted data.

    创建自己的排序逻辑。例如,如果您正在使用不支持排序的数据源,则可以在自己的代码中执行排序,然后将网格绑定到排序数据。

Sort Example (Not Tested and Not Using LINQ [on purpose])

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)

#2


0  

Salut Mathieu,

Assuming you are using a DataSource and each element is a class (instead of say, a datarow), you could implement IComparable to your class. It adds the CompareTo method in which you decide how each element compares to each other.

假设您正在使用DataSource并且每个元素都是一个类(而不是数据行),您可以将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");
    }
}    

#3


0  

Yes, You can do it. Here's how you do that.

是的,你可以做到。这是你如何做到的。

Assuming you have a GridView which calls for records from a BusinessLayer method. I will take example of UserManager as business-layer proxy class.

假设您有一个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;
        }
    }

Look at this line of code in over-loaded GetUsers method.

在过载的GetUsers方法中查看这行代码。

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

I have written a Generic Comparer implementation for my business objects. EntityComparer is just a generic class that implements IComparer interface. You can write your own Comparer implementation [that implements IComparer interface] and call it as the code above.

我为业务对象编写了Generic Comparer实现。 EntityComparer只是一个实现IComparer接口的泛型类。您可以编写自己的Comparer实现[实现IComparer接口]并将其称为上面的代码。

Here's how my GridView looks like..

这是我的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>

Also note that GridView will pass the sortExpression upon postback and call the overloaded method.

另请注意,GridView将在回发时传递sortExpression并调用重载方法。

#4


-1  

Sort procedure of dataGrinView uses Sort procedure of data source. To manually sort data create class that implements IBindingListView, implement it sort method like you want and use this class as DataSource in DataGridView

dataGrinView的排序程序使用数据源的Sort程序。要手动排序实现IBindingListView的数据创建类,请按照您的意愿实现它的排序方法,并在DataGridView中将此类用作DataSource