1

おそらく小さなことですが、以下が完全に機能しない理由がわかりません。ユーザーが初めて検索を送信すると、検索結果の最初のページが適切に表示されます。ただし、ユーザーが [前のページ] ボタンと [次のページ] ボタンを使用してナビゲートしようとすると、リピーターは DataTable から適切なデータを表示しません。

検索.aspx

<asp:Repeater ID="rptSearchResults" runat="server" OnItemDataBound="rptSearchResults_ItemDataBound">
    <ItemTemplate>
        <div>
            <asp:Literal ID="ltlCustName" runat="server" />
        </div>
    </ItemTemplate>
</asp:Repeater>

検索.aspx.vb

Public dtCustomers As DataTable = New DataTable()
Sub Page_Load(ByVal Sender As Object, ByVal E As EventArgs) Handles Me.Load
    ' Check to see if this is the first time postback-ing to itself.
    blnFirstPostBack = (Request.Form("firstpb") = "1")

    ' When the page first loads, show the search form with search options.
    If Not Page.IsPostBack Then
        Session("StoredDT") = Nothing
        ShowSearchForm()
    ' Once the form is submitted, show the search results.
    Else
        Response.Write("DEBUG: Get Data")
        If blnFirstPostBack Then
            GatherFormData()
            dtCustomers = BuildDT()
            Session("StoredDT") = dtCustomers
            BindData()
        ElseIf Not Session("StoredDT") Is Nothing Then
            dtCustomers = Session("StoredDT")
        End If
    End If
End Sub

Sub BindData()
    Response.Write("DEBUG: Bind Data")
    ' At this point, I've checked that the dtCustomers is showing the proper data (e.g., grabbing from session when appropriate).
    Dim objPDS As PagedDataSource = New PagedDataSource()
    objPDS.DataSource = dtCustomers.DefaultView
    objPDS.AllowPaging = True
    objPDS.PageSize = intNumPerPage
    ' I've checked that Me.ViewState("_CurrentPage") gets updated to the correct page.
    objPDS.CurrentPageIndex = Me.ViewState("_CurrentPage")
    rptSearchResults.DataSource = objPDS
    ' I'm not sure if the error is here but although the dtCustomers is the proper data, the PagedDataSource and the binding here doesn't seem to play nice.
    Call rptSearchResults.DataBind()
End Sub

' Subroutine called when the previous page button is pressed.
Sub GoToPrevPage()
    Response.Write("DEBUG: Prev Page")
    ' 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()
    Response.Write("DEBUG: Next Page")
    ' Set viewstate variable to the next page.
    Me.ViewState("_CurrentPage") += 1
    BindData()
End Sub

Protected Sub rptSearchResults_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.RepeaterItemEventArgs) Handles rptSearchResults.ItemDataBound
    Dim item As RepeaterItem = e.Item
    Dim strCustName As String = ""
    If (item.ItemType = ListItemType.Item) Or (item.ItemType = ListItemType.AlternatingItem) Then
        strCustName = e.Item.DataItem("CustName")
        Dim ltlCustName As Literal = CType(e.Item.FindControl("ltlCustName"), Literal)
        ltlCustName.Text = strCustName
    End If
End Sub

サンプルページ 1 (適切なデータを表示):

DEBUG: Get Data
DEBUG: Bind Data
Laurence Clinton
John Doe
Sean King
Jane Smith

サンプル ページ 2 (適切なデータは表示されませんが、不足しているデータに対して十分なスペースが表示されます):

DEBUG: Get Data
DEBUG: Next Page
DEBUG: Bind Data
[no name showing here 5]
[no name showing here 6]
[no name showing here 7]
[no name showing here 8]

コードが省略されていることをお許しください。ただし、実際のコードは膨大なので、問題の核心に到達しやすくするために簡略化しています。

不明な点がある場合、またはさらにコードが必要な場合はお知らせください。前もって感謝します!

2013 年 2 月 19 日更新:

そのため、コードを少しいじった後、リピーター サブルーチンでエラーが発生したと思います。リピーター内の元のリテラルが機能するようになりました。何らかの理由で、以前は機能しなかったと思いますが、現在は正常に機能しています。問題は、リピーター サブルーチン内でカスタム コントロールを使用してさらに一歩進んだ場合です。情報がコントロールに渡されないようです。コントロール内でのみ見つかったサポート HTML は適切に出力されますが、コントロールに渡そうとする顧客情報は内部に入らないため、コントロールは適切に呼び出されます。変更されたコードは次のとおりです。

検索.aspx

<asp:Repeater ID="rptSearchResults" runat="server" OnItemDataBound="rptSearchResults_ItemDataBound">
    <ItemTemplate>
        <div>
            <asp:Literal ID="ltlCustName" runat="server" />
            <Acme:CustInfo ID="AcmeCustInfo" runat="server" />
        </div>
    </ItemTemplate>
</asp:Repeater>

検索.aspx.vb

Protected Sub rptSearchResults_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.RepeaterItemEventArgs) Handles rptSearchResults.ItemDataBound
    Dim item As RepeaterItem = e.Item
    Dim strCustName As String = ""
    If (item.ItemType = ListItemType.Item) Or (item.ItemType = ListItemType.AlternatingItem) Then
        strCustName = e.Item.DataItem("CustName")

        ' This literal properly shows the customer name on subsequent pages so the customer name reaches this point properly.
        Dim ltlCustName As Literal = CType(e.Item.FindControl("ltlCustName"), Literal)
        ltlCustName.Text = strCustName

        ' This control gets called properly but strCustName doesn't 
        ' get passed into the control. The control works fine for the
        ' first page but subsequent pages do not work. Also, the 
        ' control works fine when PagedDataSource is not used.
        Dim AcmeCustInfo As CustInfo = CType(e.Item.FindControl("AcmeCustInfo"), CustInfo)
        AcmeCustInfo.CustName = strCustName
    End If
End Sub

アンからのリクエストごと

CustInfo のコードは次のとおりです。言うまでもなく、問題に焦点を当てるために多くの綿毛が取り除かれていますが、有用な何かが欠けている場合はお知らせください。それに応じて例を更新します.

custinfo.ascx

<%@ Control Language="VB" AutoEventWireup="false" CodeFile="CustInfo.ascx.vb" Inherits="CustInfo" %>

<div style="border: 1px solid black;">
    <asp:Literal ID="ltlCustName" runat="server" />
</div>

custinfo.ascx.vb

Imports System
Imports System.Web
Imports System.Web.Security
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports System.Web.UI.HtmlControls
Imports System.Configuration
Imports System.Data
Imports System.Data.SqlClient
Imports System.IO
Imports System.Web.HttpUtility

Partial Class CustInfo
    Inherits System.Web.UI.UserControl

    Private _CustName As String = ""

    Public Property CustName() As String
        Get
            Return _CustName
        End Get
        Set(value As String)
            _CustName = value
        End Set
    End Property

    Public Sub Page_Load(ByVal Sender As Object, ByVal E As EventArgs) Handles Me.Load
        Dim ltlCustName As Literal = CType(FindControl("ltlCustName"), Literal)
        ltlCustName.Text = "<b>Name: " & CustName & "</b>"
    End Sub
End Class
4

1 に答える 1

1

私はPagedDataSource専門家ではありませんが、ユーザー コントロールを広範囲に使用してきました。

サブルーチンのCustInfoコントロールでリテラルの値を設定しています。Load私が間違っていなければ、CustInfoコントロールが作成されたときに呼び出されます。OnItemDataBoundこれはが呼び出される前に発生するので、サブルーチンが発生し、プロパティの値を割り当てる前にリテラルの値が (空の文字列に) 設定されます。これを修正するには、後でサブルーチンなどでリテラルの値を設定してみてください。LoadCustNamePreRender

すべてのポストバックをバインドしているように見えるので、次のことは問題にならないはずですが、そうでない場合は、次のような問題が発生する可能性があります。

  1. ItemDataBound再バインドした場合にのみ実行されます。リピーターに対して ViewState をオンにしている場合、コントロールはポストバックで再作成され、実行されItemCreatedますが、実行されItemDataBoundません。CustNameしたがって、プロパティをリセットすることはありません。そして、これは重要です...
  2. ...CustNameプロパティには、バッキング ストアとしての変数があります: では保持されませんViewState。そのため、ユーザー コントロールが再作成CustNameされると、以前に設定したプロパティはもう存在しません。リテラルの内容は、CustNameプロパティの既定値である空の文字列に設定されます。

これら2つを一緒にすると、あなたが説明した動作とまったく同じになります。しかし、問題にならない可能性のあるすべてのポストバックを (最終的には) バインドしているように見えるためです。完全を期すために含めています。

于 2013-02-19T22:12:31.130 に答える