65.9K
CodeProject 正在变化。 阅读更多。
Home

多列过滤 GridView 和有效分页(可搜索 GridView)

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.75/5 (28投票s)

2014 年 2 月 1 日

CPOL

3分钟阅读

viewsIcon

124137

downloadIcon

5068

具有多列筛选功能的 ASP.NET 自定义 GridView

 

下载 SearchableGridView.zip

引言

这里我扩展了 ASP.NET Grid View,添加了内置的筛选和分页功能,并具有有效的搜索功能。它只会从数据库加载当前页面所需的数据(例如,一次每页 10 条记录),当用户导航到下一页时,它只会加载所需的下一页数据。该网格将在运行时动态创建文本框以实现筛选功能。

背景

我过去经常在我的 ASP.NET 页面中使用类似的代码来实现搜索/筛选功能。它工作得很好,但是一遍又一遍地重写代码会浪费我很多时间,而且对齐文本框和其他相关控件是一个大问题。因此,我想创建一个可重用的控件,它可以自己完成所有工作。我只用 SQL Server 2008 测试过该网格视图。我认为任何人都可以更改存储过程中的语法和连接,以便能够与其他数据库一起使用。

Using the Code

我扩展了 System.Web.UI.WebControls.BoundField 类,并添加了名为 SearchExpression 的属性,用于保存将直接传递到 SQL 存储过程的搜索表达式。

public class SearchBoundField : System.Web.UI.WebControls.BoundField
    {
        private const string SEARCH_EXPRESSION = "SearchExpression";
        public string SearchExpression
        {
            get
            {
                if (this.ViewState[SEARCH_EXPRESSION] == null)
                {
                    this.ViewState[SEARCH_EXPRESSION] = this.DataField;
                }
 
                return (string)this.ViewState[SEARCH_EXPRESSION];
            }
            set
            {
                this.ViewState[SEARCH_EXPRESSION] = value;
            }
        }
    } 

该控件将在网格视图的每列顶部创建文本框,并在最后一列创建一些额外的按钮,如“筛选”、“取消筛选”。当调用 GridView.DataBound() 时,它将创建带有页脚行的行,该页脚行将包含导航控制框和记录状态标签。

在带有导航控件的页脚行中,我们可以看到记录总数、当前页码和总页数。这指的是将包含 TotalRows 列的数据源。

我们可以通过单击导航按钮导航到下一页、上一页、最后一页、第一页以及指定的页面。

以下是使用的属性

public bool ShowEmptyFooter 

ShowEmptyFooter:用于隐藏/显示没有记录时的空页脚。

public int TotalSearchRecords 

TotalSearchRecords 将保存当前搜索存在的记录总数。

public int TotalSearchPages 

TotalSearchPages 保存当前搜索存在的总页数。通常,这将使用 TotalSearchRecords PageSize 进行计算。

public int? CurrentSearchPageNo 

CurrentSearchPageNo 将保存当前页码。当用户浏览页面时,它会发生变化。当用户单击页面更改按钮时,数据将从数据库中提取并重建网格。

public bool SelectableDataRow 

这是一个重要的属性,用于指定网格是否能够接受行单击事件。如果它是 true,那么在构建网格时,以下代码将被添加到 OnRowDataBound 中

protected override void OnRowDataBound(GridViewRowEventArgs e)
{
    base.OnRowDataBound(e);
    if (SelectableDataRow == true)
    {
        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            e.Row.Attributes.Add("onmouseover", "this.style.backgroundColor='#ceedfc'");
            e.Row.Attributes.Add("onmouseout", "this.style.backgroundColor=''");
            e.Row.Attributes.Add("style", "cursor:pointer;");
            e.Row.Attributes.Add("onclick", Page.ClientScript.
        GetPostBackClientHyperlink(this, "Select$" + e.Row.RowIndex));
        }
    }
    //Initilize search filter data
    InitSearchFilterData();
}
public DataTable SearchFilters 

上述属性用于存储 SearchFilters DataTable,该表将在每次搜索调用发生时创建,将创建一个带有 SearchString Value 的数据表,并将其传递到 SQL 存储过程,存储过程将解析 Datatable 并构建动态 SQL 查询并执行它。

public string CurrentSortExpression
public string CurrentSortDirection  

以上两个属性将用于存储当前排序表达式和排序方向,用于传递给 SQL 过程以构建查询。当用户单击列标题时,属性的值将发生变化。

当用户单击筛选按钮时,将发生 FilterButtonClick 事件,我们必须在我们的前端处理该事件,如下所示

public void sgvSearchClientMaster_FilterButtonClick(object sender, SearchGridEventArgs e)
        {
            FilterToNthPage(e.SearchFilterValues, 
        sgvSearchClientMaster.CurrentSortExpression,
        sgvSearchClientMaster.CurrentSortDirection, 1);
        } 

当用户单击任何一个导航按钮时,将发生 NavigationButtonClick 事件,我们必须像下面的代码一样处理它

       public void sgvSearchClientMaster_NavigationButtonClick(object sender, NavigationButtonEventArgs e)
{
    if (e.NavigationButtonsType == NavigationButtonsTypes.GoFirst)
    {
        FilterToNthPage(sgvSearchClientMaster.SearchFilters, 
            sgvSearchClientMaster.CurrentSortExpression, 
            sgvSearchClientMaster.CurrentSortDirection, 1);
    }
    else if (e.NavigationButtonsType == NavigationButtonsTypes.GoLast)
    {
        FilterToNthPage(sgvSearchClientMaster.SearchFilters,
            sgvSearchClientMaster.CurrentSortExpression,
            sgvSearchClientMaster.CurrentSortDirection,
            sgvSearchClientMaster.TotalSearchPages);
    }
    else if (e.NavigationButtonsType == NavigationButtonsTypes.GoNext)
    {
        if (sgvSearchClientMaster.CurrentSearchPageNo < sgvSearchClientMaster.TotalSearchPages)
        {
            FilterToNthPage(sgvSearchClientMaster.SearchFilters,
                sgvSearchClientMaster.CurrentSortExpression,
                sgvSearchClientMaster.CurrentSortDirection,
                (int)sgvSearchClientMaster.CurrentSearchPageNo + 1);
        }
    }
    else if (e.NavigationButtonsType == NavigationButtonsTypes.GoPrevious)
    {
        if (sgvSearchClientMaster.CurrentSearchPageNo > 1)
        {
            FilterToNthPage(sgvSearchClientMaster.SearchFilters,
                sgvSearchClientMaster.CurrentSortExpression, 
                sgvSearchClientMaster.CurrentSortDirection, 
                (int)sgvSearchClientMaster.CurrentSearchPageNo - 1);
        }
    }
    else if (e.NavigationButtonsType == NavigationButtonsTypes.GoToPage)
    {
        FilterToNthPage(sgvSearchClientMaster.SearchFilters,
            sgvSearchClientMaster.CurrentSortExpression, 
            sgvSearchClientMaster.CurrentSortDirection, 
            (int)e.PageIndex);
    }
} 

我们可以使用以下代码将 DataTable 传递到 SQL Server

SqlParameter tvpParam = cmd.Parameters.AddWithValue(SQLTableVariableName, SearchFilterValues);
tvpParam.SqlDbType = SqlDbType.Structured;  

添加了 git 存储库,您可以克隆并贡献 https://bitbucket.org/sukeshchand/searchable-grid-view

© . All rights reserved.