FindControl () возвращает ноль - PullRequest
       12

FindControl () возвращает ноль

4 голосов
/ 21 декабря 2011

Я пытался создать приложение, которое динамически добавляет элементы управления.У меня есть главная страница, мой 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 я хочу добавить два текстовых поля.Я пытаюсь сделать это, как в 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    

    }

Когда в функции GetPostBackControl () в loap foreach ищет мой btnAdd, например, в первой итерации для ctr"ctl00 $ MainContent $ scriptManager1", myControl имеет значение null ... В следующих итерациях также ... Так что моя функция всегда возвращает null.В чем может быть причина?

1 Ответ

8 голосов
/ 21 декабря 2011

FindControl только ищет прямые дочерние элементы контейнера.Поскольку вы начинаете с уровня страницы, вам нужно будет пройти через дочерний элемент управления UpdatePanel, чтобы перейти к вашему элементу управления btnAdd.

Посмотрите, например, здесь как это сделать.

Редактировать: Я не уверен, что понимаю, почему вы так «ищете» свою кнопку, поскольку на экране только одна статическая кнопка- вам не нужно будет использовать FindControl в этом случае.

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

(или в коде, btnAdd.OnClick += new EventHandler(btnAdd_Click);)

Даже если у вас есть несколько кнопок в вашей форме, добавляемых динамическиВы можете связать ВСЕ из них с одним и тем же обработчиком Click Button, и тогда sender будет содержать Button Control, который был нажат.Обычно вы используете FindControl для очистки данных из динамически добавленных элементов управления вводом (текстовое поле и т. Д.), А не для того, чтобы увидеть, какой элемент управления вызвал обратную передачу (поскольку «отправитель» в соответствующем обработчике события будет проще)

Редактировать 2: Вы можете добавлять кнопки динамически, как и другие ваши элементы управления

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

Если вы хотите, чтобы все добавленные вами элементы управления «оставались» между постбэками, тогдавключите viewstate на странице и в элементах управления, а затем убедитесь, что вы добавляете элементы управления только один раз без обратной передачи, в OnInit:

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

Вы можете сохранить состояние 'mycount' в скрытом поле (в той же панели обновления, и с включенным viewstate) - вам нужно будет каждый раз анализировать его в int.Или вы можете использовать SessionState для его отслеживания.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...