user-control to nested usercontrol communication in asp.net - asp.net

I have a ProductBox.ascx user control which I use as ItemTemplate for a DataList as i have to repeat it.Now that datalist in inside a seperate user control ProductGrid.ascx.There is a third usercontrol ProductPopUp.ascx.All these controls are on page User.aspx.
I want to access ProductBox.ascx from ProductPopUp.ascx. I want a loosely coupled solution to it.
Please mind ProductBox.ascx is inside other usercontrol

Create a Public property member on the nested control and set this as required for basic passing in data/values.
Edit: If these controls are repeated etc you can then set these new properties like setting other Controls using 'FindControl' and getting a reference to the UserControl.
Is this what you're after?

I understand your desire for loose coupling as user controls ideally should be solely responsible for their appearance. However I can imagine circumstances where parent controls need to dictate their childrens' behavior.
You could bubble the DataList's data binding event up to the parent page and then manipulate each product. Just try to minimize the complexity of the interface between the parents & kids putting as much business logic inside the product controls as you can.

Related

asp.net webforms - composite controls interacting with page controls

I am writing a composite control in c# asp.net as an experiment and would like to have all the instances of my composite control interact with one external control. Is this possible?
Things I have tried:
option 1: check from within the control whether an external control exists on the page, and add it if it doesn't
option 2: have the target control's id passed to the composite control at design time and then use this.Page.FindControl()
Obviously it was wishful thinking that it would be that simple :)
If I try do this from within the CreateChildControls Method, this.Page.FindControl(target control) always returns null. If I try to add the control to the page from within this method, it throws an exception:
"The control collection cannot be modified during DataBind, Init, Load, PreRender or Unload phases."
is there another method / event where I can achieve this?
Why don't you expose a public property on your Composite Control of what output from them, then when rendering the Panel's contents, recurse through the page, find all instances of the composite control, grab the text, and add it to the panel?
You can create multiple instances on the same Web form by implementing the INamingContainer Interface. This basically helps prevent id clashes in the same namespace.
If you want to access another control set a property on it to expose the data you want made public.
Build Composite Controls

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.

ASP.NET: Bind Repeater using jQuery?

I have a Repeater control that I bind server-side. It repeats a series of divs, and does so with no problem. I have some buttons that I use to sort the repeater (newest, highest ranked, random) and this works the way it should.
I would like to improve my user experience by making the buttons sort the divs using Ajax/jQuery somehow so that there is no page postback and the user does not lose his/her spot on the page.
Is there a way to use jQuery to access server-side code like this, or use Ajax to re-bind a server-side control?
Thanks... if I need to list more details, please let me know!
EDIT I'm aware of UpdatePanels, but I would prefer not to use them if I don't have to.
Have you considered moving the Repeater's functionality to the client-side?
Doing it that way, functionality like paging and sorting is not very difficult to add. In fact, you can lean on the framework pretty heavily by using ADO.NET data services as the service layer.
It's relatively easy.
Move your repeater to a separate custom control, let's say MyControl. Now repeater in your page becomes uc1:MyControl.
Wrap MyControl into a div:
<div id="mydiv">
<uc1:MyControl ID="MyControl1" runat="server" />
</div>
Create a new page, pgMyControl.aspx, that contains MyControl only.
On your main page, add jQuery handlers to your sort links. Use load method to dynamically replace div contents:
$('#link_sort_random').click(function()
{
$("#mydiv").load("pgMyControl.aspx&sort=random");
}
Use QueryStringParameter in datasource inside MyControl to change order. Or use Request.QueryString in code-behind file.
Using an updatePanel or a jquery Ajax postback are the same thing essentially. Both will ask your code to fetch the new query, then make your control render itself, and then feed the HTML back to the client as a partial page render, and then insert the content in place of the old content in the same DOM location.
It is considerably harder to make JQuery and ASP.NET talk to each other this way due to the nature of web controls and their lifecycle that determines when they render. An updatePanel knows how to call all this, maintain proper viewstate and return the result to the correct location.
In this case, don't make things any harder on yourself, use the updatePanel unless you have some very specific reason not to.
EDIT: If you're having JQuery issues with update panels it is probably due to the fact that new DOM nodes being created. JQuery has the live event to handle this. It will notice when new DOM elements are created and match them against your selector even after the document ready.
Maybe it's an OT, but you can consider to change the way you bind even the client and the server control, using XSLT transformation instead od the classics server controls.
You can find an example here (sorry, it's in italian...).

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

How do I enable ViewState for child custom controls when disabled in parent?

I am trying to create a custom control that a "gridview" like control but specifcally for business objects that implement certain custom interfaces.
In doing this I have come across the following problem.
I have a control that I have disabled viewstate on (and I don't want to re-enable it) and it has a child control that I want viewstate enabled on. I can't seem to get the viewstate on the child control to work since its parents is disabled. Does anyone have any ideas of how to get that to work?
You cannot enable viewstate on a control which is within another control that has viewstate disabled.
Your only option is to enable it for the outer control, and then turn it off for all of the controls within it, except for the control you need viewstate.
EnableViewState property on any container will override the behavior of all controls within that containter.
Good Luck!
EDIT:
You may want to look at your CreateChildContols() method and enumerate the controls disabling viewstate from there for each of the controls within the custom control using the EnableViewState property.
If you're happy putting data into the ViewState manually (instead of letting ASP.NET preserve the state of your control for you), You could put items directly into the ViewState of the page, rather than the ViewState of your control.
I.e. instead of saying:
this.ViewState["someKey"] = someValue;
say:
this.Page.ViewState["someKey"] = someValue;
Be careful though - if you have more than one instance of your control on the page, you'll have to make sure they use different keys!
Apparently this is possible with Asp.Net 4.0

Resources