views:

1063

answers:

8

i'm having issues retreiving the values out of a dynamically created dropdownlist. all controls are created in the Page_Init section. the listitems are added at that time as well from an array of listitems. (the controls are named the same so should be accessable to the viewstate for appropriate setting.)

here is the function that attempts to retrieve the values:

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/>");
}

here is the output I get, no matter which instructor was selected.....

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

the name of the control is correct (verified via view source)....

ideas?

A: 

I'm not sure why you are generating the control in code (you can still add items dynamically if you do), but the code that generates the controls would probably be a huge help here. I'm guessing you are not setting the list item value, and instead just setting the list item text. Try seeing what you get from the SelectedText field and post your control creation function.

EDIT: In response to your comment on @Martin's post, you said "yes I recreate the controls in the Page_Init function each time the page is created (initial or postback)". Are you also setting the selected value when you create them?

You can also use controls on the page even if your data comes from a database, the controls themselves don't have to be dynamically generated.

NickLarsen
from the view source:<select name="ctl00$ContentPlaceHolder$Eng098Instructors_1_1" id="ctl00_ContentPlaceHolder_Eng098Instructors_1_1"><option selected="selected" value="0"><Select></option><option value="XXXXXXXXX">Anderson, Christie</option><option value="XXXXXXXXX">Ankcorn, Beth</option><option value="XXXXXXXXX">Anthony, Jared</option></select>(NOTE: the XXXXXXXXX replaced the actual value within). So this is getting set. the list was also shortened.
shaddow
if I do set the selected value on the Page_Init, I get an error that says I can't have multi selected values in the control. If I don't then it doesn't deliver the error, but doesn't seem to retain the value (i'm assuming via the viewstate) upon postback.... I've checked the naming scheme and it looks correct, so the data 'should' just flow thru....
shaddow
+1  A: 

why not just save the control in an instance in your class so that you don't have to use FindControl?

tster
+1  A: 

Do you also re-create the controls during the postback? Dynamically generated/added controls must be re-created with every request, they are not automatically re-created.

M4N
The reason the controls are created dynamically is because the application is database driven. Meaning that they can add/remove assignments for each course. This has to be build the same way each time and dynamically, I am most definitely setting the list item value and text. (verified), and yes I recreate the controls in the Page_Init function each time the page is created (initial or postback).... I have values coming out of the other controls correctly, just not the drop down....
shaddow
If the app is database driven, then use a data-driven naming container like a repeater.
Joel Coehoorn
+2  A: 

You're going to a lot of work to build this fancy string:

ctl00$ContentPlaceHolder$Eng098Instructors_1_1

That is the client ID of your control, not the server id. This code is running on the server side, and so you need the server id. To get that control using the server id, you need to do this:

ContentPlaceHolder.FindControl("Eng08Instructors_1_1");

Notice I didn't look in the page, because your content place holder created a new naming container.

Also, the way your loop is set up the myID variable will always end up holding the last button in the Keys collection. Why even bother with the loop?


Based on your comments, a better way to find the id of the dropdownlist is like this:

string id = ((Control)sender).ID.Replace("button_", "Eng098Instructors_");
Joel Coehoorn
I'm not sure that this is doing what you think. It goes thru the keys on the page (all, both static and dynamic controls), and then tells me which was used to call the postback, via determing via true/false (if (postbackControlInstance is System.Web.UI.WebControls.Button)), which button was pushed. The button that was pushed tells me which assignment to update.or maybe I'm not understanding..... quite possible...
shaddow
Sorry, that should read that it would also hold the last _button_. Fixed now. But it definitely won't tell you which of those buttons was pushed.
Joel Coehoorn
but it does... this is working code.... except for the dropdown ... The myID most definitely returns the portion of the button that tells me the ID of what button was pushed. if (postbackControlInstance is System.Web.UI.WebControls.Button) { myID = Convert.ToString(postbackControlInstance.ID.Replace("button_", "")); }Since they can push one of any number of buttons, I needed to know which assignment control group to interogate to get the values for the update. (I've used it several times.. if there is a better way?)
shaddow
As it is, your code only works if the press the last button, I promise you. If you want to know what button was pressed, just use the _sender_ argument to the event. That is the object (button) that raised the event. Just cast it and go.
Joel Coehoorn
A: 

Why don't you cast the sender? This should be the button that caused the postback:

string myId = "0";
Button btn = sender as Button;
if (btn != null)
    myId = btn.ID
...
OrangBule
Here is teh whole section. 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_", "")); } }
shaddow
So you are finding the correct DropDownList, but the SelectedValue is always the same, right? Make sure Viewstate is enabled. Check whether you are setting the SelectedValue somewhere explicitly before the click event. If you do so, check Page.IsPostback first.
OrangBule
A: 

You need to perform something like this because the UniqueID property is the key in 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;
         }
        } 
       }
      } 
     }
ChaosPandion
this approach was helpful!
shaddow
A: 

How about this?

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

Edit:I misunderstood your question. But i think you should follow page lifecycle. it is common issue for dynamically created controls.

I did some research and here is some info about Dynamically Created Controls may help you...

Emrah GOZCU
the attached article was by far the best article I've read about it! Thank you VERY much.
shaddow
A: 

I had 2 catches.... here's what they were.

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

apparently my attention to detail was off yesterday, i'm pretty sure the ctlXX frontrunner of the control was some different number upon postback due to how I was recreating the controls.

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

once I called the lookup upon each creation a dropdownlist control, all works well.

anyway for what it's worth....

shaddow