Setting values of Controls used multiple times on a page

Discussion in 'ASP .Net' started by james.e.coleman, Apr 20, 2005.

  1. Hello,

    I have created a custom dropdownlist that is used multiple times within
    a single page. When trying to set the values of the controls with the
    page in which they are being used, they all are set to the value of the
    last control. I found this link:
    http://www.codecomments.com/archive315-2005-1-366113.html which I think
    explains the situation but I'm not sure how to implement the solution
    in my case since I am not using a .ascx control, but a programmatically
    created control.

    ++++++++++++++++++
    Following is an abbreviated example of what I'm trying to do:

    In the .ascx page
    <%@register tagprefix=custom %>
    <custom:mydropdownlist></custom:mydropdownlist>

    In the .ascx.vb page

    Private Sub LoadInfoFromSession()
    mydropdownlist1.selectedvalue = 1
    mydropdownlist2.selectedvalue = 2
    mydropdownlist3.selectedvalue = 3
    End Sub

    Private Sub Page_PreRender()
    LoadInfoFromSession()
    'Note it doesn't work in Page_Load at all
    End Sub

    ..vb File that contains dropdownlist
    Public Class MyDropDownList
    Inherits dropdownlist
    End Class
    +++++++++++++++++++++++++++

    When the control containing the dropdownlists is loaded, they are all
    set to 3. I have tried using the INamingContainer, Page.Databinding,
    and a bunch of other optons. None have worked.

    If I use a system dropdownlist, I have no problems setting the
    individual values.

    Any help is greatly appreciated.

    Thanks,

    James
     
    james.e.coleman, Apr 20, 2005
    #1
    1. Advertisements

  2. james.e.coleman

    C.F. Guest

    I think I did the same thing as you do. The problem is that controls
    provides by .NET library save their property data in the ViewState and upon
    each roundtrip the previous property data will be retrieved from postback
    data. Whereas your customer control ( Assume that is your Programmically
    Created Control) does not do that. Upon each round trip they are removed and
    recreated on your webpage, if they are created dynamically.

    There are couple of solutions depends on how you create your controls
    1. Store property data of customer control explicitly in ViewState or
    Session. The problem with Session is that if you put two customer controls
    on one page, they will share the session data.
    2. If you are using non-native data type, you have to overwrite postback
    event handler to store and retrieve viewstate data.
    3. It seems if you add your customer control or user control on the .aspx
    page using VS graphic designer, (create them statically), the compiler will
    handle the ViewState processing for your customer control.

    It took some try and error session for me to be pretty good at controls. The
    following link give a good description of the background.
    http://msdn.microsoft.com/library/d...guide/html/cpconControlExecutionLifecycle.asp
     
    C.F., Apr 20, 2005
    #2
    1. Advertisements

  3. Hey C.F,

    Thanks for the response. I've started playing around with the page
    lifecycle and found that no matter where I set the value within the
    control (even in PreRender) all of the values are set the same. If
    there are controls in order A-B-C, all of the controls will always have
    the value of C. I did find that PreRender was the last function where
    it could be set, but say if I set control A in preRender after control
    C was set earlier in the page lifecycle it would still have the value
    of A.

    What I am trying to avoid is having to set a controls values within the
    page that contains it. Maybe the answer is an event handler in the
    prerender of the page that fires a reset in the control. It seems me
    to be a bit clunky, but I will try that since I just thought of it.

    Thanks again for your thoughts as you've inspired me to try things
    another way.

    James
     
    james.e.coleman, Apr 20, 2005
    #3
  4. I tried setting the values in the PAGE prerender as opposed to the
    control prerender and got the same result. All of the ddl values are
    set to the value of the last dropdownlist that was set. Very
    frustrating for one custom control.
     
    james.e.coleman, Apr 20, 2005
    #4
  5. james.e.coleman

    C.F. Guest

    Yeah, it can be frustrating sometime, but there are lots of joy when you get
    it right. Can you post some code section for us to look at? Thanks.
     
    C.F., Apr 20, 2005
    #5
  6. I'm not sure how much code to post because it would be a lot....here's
    another description:
    Here's an object heirarchy

    webpage.aspx
    placeholder
    myform.ascx
    mycustomdropdownlist

    inside myform.ascx I am trying to set the value of mycustomdropdownlist
    from session. I am just wondering why the custom dropdownlist can't be
    set, but a regular dropdownlist works just fine...

    I also figured out that the value is correct when you look at the
    object inside the myform.ascx: ie

    Public Class MyForm
    Protected withevents CustomDDL

    Private Sub LoadFromSession()
    customddl.selectedvalue = 1

    httpcontext.current.response.write(customddl.selectedvalue) 'gives the
    correct value
    End Sub
    End Class

    But the when you look inside the customDDL's onPreRender the value is
    wrong:

    Public Class CustomDDL
    Inherits dropdownlist
    Protected Overrides Sub OnPreRender(ByVal e As EventArgs)
    HttpContext.Current.Response.Write(Me.SelectedItem.Text &
    "<br>") 'this is the wrong value
    End Sub

    End Class

    I hope this helps to clarify what I'm trying to accomplish....
     
    james.e.coleman, Apr 21, 2005
    #6
  7. Basically it seems at though the default render method is what is
    killing me. It is where the values set in prerender are being
    overwritten in the custom objects. I've spent quite a bit of time
    seeing where the values get changed. The values always get changed
    AFTER prerender. All of the microsoft documentation seems to say this
    shouldn't happen, but it does. At this point, unless, I find a better
    solution, I am not going to use the custom object and use the default
    dropdownlist which works just fine. I can set instances indivdually
    from session so my back button will work correctly. Admittedly, I am a
    little disappointed what was seemingly straight forward turned into
    hours of time reviewing the page life cycle, only to find, at least
    according to my current findings that custom controls are easy for
    submit and reading but not so easy for resetting.

    Not being able to use the custom object means I'll have to rewrite my
    object using a class that will set the values for me while retaining
    the original class unaltered. So much for inheritance simplifiying
    things. I really wish that when an object was inherited it really took
    on all of the attributes of the it's parent was was treated by the
    system as such especially when key function were NOT overridden.
     
    james.e.coleman, Apr 21, 2005
    #7
  8. james.e.coleman

    C.F. Guest

    If you set the value of dropdownlist from session, do you have seperate
    session variables for each ddl? The session variables are shared among your
    pages. Is it why all ddl end up with the same value?

    Here is what I did with DDL and I did not have your problem before. In the
    customized DDL, I will overwrite CreateChildControls(). The following
    function is a ddl that shows the last few years.

    namespace PCUpload.Control

    {

    /// <summary>

    /// Summary description for DDLYear.

    /// </summary>

    [DefaultProperty("Text"),

    ToolboxData("<{0}:DDLYear runat=server></{0}:DDLYear>")]

    public class DDLYear : System.Web.UI.WebControls.DropDownList

    {

    [Bindable(true),

    Category("Appearance"),

    DefaultValue("")]

    protected override void CreateChildControls()

    {

    // get the year of last month and add other years

    int year = DateTime.Now.AddMonths(-1).Year;

    this.Items.Clear();

    this.Items.Add(new ListItem("All", "0"));

    this.Items.Add(new ListItem(Convert.ToString(year-4),
    Convert.ToString(year-4)));

    this.Items.Add(new ListItem(Convert.ToString(year-3),
    Convert.ToString(year-3)));

    this.Items.Add(new ListItem(Convert.ToString(year-2),
    Convert.ToString(year-2)));

    this.Items.Add(new ListItem(Convert.ToString(year-1),
    Convert.ToString(year-1)));

    this.Items.Add(new ListItem(Convert.ToString(year),
    Convert.ToString(year)));

    int i = Convert.ToInt16(PCUpload.Util.MySession.Year);

    this.SelectedIndex = -1;

    this.SelectedIndex = (i==0)? 0 : i-year+5; // convert to index of
    dropdownlist

    }

    }

    }


    in the user control that uses the ddl, I used the @Register to add the ddl
    statically. Upon roundtrip the DDL will remember its own selectedIndex
    value. Amazingly
    ..NET handled it for you. Hope this will help.
     
    C.F., Apr 21, 2005
    #8
  9. Thanks for the response. I really appreciate the dialog.

    Yes the session variables are different for each ddl. They are pulled
    from a single object in session that has properties for each of the
    ddls.
    within the create child controls. My custom dll adds the list items in
    the OnLoad function. Does this make a difference?

    Also, when I am setting the selected value from session, it is
    happening within the .ascx file that houses the dropdownlist thus:
    Public Class MyASCX
    Private Sub LoadInfoFromSession()
    myddl.selectedvalue = foo.value
    End Sub
    End Class

    I will try moving the add items piece to the createchildcontrols method
    and see if that fixes the problem.

    Thanks again,

    James
     
    james.e.coleman, Apr 22, 2005
    #9
  10. Ok, I've figured out what the problem was. The custom dropdownlist was
    populated by an arraylist from memory. I needed to create a new, fresh
    copy of the arraylist for each dropdownlist. So I create a function
    that did this and everything worked fine.

    Thanks for all of your help,

    James
     
    james.e.coleman, Apr 25, 2005
    #10
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.