Setting values of Controls used multiple times on a page

J

james.e.coleman

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
 
C

C.F.

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
 
J

james.e.coleman

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
 
J

james.e.coleman

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.
 
C

C.F.

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.
 
J

james.e.coleman

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....
 
J

james.e.coleman

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.
 
C

C.F.

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.
 
J

james.e.coleman

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.
From your example it looks as if you are setting the selected index
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
 
J

james.e.coleman

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
 

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. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top