1

それぞれ 1 つのテキスト入力を含む 2 つのユーザー コントロールを持つ VB ASP.NET Web アプリケーションがあります。それぞれユーザー コントロールの 1 つに対応する 2 つの送信ボタンがあります。

ボタンをクリックすると、対応するユーザー コントロールのインスタンスが追加されます。ほとんどの場合、これは機能しますが、特定のシナリオでテキストボックスの ID が混同され、以前に入力された値が混同されることを除きます。

問題のシナリオは次のとおりです。

1) 2 番目のボタン ([承認者の追加] ボタン) を 2 回クリックし、表示される 2 つのテキスト ボックスに値を入力します (分析を容易にするため、値を異なるものにします)。

2) 最初のボタン ([ドキュメントの追加] ボタン) を 1 回クリックします。(ここでは、結果のテキスト ボックスに値を追加する必要はありません。)

この時点で、すべてが正しく表示されます。ページ ソースを表示すると、2 つの「承認者」テキスト ボックスの ID が ctl02_txtApprover と ctl03_txtApprover であり、1 つの「ドキュメント」テキスト ボックスの ID が ctl04_txtDocument であることがわかります。

  1. 最初のボタン ([ドキュメントの追加] ボタン) をもう一度クリックします。

この時点で、最初の「承認者」テキストボックスの値が消えます。2 番目の「承認者」テキスト ボックスの値は、最初の「承認者」テキスト ボックスに移行されます。ページ ソースを表示すると、2 つの「承認者」テキスト ボックスの ID が ctl03_txtApprover と ctl04_txtApprover に変更されています。テキストボックス ID が変更されたことを考えると、移行された値は理にかなっています。つまり、ViewState は正しく表示されますが、コントロール ID が正しくありません。

コードをできるだけシンプルにして、ここに投稿しました。

デフォルト.aspx

<%@ Page Language="vb" AutoEventWireup="false" CodeBehind="Default.aspx.vb" Inherits="WebApplicationUserControlTest._Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
        <asp:PlaceHolder ID="phDocument" runat="server" />
        <asp:Button ID="btnAddDocument" runat="server" Text="Add Document" />
        <br /><br />
        <asp:PlaceHolder ID="phApprover" runat="server" />
        <asp:Button ID="btnAddApprover" runat="server" Text="Add Approver" />
    </form>
</body>
</html>

Default.aspx.vb

Public Class _Default
Inherits System.Web.UI.Page
Private Const VIEWSTATE_DOCUMENT_COUNT As String = "DocumentCount"
Private Const VIEWSTATE_APPROVER_COUNT As String = "ApproverCount"

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    If Not IsPostBack Then
        ViewState(VIEWSTATE_DOCUMENT_COUNT) = 0
        ViewState(VIEWSTATE_APPROVER_COUNT) = 0
    Else
        're-display any preexisting dynamic sections on postback
        AddAllDocumentInfoSections()
        AddAllApproverSections()
    End If
End Sub

Protected Sub btnAddDocument_Click(sender As Object, e As EventArgs) Handles btnAddDocument.Click
    ViewState(VIEWSTATE_DOCUMENT_COUNT) += 1
    AddDocumentSection()
End Sub

Protected Sub btnAddApprover_Click(sender As Object, e As EventArgs) Handles btnAddApprover.Click
    ViewState(VIEWSTATE_APPROVER_COUNT) += 1
    AddApproverSection()
End Sub

Private Sub AddAllDocumentInfoSections()
    For i As Integer = 0 To ViewState(VIEWSTATE_DOCUMENT_COUNT) - 1
        AddDocumentSection()
    Next
End Sub

Private Sub AddAllApproverSections()
    For i As Integer = 0 To ViewState(VIEWSTATE_APPROVER_COUNT) - 1
        AddApproverSection()
    Next
End Sub

Private Sub AddDocumentSection()
    Dim c As UserControl = LoadControl("~/Document.ascx")
    phDocument.Controls.Add(c)
End Sub

Private Sub AddApproverSection()
    Dim c As UserControl = LoadControl("~/Approver.ascx")
    phApprover.Controls.Add(c)
End Sub
End Class

ドキュメント.ascx

<%@ Control Language="vb" AutoEventWireup="false" CodeBehind="Document.ascx.vb" Inherits="WebApplicationUserControlTest.Document" %><asp:TextBox ID="txtDocument" runat="server" /><br /><br />

承認者.ascx

<%@ Control Language="vb" AutoEventWireup="false" CodeBehind="Approver.ascx.vb" Inherits="WebApplicationUserControlTest.Approver" %><asp:TextBox ID="txtApprover" runat="server" /><br /><br />

Visual Studio 2010 を使用しています。ターゲット フレームワークは 4.0 です。clientIDMode を変更しようとしましたが、違いはないようです。.NET でバグが発生したのでしょうか、それともコードに何か問題がありますか?

4

2 に答える 2