【问题标题】:Unable to retrieve value from dynamically added control无法从动态添加的控件中检索值
【发布时间】:2017-09-01 21:04:14
【问题描述】:

我正在添加动态文本框和标签。我想用标签和文本框创建动态控件。之后我需要从提交中获取值,但我无法获取将控件添加到表中的值。

    if (!string.IsNullOrEmpty(dynamicFieldstring))
    {
        string[] groupControl = dynamicFieldstring.Split('|');

        for (int i = 0; i < groupControl.Length; )
        {
            TableRow row = new TableRow();

            for (int j = 0; j < 2; j++)
            {
                if (i >= groupControl.Length)
                    break;

                string[] singleControl = groupControl[i].Split('=');

                Label label = new Label();
                TextBox textbox = new TextBox();
                string textboxId = string.Empty;
                string labelId = string.Empty;
                TableCell cell = new TableCell();

                label.Text = singleControl[0];
                labelId = "lbl" + i + j;
                label.ID = textboxId;
                label.Attributes.Add("runat", "server");
                cell.Controls.Add(label);

                TableCell cell1 = new TableCell();
                textbox.Text = singleControl[1];
                textboxId = "txt" + i + j;
                textbox.ID = textboxId;
                textbox.Attributes.Add("runat", "server");
                cell1.Controls.Add(textbox);

                _dynamicControlId.Add(labelId, textboxId);
                Session["controllIds"] = _dynamicControlId;
                // Add the TableCell to the TableRow
                row.Cells.Add(cell);
                row.Cells.Add(cell1);
                //}

                i = i + 1;
            }

            extraAttr.Rows.Add(row);
        }

Value added successfully, but when I am trying to get value from the code. I am getting null value. This is my code for get the value:

    string value = string.Empty;
    _dynamicControlId = (Dictionary<string, string>)Session["controllIds"];
    if (_dynamicControlId != null && _dynamicControlId.Count > 0)
    {
        TextBox textbox;

        for (int i = 0; i < this.Controls.Count; i++)
        {
           var control= this.Controls[i];
        }

        foreach (var item in _dynamicControlId)
        {
            Label label = (Label)this.FindControl(item.Key);
            //value = Request.Form("something_TextoxFirstName");
            value = label.Text + "=";
            textbox = (TextBox)this.FindControl(item.Value);
            value += textbox.Text + "|";
        }
    }
    return value;

【问题讨论】:

    标签: c# asp.net webforms


    【解决方案1】:

    动态控件的诀窍是您需要在回发时重新加载它们,因为它们不在控件树中。我们通常在 Page Init 事件或 Page Load 事件中重新加载它们。

    另一个问题是FindControl 只寻找直系孩子。如果要查找嵌套在其他控件中的控件,则需要递归查找。

    结果

    <asp:Table runat="server" ID="extraAttr" />
    <asp:Button runat="server" ID="SubmitButton" OnClick="SubmitButton_Click" Text="Submit" />
    <br/>
    <asp:Label runat="server" ID="ResultLabel" />
    

    代码隐藏

    public partial class _Default : Page
    {
        Dictionary<string, string> _dynamicControlId = new Dictionary<string, string>();
    
        protected void Page_Init(object sender, EventArgs e)
        {
            CreateControls();
        }
    
        protected void SubmitButton_Click(object sender, EventArgs e)
        {
            ResultLabel.Text = "Result : " + RetrieveValues();
        }
    
        private void CreateControls()
        {
            string dynamicFieldstring = "one=1|two=2|three=3|four=4";
            if (!string.IsNullOrEmpty(dynamicFieldstring))
            {
                string[] groupControl = dynamicFieldstring.Split('|');
    
                for (int i = 0; i < groupControl.Length;)
                {
                    TableRow row = new TableRow();
    
                    for (int j = 0; j < 2; j++)
                    {
                        if (i >= groupControl.Length)
                            break;
    
                        string[] singleControl = groupControl[i].Split('=');
    
                        Label label = new Label();
                        TextBox textbox = new TextBox();
                        string textboxId = string.Empty;
                        string labelId = string.Empty;
                        TableCell cell = new TableCell();
    
                        label.Text = singleControl[0];
                        labelId = "lbl" + i + j;
                        label.ID = labelId; // <--- value should be labelId instead of textboxId
                        label.Attributes.Add("runat", "server");
                        cell.Controls.Add(label);
    
                        TableCell cell1 = new TableCell();
                        textbox.Text = singleControl[1];
                        textboxId = "txt" + i + j;
                        textbox.ID = textboxId;
                        textbox.Attributes.Add("runat", "server");
                        cell1.Controls.Add(textbox);
    
                        _dynamicControlId.Add(labelId, textboxId);
                        row.Cells.Add(cell);
                        row.Cells.Add(cell1);
                        i = i + 1;
                    }
                    extraAttr.Rows.Add(row);
                    Session["controllIds"] = _dynamicControlId;
                }
            }
        }
    
        private string RetrieveValues()
        {
            string value = string.Empty;
            _dynamicControlId = Session["controllIds"] as Dictionary<string, string>;
            if (_dynamicControlId != null && _dynamicControlId.Count > 0)
            {
    
                foreach (var item in _dynamicControlId)
                {
                    Label label = FindControlRecursive(extraAttr, item.Key) as Label;
                    value += label.Text + "="; // <--- Operator should be should be +=
                    var textbox = FindControlRecursive(extraAttr, item.Value) as TextBox;
                    value += textbox.Text + "|";
                }
            }
            return value;
        }
    
        private Control FindControlRecursive(Control root, string id)
        {
            if (root.ID == id)
                return root;
    
            return root.Controls.Cast<Control>()
                .Select(c => FindControlRecursive(c, id))
                .FirstOrDefault(c => c != null);
        }
    }
    

    【讨论】:

    • 所以我必须删除 Page_Load 方法??
    • 如果您将其用于其他目的,您仍然可以保留Page_Load 方法。请确保您不要在Page_InitPage_Load 内调用 CreateControls 两次。
    • 在我们继续之前,请创建一个没有母版页的新 ASPX 页面,然后复制并粘贴上面的代码并进行调试。
    • 实际上我的页面是从母版页继承的Production : Base
    • 好吧,你得从某个地方开始。我在新的 ASPX 页面中测试了上面的代码,它正在工作。
    猜你喜欢
    • 1970-01-01
    • 2010-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-23
    • 2012-12-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多