4

コントロールを動的に追加するアプリケーションを作成しようとしています。私はマスターページを持っています、私のasp:コンテンツはここにあります:

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<asp:ScriptManager ID="scriptManager1" runat="server">
</asp:ScriptManager>   
<div style="margin: 10px">
    <asp:UpdatePanel ID="updatePanel1" runat="server">
        <ContentTemplate>
            <asp:PlaceHolder runat="server" ID="myPlaceHolder" />
        </ContentTemplate>
        <Triggers>
            <asp:AsyncPostBackTrigger ControlID="btnAdd" EventName="Click" />
        </Triggers>
    </asp:UpdatePanel>
</div>
<asp:Button ID="btnAdd" runat="server" Text="Add" />

btnAddをクリックした後、2つのテキストボックスを追加します。http://jagdeepmankotia.wordpress.com/2010/01/30/dynamically-add-controls-in-asp-net-c/のようにやってみました

これは私のコードです:

    static int myCount = 1;
    private TextBox[] color;
    private TextBox[] text;

    protected override void OnInit(EventArgs e)
    {
        base.OnInit(e);
        color = new TextBox[myCount];
        text = new TextBox[myCount];

        for (int i = 0; i < myCount; i++)
        {
            TextBox tbColor = new TextBox();
            tbColor.ID = "colorTextBox" + i.ToString();
            myPlaceHolder.Controls.Add(tbColor);
            color[i] = tbColor;

            TextBox tbText = new TextBox();
            tbText.ID = "textTextBox" + i.ToString();
            myPlaceHolder.Controls.Add(tbText);
            text[i] = tbText;

            LiteralControl literalBreak = new LiteralControl("<br />");
            myPlaceHolder.Controls.Add(literalBreak);
        }
    }


    public Control GetPostBackControl(Page page)
    {
        Control control = null;
        string ctrlname = page.Request.Params.Get("__EVENTTARGET");
        if (ctrlname != null && ctrlname != string.Empty)
        {
            control = page.FindControl(ctrlname);
        }
        else
        {
            foreach (string ctl in page.Request.Form)
            {
                Control mycontrol = page.FindControl(ctl);
                if (mycontrol is System.Web.UI.WebControls.Button)
                {
                    control = mycontrol;
                    // This gives you ID of which button caused postback                        
                    break;
                }
            }
        }
        return control;
    }

    protected void Page_PreInit(object sender, EventArgs e)
    {
        Control myControl = GetPostBackControl(this.Page);
        if (myControl != null)
            if (myControl.ClientID.ToString() == "btnAdd")
                myCount = myCount + 1;
    }

    protected void btnAdd_Click(object sender, EventArgs e)
    {
        //handled in PreInit    

    }

たとえば、ctr "ctl00 $ MainContent $ scriptManager1"の最初の反復で、loap foreachの関数GetPostBackControl()で、myControlがnullになると、次の反復でも...したがって、関数は常にnullを返します。理由は何ですか?

4

1 に答える 1

9

FindControlコンテナの直接の子のみを検索します。あなたはページレベルから始めているので、あなたはUpdatePanelあなたのコントロールに到達するために子コントロールを通して再帰する必要があるでしょうbtnAdd

これを行う方法の例については、こちらをご覧ください。

編集: 画面には静的ボタンが1つしかないため、この方法でボタンを「探している」理由がわかりませんFindControl。この場合は使用する必要はありません。

<asp:Button ID="btnAdd" runat="server" Text="Add" onclick="btnAdd_Click" />

(またはコードではbtnAdd.OnClick += new EventHandler(btnAdd_Click);

フォームに複数のボタンを動的に追加した場合でも、それらすべてを同じボタンクリックハンドラーに接続できます。その場合、クリックさsenderれたボタンコントロールが含まれます。通常、FindControlを使用して、動的に追加された入力コントロール(テキストボックスなど)からデータを取得します。どのコントロールがポストバックを引き起こしたかを確認するのではありません(適切なイベントハンドラーの「送信者」の方が簡単です)。

編集2: 他のコントロールと同じようにボタンを動的に追加できます

    Button myButton = new Button();
    myButton.Text = "Click Me";
    myButton.Click += new EventHandler(btnAdd_Click);
    myPlaceHolder.Controls.Add(myButton); 

ポストバックの間にすでに追加したすべてのコントロールを「滞在」する場合は、ページとコントロールでビューステートを有効にしてから、OnInitでポストバックなしでコントロールを1回だけ追加するようにします。

   base.OnInit(e);    
   if (!IsPostBack)
   { // ... Add controls here

'mycount'の状態を非表示フィールド(同じupdatepanel内で、ビューステートが有効になっている場合)に保持できます。毎回intに解析する必要があります。または、SessionStateを使用して追跡することもできます。

于 2011-12-21T12:42:32.607 に答える