ASP.net: How to handle events from dynamically added controls? - asp.net

So I have a number of user control dynamically added to a page, and user interaction with these dynamically added user controls need to be handled by the control's parent.
Is this what is referred to as "event bubbling"?
How do I do that in VB?
Thanks in advance.

First, you have several complex issues here and my initial thought is that you should separate them and attack each on its own until you have it working and then add them into the final solution. For instance, don't try to start off by dynamically creating your user control and getting it to expose and fire an event. The dynamic part of this problem could get in the way and cause your events not to work but you would never know which is the problem. Instead my recommendation is you focus on events in VB.NET and getting them to work from a statically created user control. Then once you have this all working, move to making the user control dynamically created.
As far as understanding events in VB.NET, I highly recommend the MSDN samples. Start with this simple example: How to: Raise an Event (Visual Basic) and then follow through with the other samples that are linked to from that page. Then once you have learned creating your own events in VB.NET, then look into adding a usercontrol dynamically.
Event bubbling is when a parent control handles an event from a child. So, yes, this is what you are trying to do.

I am not sure of VB but in c# you can use following
id.event+=eventhandler yourEvent;

My first response to this kind of question is always this - why are you dynamically adding the controls? Could they go into a repeater (where this becomes a lot simpler), or must they be programatically handled?

Related

Dynamic adding controls during OnLoad or OnInit?

I want to add more controls to page based on some specific conditions. Those controls don't need any ViewState or binding data, it is as simple as a static link.
I wonder where I could write the code: inside OnLoad or OnInit method? and why? If I place it inside OnLoad, should I add following line: if (IsPostBack) return; before any initialization code?
You can add controls in either the OnInit method or OnLoad, whether they need view state or not. (The reason why is because as soon as you add a control to the Page the control loads its view state, even if you add it after the LoadViewState stage...)
should I add following line: if (IsPostBack) return; before any initialization code?
No. It is imperative that your dynamically added controls are added to the control hierarchy on every page load, not just the initial one.
If you are going to work with dynamically-added Web controls, I strongly suggest you read these two articles:
Dynamic Controls in ASP.NET (This is actually three articles, this being the first in a series.)
Creating Dynamic Data Entry User Interfaces
For a working, end-to-end example of dynamically loading controls based on some external conditions (such as configuration in a database), see Creating a Dynamic Data-Driven User Interface.
Happy Programming!
I would suggest just adding the controls to the page statically and toggling their visibility to "True" when the conditions are met. They won't render anything to the page when they're invisible, and this will save you a lot of headaches, especially since it sounds like you're fairly new to dynamic controls.
I'm not sure I fully understand, but I'd personally put an asp:Literal on the page (or several if you need them in different places) and then create the HTML you need in the OnLoad event.
If you do that, then the html you put into that literal will be saved in viewstate, and therefor you won't have redo it on postback.
http://chetanwarade.wordpress.com/2010/08/21/asp-net-add-dynamic-control-and-retrieve-dynamic-control-value-2/
Here is code that demonstrate how to add dynamic control and retrieve dynamic control value.

Dynamically creating many instances of ASP.NET usercontrols: How do I create it, and where will my conflicts be?

I haven't seen this implemented before in ASP.NET, but am thinking about a UI that would look and act like this:
Conceptual Overview
A TabControl is loaded and the first tab contains a grid
When a row is double-clicked, a new tab is created with the record detail
The content of the tab/record detail is created by a usercontrol
Many tabs could be created, and therefore many instances of the usercontrol will be created
I know ASP.NET will rename my (runat="server") ID's for me, and that I can use jQuery or ASP.NET server-side code to work with the ID's... My concerns are:
How can I ask ASP.NET to generate a unique ID for each Nth instance of my usercontrol (to be rendered in a placeholder)
How do I actually create that extra instance of the control?
What else do I need to keep in mind?
Since I don't want postbacks I'm considering basing my implementation off of ComponentArt's Callback Control, and using ASP.net usercontrols to achieve this effect. This will allow me to do most things that require a postback, but won't refresh all the elements on a page... just the section that contains the user control. That being said, I'm not tied to a particular implementation.
You should look into the Page.LoadControl method. It works nicely and as far as I remember you put placeholders on your page and load the controls into the PlaceHolders, that's how you control the ids.
One thing that doesn't work out so well with this approach is when your control raises events that your Page object has to handle. If your control is selfcontained however you shouldn't have a problem.
This might help you get started:
http://www.codeproject.com/KB/aspnet/LoadingUSerControl.aspx

ASP.NET: How to initialize when *user control* is initially loaded

I have an ASP.NET user control that I'm embedding in another user control. This works fine.
I need to know the best logic/method for detecting when the control is loaded. In other words, I have some display initialization logic that needs to run when the control is initially displayed. Surely there is a pattern for this.
The typical method is to put (!IsPostBack) logic in the Page_Load method of the control. This works great until you end up with a state when the Parent page has already posted back many times. My user control gets added to the page but its display does not intialize properly.
I'm hoping to find a way that keeps this logic inside the control, versus various hacking around in the codebehind of the parent page.
See the following MS article. They have an example that places several controls within a user control and initializes them.
There is another post here on StackOverflow that seems similar. You may want to check it out, and see if it points you in the right direction.
It may also be helpful to review the page life-cycle and events.

Dynamically added controls in Asp.Net

I'm trying to wrap my head around asp.net. I have a background as a long time php developer, but I'm now facing the task of learning asp.net and I'm having some trouble with it. It might very well be because I'm trying to force the framework into something it is not intended for - so I'd like to learn how to do it "the right way". :-)
My problem is how to add controls to a page programmatically at runtime. As far as I can figure out you need to create the controls at page_init as they otherwise disappears at the next PostBack. But many times I'm facing the problem that I don't know which controls to add in page_init as it is dependent on values from at previous PostBack.
A simple scenario could be a form with a dropdown control added in the designer. The dropdown is set to AutoPostBack. When the PostBack occur I need to render one or more controls denepending on the selected value from the dropdown control and preferably have those controls act as if they had been added by the design (as in "when posted back, behave "properly").
Am I going down the wrong path here?
I agree with the other points made here "If you can get out of creating controls dynamically, then do so..." (by #Jesper Blad Jenson aka) but here is a trick I worked out with dynamically created controls in the past.
The problem becomes chicken and the egg. You need your ViewState to create the control tree and you need your control tree created to get at your ViewState. Well, that's almost correct. There is a way to get at your ViewState values just before the rest of the tree is populated. That is by overriding LoadViewState(...) and SaveViewState(...).
In SaveViewState store the control you wish to create:
protected override object SaveViewState()
{
object[] myState = new object[2];
myState[0] = base.SaveViewState();
myState[1] = controlPickerDropDown.SelectedValue;
return myState
}
When the framework calls your "LoadViewState" override you'll get back the exact object you returned from "SaveViewState":
protected override void LoadViewState(object savedState)
{
object[] myState = (object[])savedState;
// Here is the trick, use the value you saved here to create your control tree.
CreateControlBasedOnDropDownValue(myState[1]);
// Call the base method to ensure everything works correctly.
base.LoadViewState(myState[0]);
}
I've used this successfully to create ASP.Net pages where a DataSet was serialised to the ViewState to store changes to an entire grid of data allowing the user to make multiple edits with PostBacks and finally commit all their changes in a single "Save" operation.
You must add your control inside OnInit event and viewstate will be preserved. Don't use if(ispostback), because controls must be added every time, event in postback!
(De)Serialization of viewstate happens after OnInit and before OnLoad, so your viewstate persistence provider will see dynamically added controls if they are added in OnInit.
But in scenario you're describing, probably multiview or simple hide/show (visible property) will be better solution.
It's because in OnInit event, when you must read dropdown and add new controls, viewstate isn't read (deserialized) yet and you don't know what did user choose! (you can do request.form(), but that feels kinda wrong)
After having wrestled with this problem for at while I have come up with these groundrules which seems to work, but YMMV.
Use declarative controls whenever possible
Use databinding where possible
Understand how ViewState works
The Visibilty property can go a long way
If you must use add controls in an event handler use Aydsman's tip and recreate the controls in an overridden LoadViewState.
TRULY Understanding ViewState is a must-read.
Understanding Dynamic Controls By Example shows some techniques on how to use databinding instead of dynamic controls.
TRULY Understanding Dynamic Controls also clarifies techniques which can be used to avoid dynamic controls.
Hope this helps others with same problems.
If you truly need to use dynamic controls, the following should work:
In OnInit, recreate the exact same control hierarchy that was on the page when the previous request was fulfilled. (If this isn't the initial request, of course)
After OnInit, the framework will load the viewstate from the previous request and all your controls should be in a stable state now.
In OnLoad, remove the controls that are not required and add the necessary ones. You will also have to somehow save the current control tree at this point, to be used in the first step during the following request. You could use a session variable that dictates how the dynamic control tree was created. I even stored the whole Controls collection in the session once (put aside your pitchforks, it was just for a demo).
Re-adding the "stale" controls that you will not need and will be removed at OnLoad anyway seems a bit quirky, but Asp.Net was not really designed with dynamic control creation in mind. If the exact same control hierarchy is not preserved during viewstate loading, all kinds of hard-to find bugs begin lurking in the page, because states of older controls are loaded into newly added ones.
Read up on Asp.Net page life cycle and especially on how the viewstate works and it will become clear.
Edit: This is a very good article about how viewstate behaves and what you should consider while dealing with dynamic controls: <Link>
Well. If you can get out of creating controls dynamicly, then do so - otherwise, what i whould do is to use Page_Load instead of Page_Init, but instead of placing stuff inside the If Not IsPostBack, then set i just directly in the method.
Ah, that's the problem with the leaky abstraction of ASP.NET web forms.
Maybe you'll be interested to look at ASP.NET MVC, which was used for the creation of this stackoverflow.com web site? That should be an easier fit for you, coming from a PHP (thus, pedal-to-the-metal when it comes to HTML and Javascript) background.
I think the answer here is in the MultiView control, so that for example the dropdown switches between different views in the multi-view.
You can probably even data-bind the current view property of the multiview to the value of the dropdown!
The only correct answer was given by Aydsman. LoadViewState is the only place to add dynamic controls where their viewstate values will be restored when recreated and you can access the viewstate in order to determine which controls to add.
I ran across this in the book "Pro ASP.NET 3.5 in C# 2008" under the section Dynamic Control Creation:
If you need to re-create a control multiple times, you should perform the control creation in the Page.Load event handler. This has the additional benefit of allowing you to use view state with your dynamic control. Even though view state is normally restored before the Page.Load event, if you create a control in the handler for the Page.Load event, ASP.NET will apply any view state information that it has after the Page.Load event handler ends. This process is automatic.
I have not tested this, but you might look into it.

How to retrieve data from dynamically added textboxes?

Im adding textboxes (not a fixed number of textboxes) dynamically to a form on ASP.NET page, how do i read back data from these textboxes?
Assuming you're wanting to access the controls on the postback you'd probably re-create the dynamic controls exactly as they were created on the initial load, then use the page's FindControls method to find the controls. It would probably help to create the textboxes with IDs like Textbox1, Textbox2, etc.
Look at Request.Params and extract them from there. You will, of course, have to give them ids to be able to tell them apart.
From all the ASP.NET apps I've worked with, .NET likes to use the following algorithm when generating the Id for server controls:
ctl00$cphBody$[ControlID]
Try using this algorithm when accessing your data from the dynamically generated textboxes.
When you add them you should be giving them names/ids, and you can use those to reference them.
If not, walk your DOM in javascript to find them inside the form you made - they'll be in the same order you inserted them.
Lastly, they're all available as post/get inputs to your page, so you should be able to look at them all as long as you assigned them different names.
-Adam
When creating textboxes dynamically (presumably using JavaScript, but same goes for ASP.NET controls) give them names in a specific pattern. The one you will be able to recognize later.
On server-side, in any event handler occurring after Page_Init you can iterate through Request.Form collection.
Do not be tempted to use Request.Param because it can be used to apply cross-site request forgery on your application (an attacker could lure user into issuing a GET request which your application would interpret the same as it would interpret a POST one, which is usually not a good thing).
If you are adding dynamic ASP.NET controls (in Page_Render for example) you can also reconstruct controls and use their properties.
You can use FindControl and pass the textbox ID to get an instance of the textbox when post back. The Text property contains the data, given that we are at page load stage or later in the cycle.
When adding dynamic controls, override the CreateChildControls method and add the dynamic controls to control hierarchy at this stage of the cycle.
Remember that in ASP.Net, every postback is a new instance of your class. If you created these controls during a previous postback or on the first view then they were garbage collected with the rest of that previous instance. So to use the controls in this new instance, you need to create them again. If you need the state information loaded for those controls (including any value entered by the user), you also need to create before the viewstate is loaded, meaning you do it during the Init event, rather than the load event.
To create dynamic controls, I would usually use a ASP.NET PlaceHolder Control and add the dynamic controls to this container.
I would give each dynamic control an ID.
You can then subsequently use FindControl on the PlaceHolder to access the dynamic controls.
I say "dynamic controls" to mean controls you add at run-time

Resources