C#动态创建控件问题

时间:2009-09-28 18:30:24

标签: c# asp.net dynamic-controls

我遇到了从动态创建的下拉列表中检索值的问题。所有控件都在Page_Init部分中创建。列表项目也是从列表项目数组中添加的。 (控件的名称相同,因此应该可以访问视图状态以进行适当的设置。)

这是尝试检索值的函数:

protected void Eng98AssignmentComplete_Click(object sender, EventArgs e)
{
    String myID = "0";
    Page page = Page;
    Control postbackControlInstance = null;
    // handle the Button control postbacks
    for (int i = 0; i < page.Request.Form.Keys.Count; i++)
    {
        postbackControlInstance = page.FindControl(page.Request.Form.Keys[i]);
        //Response.Write(page.Request.Form.Keys[i].ToString());
        if (postbackControlInstance is System.Web.UI.WebControls.Button)
        {
            myID = Convert.ToString(
                postbackControlInstance.ID.Replace("button_", ""));
        }
    }
    String txtholder = "ctl00$ContentPlaceHolder$Eng098Instructors_" + myID;
    Response.Write("MYID: " + myID + "<br/>");
    DropDownList ddInstructorCheck = (DropDownList)Page.FindControl(txtholder);
    Response.Write("Instructor Selected: "
      + ddInstructorCheck.SelectedValue + "<br/>");
}

这是我得到的输出,无论选择哪位教师.....

MYID: 1_1
Instructor Selected: 0
ctl00$ContentPlaceHolder$Eng098Instructors_1_1

控件的名称是正确的(通过查看源验证)....

想法?

8 个答案:

答案 0 :(得分:3)

你需要做很多工作来构建这个花哨的字符串:

  

ctl00 $ $的ContentPlaceHolder Eng098Instructors_1_1

这是您控件的客户端ID ,而不是服务器ID。此代码在服务器端运行,因此您需要服务器ID。要使用服务器ID获取该控件,您需要执行以下操作:

ContentPlaceHolder.FindControl("Eng08Instructors_1_1");

注意我没有查看页面,因为您的内容占位符创建了一个新的命名容器。

此外,设置循环的方式myID变量将始终最终按住Keys集合中的 last 按钮。为什么甚至打扰循环?


根据您的评论,找到下拉列表ID的更好方法是:

string id = ((Control)sender).ID.Replace("button_", "Eng098Instructors_");

答案 1 :(得分:1)

为什么不将控件保存在类中的实例中,这样就不必使用FindControl?

答案 2 :(得分:1)

您是否还在回发期间重新创建控件?必须使用每个请求重新创建动态生成/添加的控件,它们不会自动重新创建。

答案 3 :(得分:1)

你为什么不投下发件人?这应该是导致回发的按钮:

string myId = "0";
Button btn = sender as Button;
if (btn != null)
    myId = btn.ID
...

答案 4 :(得分:1)

您需要执行类似的操作,因为UniqueID属性是Request.Form中的键。

        List<Button> buttons = new List<Button>();
        List<DropDownList> dropdowns = new List<DropDownList>();
        foreach (Control c in Controls)
        {
            Button b = (c as Button);
            if (b != null)
            {
                buttons.Add(b);
            }

            DropDownList d = (c as DropDownList);
            if (d != null)
            {
                dropdowns.Add(d);
            }
        }

        foreach (String key in Request.Form.Keys)
        {
            foreach (Button b in buttons)
            {
                if (b.UniqueID == key)
                {
                    String id = b.ID.Replace("button_", "");
                    String unique_id = "ctl00$ContentPlaceHolder$Eng098Instructors_" + id;
                    Response.Write("MYID: " + id + "<br/>");

                    foreach (DropDownList d in dropdowns)
                    {
                        if (d.UniqueID == unique_id)
                        {
                            Response.Write("Instructor Selected: " + d.SelectedValue + "<br/>");
                            break;
                        }
                    } 
                }
            }   
        }

答案 5 :(得分:0)

我不确定为什么要在代码中生成控件(如果你这样做,你仍然可以动态添加项目),但生成控件的代码可能会在这里提供很大的帮助。我猜你没有设置列表项值,而只是设置列表项文本。尝试查看您从SelectedText字段获得的内容并发布您的控件创建功能。

编辑: 为了回应你对@ Martin帖子的评论,你说“是的,我每次创建页面时都会在Page_Init函数中重新创建控件(初始或回发)”。您是否还在创建时设置了所选值?

即使您的数据来自数据库,您也可以在页面上使用控件,控件本身不必动态生成。

答案 6 :(得分:0)

这个怎么样?

((Button)sender).Parent.FindControl(myid)

编辑:我误解了你的问题。但我认为你应该遵循页面生命周期。这是动态创建控件的常见问题。

我做了一些研究,这里有一些关于Dynamically Created Controls的信息可以帮助你...

答案 7 :(得分:0)

我有2次捕获......这就是它们的原因。

1.  I didn't clear the table I was adding to before re-creating the controls.

显然我对细节的关注是昨天关闭的,我很确定控件的ctlXX领跑者在回发时因为我重新创建控件的方式而有一些不同的数字。

2.  I was assigning the same list to all the dropdownlist controls.  

一旦我在每次创建时调用查找下拉列表控件,一切运行良好。

无论如何它的价值......