web-dev-qa-db-ja.com

ポストバック後にデータを失う動的に作成されたコントロール

実際、TextBoxに1つのPageloadを作成し、TextBoxPanelを追加しています。これで、Add AnotherのようなLinkButtonができました。

そのTextBoxにテキストを入力しています。必要に応じて、Add Another LinkButtonをクリックして、新しいTextBoxを作成する必要があります。

実際、カウントを取得し、TextBoxesを再作成できます。しかし、問題は、以前に生成されたTextboxesに入力したテキストが見つからないことです。

誰でも、この解決策を提案できますか?

protected void Page_Load(object sender, EventArgs e)
    {
        try
        {
            if (!IsPostBack)
            {
                for (int i = 0; i < 5; i++)
                {
                    TableRow row = new TableRow();
                    for (int j = 0; j < 5; j++)
                    {
                        TableCell cell = new TableCell();
                        TextBox tb = new TextBox();                        
                        tb.ID = "TextBoxRow_" + i + "Col_" + j;                        
                        cell.Controls.Add(tb);                        
                        row.Cells.Add(cell);
                    }                    
                    Table1.Rows.Add(row);
                }
            }
        }
        catch (Exception ex)
        {
            throw;
        }        
    }

これはサンプルコードです。同じコードがButton_Clickにも記述されています

 protected void ASPxButton1_Click(object sender, EventArgs e)
    {
 int k = Table1.Controls.Count;
}

Count=0Button_Clickを取得しています。

33
RealSteel

これは、ダイナミックコントロールで多くの作業を行った後の私の最終回答です

。aspx

<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<div style="text-align: center">
    <div style="background-color: Aqua; width: 250px;">
    <br />
    <asp:UpdatePanel ID="UpdatePanel1" runat="server">
        <ContentTemplate>
            <asp:PlaceHolder runat="server" ID="myPlaceHolder"></asp:PlaceHolder>
        </ContentTemplate>
        <Triggers>
            <asp:AsyncPostBackTrigger ControlID="btnAddTextBox" EventName="Click" />
        </Triggers>
    </asp:UpdatePanel>
    <br />
    </div>
    <br />
    <asp:Button ID="btnAddTextBox" runat="server"  Text="Add TextBox" OnClick="btnAddTextBox_Click" />
    <br /><br />
    <asp:UpdatePanel ID="UpdatePanel2" runat="server">
        <ContentTemplate>
            <asp:Button runat="server" ID="MyButton" Text="Get Values." OnClick="MyButton_Click" />
            <br /><br />
            <asp:Label runat="server" ID="MyLabel"></asp:Label>
        </ContentTemplate>
    </asp:UpdatePanel>
 </div>
</form>

。aspx.cs

static int myCount = 0;
    private TextBox[] dynamicTextBoxes;

    protected void Page_PreInit(object sender, EventArgs e)
    {
        Control myControl = GetPostBackControl(this.Page);

        if ((myControl != null))
        {
            if ((myControl.ClientID.ToString() == "btnAddTextBox"))
            {
                myCount = myCount + 1;
            }
        }
    }

    protected override void OnInit(EventArgs e)
    {
        base.OnInit(e);
        dynamicTextBoxes = new TextBox[myCount];
        int i;
        for (i = 0; i < myCount; i += 1)
        {
            TextBox textBox = new TextBox();
            textBox.ID = "myTextBox" + i.ToString();
            myPlaceHolder.Controls.Add(textBox);
            dynamicTextBoxes[i] = textBox;
            LiteralControl literalBreak = new LiteralControl("<br />");
            myPlaceHolder.Controls.Add(literalBreak);
        }
    }

    protected void btnAddTextBox_Click(object sender, EventArgs e)
    {
        // Handled in preInit due to event sequencing.
    }

    protected void MyButton_Click(object sender, EventArgs e)
    {
        MyLabel.Text = "";
        foreach (TextBox tb in dynamicTextBoxes)
        {
            MyLabel.Text += tb.Text + " :: ";
        }
    }

    public static Control GetPostBackControl(Page thePage)
    {
        Control myControl = null;
        string ctrlName = thePage.Request.Params.Get("__EVENTTARGET");
        if (((ctrlName != null) & (ctrlName != string.Empty)))
        {
            myControl = thePage.FindControl(ctrlName);
        }
        else
        {
            foreach (string Item in thePage.Request.Form)
            {
                Control c = thePage.FindControl(Item);
                if (((c) is System.Web.UI.WebControls.Button))
                {
                    myControl = c;
                }
            }
        }
        return myControl;
    }
3
RealSteel

すべての行う必要があるのは、ポストバック中に毎回ページ読み込みイベントの前またはページ内で動的コントロールを再インスタンス化/再初期化するで、このコントロールをページ/フォーム/プレースホルダーに追加することです。次に、ポストされたデータは、親コントロールによってLoadPostDataメソッドを呼び出すことにより、自動的にコントロールに割り当てられます。

記事と動的制御のコードの記述方法を確認してください-asp.net

enter image description here

17
Vivek

動的コントロールを使用する場合、次のポストバックまでしか存在しないことに注意する必要があります。ASP.NETは動的に追加されたコントロールを再作成しません。コントロールを複数回再作成する必要がある場合は、PageLoadイベントハンドラーでコントロールの作成を実行する必要があります(現在のところ、Condition:!IsPostabckを使用してTextBoxを初めて作成するだけです)。これには、動的制御でビューステートを使用できるという追加の利点があります。通常、ビューステートはPage.Loadイベントの前に復元されますが、PageLoadイベントのハンドラーでコントロールを作成すると、ASP.NETは、PageLoadイベントハンドラーが終了した後のビューステート情報を適用します。

そのため、条件を削除します:!IsPostback。ページがロードされるたびに、TextBoxコントロールも作成されます。また、PageLoadハンドラーの完了後に保存された[テキストの状態]ボックスも表示されます。 [明らかにViewStateを無効にしていない!!! ]

例:

protected void Page_Load(object sender, EventArgs e)
{

    TextBox txtBox = new TextBox();
    // Assign some text and an ID so you can retrieve it later. 

    txtBox.ID = "newButton";
    PlaceHolder1.Controls.Add(txtBox);

}

実行後、テキストボックスに何かを入力し、ポストバックの原因となるボタンをクリックするとどうなるかを確認します。テキストボックスはまだ状態を維持しています!!!

14
R.C

動的に生成されたコントロールは状態を維持しません。あなた自身でそれを維持する必要があります。隠しフィールドを使用してコントロールの状態を保持できます。これは、サーバー側で状態を抽出するために使用されます。 Asp.netは非表示フィールドを使用してリクエスト間の状態を維持します。__VIEWSTATEソース。

ASP.NETページでは、ビューステートは、サーバーで最後に処理されたときのページの状態を表します。呼び出しコンテキストを構築し、同じページの2つの連続したリクエストにわたって値を保持するために使用されます。デフォルトでは、ページに追加された非表示フィールドを使用してクライアントで状態が保持され、ページ要求が処理される前にサーバーに復元されます。ビューステートは、ページ自体とともに前後に移動しますが、クライアント側のページ表示に関連する情報を表すことも、表示することもありません。 Reference

7
Adil

この行を削除してください

 if (!IsPostBack)
4
Seçkin Durgay

動的コントロールで作業している場合、ポストバック中に状態を維持できず、データが失われます。データを維持するためのビューステートがありません。

作成されたコントロールデータをViewStateに動的に維持し、ポストバック時にデータをページにロードするだけで済みます。

public Dictionary<Guid, string> UcList
{
    get { return ViewState["MyUcIds"] != null ? (Dictionary<Guid, string>)ViewState["MyUcIds"] : new Dictionary<Guid, string>(); }
    set { ViewState["MyUcIds"] = value; }
}

public void InitializeUC()
{
    int index = 1;
    foreach (var item in UcList)
    {
        var myUc = (UserControls_uc_MyUserControl)LoadControl("~/UserControls/uc_MyUserControl.ascx");
        myUc.ID = item.Value;
        pnlMyUC.Controls.AddAt(index, myUc);
        index++;
    }
}

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
        LoadControl();
    else
        InitializeUC();
}

ここでは、ダイナミックコントロールのポストバックとポストバックについて最もよく理解できます。 すべてのポストバックまたはイベントクリックで動的制御値を保持

enter image description here

1
Jatin Phulera

実際、私は仕事を達成するためにJavascriptを使用しました。そしてそれはこのようになります:

<form id="form1" runat="server" enctype="multipart/form-data" method="post">
        <span style="font-family: Arial">Click to add files</span>&nbsp;&nbsp;
        <input id="Button1" type="button" value="add" onclick="AddFileUpload()" />
        <br />
        <br />
        <div id="FileUploadContainer">
            <!--FileUpload Controls will be added here -->
        </div>
        <asp:HiddenField ID="HdFirst1" runat="server" Value="" />
        <br />
        <asp:Button ID="btnUpload" runat="server" Text="Upload" OnClick="btnUpload_Click" />
    </form>

脚本 :

 <script type="text/javascript">
        var counter = 0;

        function AddFileUpload() {

            var div = document.createElement('DIV');
            div.innerHTML = '<input id="file' + counter + '"name = "file' + counter + '"type="text"/><input id="file' + counter + '" name = "file' + counter + '" type="file" /><input id="Button' + counter + '" type="button" value="Remove" onclick = "RemoveFileUpload(this)" />';

            document.getElementById("FileUploadContainer").appendChild(div);
            counter++;
        }
        function RemoveFileUpload(div) {
            document.getElementById("FileUploadContainer").removeChild(div.parentNode);
        }

        function mydetails(div) {
            var info;
            for (var i = 0; i < counter; i++) {
                var dd = document.getElementById('file' + i).value;
                info = info + "~" + dd;
            }
            document.getElementById('<%= HdFirst1.ClientID %>').value = info;
        }
    </script>

upload_Clickボタンで:

for (int i = 0; i < Request.Files.Count; i++)
        {           
           string strname = HdFirst1.Value;
           string[] txtval = strname.Split('~');
            HttpPostedFile PostedFile = Request.Files[i];
            if (PostedFile.ContentLength > 0)
            {
                string FileName = System.IO.Path.GetFileName(PostedFile.FileName);
               // string textname=
                //PostedFile.SaveAs(Server.MapPath("Files\\") + FileName);
            }
        }
0
RealSteel