2013-01-15 77 views
0

我很难与这种情况下,希望有人可以帮助我澄清我失去了一步/逻辑。我尝试在线搜索,但找不到解决此问题的示例。PagedDataSource不能与上一页/下一页

我们正在设置一个搜索页面,当第一次加载显示一堆选项时(例如,文本框,复选框等)。用户将填写表格并将表格提交回自己。一旦返回,该页面将用用户选项构建并运行SQL查询(例如,SELECT ID FROM Customers WHERE Company ='Acme'AND AmtDue = 3),然后结果将显示出来。这部分工作正常。

崩溃的部分是当我试图添加分页时。结果集是绑定到Repeater的DataTable。我正在使用PagedDataSource来添加分页。分页对第一页非常有用,但对于后续页面而言,它不起作用。基本上,返回结果的下一页(例如SELECT ID FROM Customers WHERE Company ='Acme'AND AmtDue = 3),返回的结果是在追加用户的搜索选项之前的SQL查询(例如,SELECT ID FROM顾客)。

我认为我的基本问题是我不确定如何区分正常的Page.IsPostBack和通过结果进行分页。造成问题的原因是因为我不想重新构建表单数据,重建查询和重新查询数据库。

我在网上找到的例子涉及每次页面加载时重建的DataTable的分页(例如Not Page.IsPostBack)。

这里是我们的代码一个大致的轮廓:

Public dtCustomers As DataTable = New DataTable() 
Sub Page_Load(ByVal Sender As Object, ByVal E As EventArgs) Handles Me.Load 
    ' When the page first loads, show the search form with search options. 
    If Not Page.IsPostBack Then 
     ShowSearchForm() 
    ' Once the form is submitted, show the search results. 
    Else 
     ' ---------------------------------------- 
     ' This is the part that I'm having trouble with. How do I skip the following two steps (GatherFormData() and BuildDT()) when the user requests a subsequent page? 
     GatherFormData() 
     dtCustomers = BuildDT() 
     ' ---------------------------------------- 
     BindData() 
    End If 
End Sub 
Sub BindData() 
    Dim objPDS As PagedDataSource = New PagedDataSource() 
    objPDS.DataSource = dtCustomers.DefaultView 
    objPDS.AllowPaging = True 
    objPDS.PageSize = intNumPerPage 
    objPDS.CurrentPageIndex = Me.ViewState("_CurrentPage") 
    rptSearchResults.DataSource = objPDS 
End Sub 
' Subroutine called when the previous page button is pressed. 
Sub GoToPrevPage() 
    ' Set viewstate variable to the previous page. 
    Me.ViewState("_CurrentPage") -= 1 
    BindData() 
End Sub 
' Subroutine called when the next page button is pressed. 
Sub GoToNextPage() 
    ' Set viewstate variable to the next page. 
    Me.ViewState("_CurrentPage") += 1 
    BindData() 
End Sub 

注:据我所知,数据表将不得不被放入缓存或会话变量,但还没有决定是最好的方法。

请原谅代码大纲,但实际的代码是巨大的,所以简化是让它更容易处理问题的核心。

让我知道如果有任何不清楚。提前致谢!

回答

0

我假设你要将数据存储在会话/缓存中(我宁愿稍后,但可以将用户存储在会话中的用例) - 您可以将密钥存储在视图状态和存在的关键可以用来确定是否回传是用于分页的。例如,

if (ViewState["dataKey"] == null) 
{ 
    // first form submittal, do the search 
    GatherFormData(); 
    dtCustomers = BuildDT(); 
    // store it in cache 
    ViewState["dataKey"] = Guid.NewGuid().ToString(); // create a key 
    Cache.[ViewState["dataKey"].ToString()] = dtCustomers; // TODO use Add method to control expiration etc 
} 

其重要的是你清楚的视图状态,当搜索被重置(或类似条件)

最后,还可以从数据库/数据存储进行分页(例如,在SQL Server中使用排名函数),这样就不需要将搜索结果存储到会话/缓存中,而是在每个后​​台执行数据库访问。当完整的结果集大小可能很大时,此方法非常有用。

+0

谢谢你的回答。对于提供的示例,如何确定第一次遇到回发与后续页面之间的区别?我想到的场景是用户使用“返回”按钮返回到原始表单,设置不同的搜索选项,然后再次提交表单。通过使用“后退”按钮,用户不会重新加载原始表单,因此无法将ViewState归零,因此无法处理表单,结果将从缓存中提取。 – jiminy

+0

我想出了一个简单的解决方法。我在原始表单中添加了一个常规的字段,并在回发函数中测试了该输入字段是否有值。该字段仅在第一次回发(例如,第1页)上具有值,而不在每个后续页面上(例如第2+页)。再次感谢你的帮助。 – jiminy

+0

@jiminy,隐藏领域当然会工作。仅供参考,对于您以前的问题,您需要嗅探Request.Form以确定是否单击了搜索按钮,如果是,则清除视图状态。 – VinayC

相关问题