I have several pages that all have a GridView control. Within that control there are several events that need to be implemented (OnRowDataBound, OnEditing, etc...)
Any suggestions as far as inheriting from a page that will force me (virtual functions) to implement each of these events? I can't visualize how that would look because of the GridView being a control. How do I inherit from a control?
A common way of doing this is to contain your GridView in a UserControl
If you place your grid on the user control, and subscribe to all the events there, then you can reuse this implementation anywhere you want in the application - you are essentially just wrapping the user control with the functionality you want, and then reusing this wrapper everywhere.
The neat thing is that you only have to write the wire-up code once.
That's what I think you want to do.
If you want to extend or handle these events outside the usercontrol, though, you'll need to reimplement them (i.e. add your own event handlers and let those bubble up).
You can't force anyone to subscribe to your events though.
If you wanted to force an implementation of the events then you can put the events on an interface, and implement that interface on the class or control you add it to. As the events are on the interface, you will not be able to compile until the interface has been implmented.
If you have a specific use case I can try to add an example.
Related
I have an aspx page that has two different user controls. I want to find user control A and be able to set properties, etc., from user control B.
I was thinking I could do something like this:
Dim CMFilters As Control = Me.Parent.FindControl("CMFilters")
...but that doesnt work to be able to set properties and call methods. I somehow need to get the user control and and declare it as that user control type.
You should not make control A dependent of control B.
Instead, read and write the properties of both controls from the page that contains the controls.
So expose all properties you want to set in both controls A and B as public properties (read/write or read-only) and connect them e.g. in the Page_Load event of your page.
There's an article here explaining how to do it.
I would like to note that this is not considered a good design. This is the type of thing that's referred to as a "code smell". As a general rule of thumb, objects should be designed so that they are unaware of other objects, and can function independently of other objects.
A better approach would be to simply let the objects do what they do independently, and let the page class handle the interactions, since each is a child element of the page.
This design is listed as a code smell here:
http://www.codinghorror.com/blog/2006/05/code-smells.html
Inappropriate Intimacy
Watch out for classes that spend too much time together, or classes
that interface in inappropriate ways. Classes should know as little as
possible about each other.
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.
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
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?
Lets say you need to attach some JavaScript functionality to an ASP.NET User Control of which there might be multiple instances on any given page. Because JavaScript has shared global state, what techniques can you use to keep the client state and behavior for each instance of a control separate?
Well, the main thing you can do is make sure your JavaScript functions are abstract enough that they are not coupled to specific instances of HTML controls - have them accept parameters that allow you to pass various instances of objects in.
The JavaScript that does whatever magic you need to be done should only exist once in your page regardless of how many instances of a user control you have on a given page, thus your functions need to be ignorant of that fact.
Without more information about what you are trying to do, there is little more I can offer in the way of help; it would depend on your circumstance.
EDIT: One way I have dealt with particular aspects of this problem is to create a static property on the user control (thus it is the same variable across multiple instances) that tracks the client-side IDs of the various user control elements (the user control adds the client IDs to this list in the control's OnLoad event); then, in the page's OnPreRender event (IIRC), render those out in a JavaScript variable that my code knows to look for on the client and operate on. I don't know if that makes sense, but it might help someone...
function <%=this.ClientID %>_myButton_onclick()
{
DoSomething();
}
and
<button id="myButton" onclick="<%=this.ClientID %>_myButton_onclick()">
Notice in this case the control is a regular HTML control.
If your control has more than one function, you can put it in an external js files and refer to it.
this.Page.ClientScript.RegisterClientScriptInclude("searchcontrol.js","includes/searchcontrol.js");