So i've got a custom user control. I have an event (SelectionChanged) and I'm wanting to have who ever uses my control to do the following to hook up the event:
drag the control to the page
in designer mode, click on the control
view the controls event handlers (from the properties window)
find the SelectionChanged event
double click and let visual studio create the code behind function and the wire-up on the aspx page.
How do i get this done? I've got the control setup so that the user can manually type in the event wire-up and code behind event by hand, but i want Visual Studio to do this.
Currently, when the a developer has dropped my control on the page, they can click on it and see the properties but no events are available (the lightning bolt isn't even there).
My events are public. Here they are:
public delegate void SelectionChangedDelegate(object sender, SelectionChangedEventArgs e);
public event SelectionChangedDelegate SelectionChangedEvent;
I don't understand how the lightning bolt isn't there. Is your control inheriting from System.Web.UI.HtmlControls.HtmlControl or System.Web.UI.Control or another derive control?
If you are inheriting from one of these controls, you should see the inherited events in the properties window.
The fact the lightning bolt isn't there leads me to believe that you aren't inheriting from one of the the control classes.
EDIT:
Well, you're not going to like this. UserControl doesn't behave the same as a WebControl. And as such, the VS Editor doesn't wireup the events.
If the Event Wireup is critcal for you (If this is going to be a sold library) I would recommend that you rewrite the control as a WebControl. This will require you to add all the controls programatically in the CreateChildControls override method.
You might also be able to wrap your UserControl inside of a WebControl and bubble up all the events that way.
Best of luck!
Related
Allright so I have a slight issue when I want to load some basic usercontrols which contain an UpdatePanel inside to another page which is an usercontrol.
The set up:
Whenever an user clicks on a button a pop-up shows up containing some basic info on a certain person and a tab which contains the companies he worked for. The amount of companies he/she works for can range from 1 to 4~, so I do a query then for each company I get I add a view to a multiview, this view contains multiple simple user controls (Textfields inside an updatepanel). Now whenever I go to the page I get this error:
Cannot unregister UpdatePanel with ID 'UpdatePanel2' since it was not registered with the ScriptManager. This might occur if the UpdatePanel was removed from the control tree and later added again, which is not supported. Parameter name: updatePanel
Now I know this is a common error caused by generating UpdatePanels dynamically which aren't registered with the ScriptMaster. I can't add a PreInit event handler to the page which adds the UserControls with the UpdatePanels since it's an UserControl itself.
My question is:
How can I get rid of this nasty error in a not so nasty way e.g. not a hardcoded sub routine which adds the UpdatePanel to the scriptmaster
You could define the functionality you want to add inside your user controls. I have done the same in the past, adding the following, inside of my user control.
override protected void OnInit(EventArgs e) {
// your code here
}
Add a ScriptManager on your MasterPage before the UpdatePanel. And your updatePanel is a bit confusing so might change it as well. :)
As a followup to this question (https://stackoverflow.com/questions/28567211/how-to-log-control-hierarchy-in-net), is there any global way to capture all click events in either Silverlight or ASP.NET?
I am basically asking if there is some way to attach a global click event handler so that I can run some code on every click event captured against all controls that handle click events, wihtout having to add the event handlers manually to each control.
If you can, I'm wondering how this can be accomplished without having to explicitly add an event handler to every control manually. One thought I had was from a top ASP.NET page or Silverlight app to traverse the entire Control tree looking for ButtonBase controls (or the equivalent in ASP.NET) and add a new event handler for the click event. However, I don't love the idea of traversing the entire tree and doing it this way. I guess in Silverlight it wouldn't be so bad as it would only have to be done when the app is loaded, but with ASP.NET I would imagine it would happen on every PostBack?
It looks something like System.Windows.EventManager.RegisterClassHandler() would do it, but I don't believe I have access to that in Silverlight, or any equivalent in ASP.NET.
In Silverlight you can attach a mouseClick event handler to the UI tree RootElement. You do not need to traverse the tree, the mouseclick event bubble up the whole tree - even if they are handled by intermediate nodes. If you want to catch also events that are already handled, you have to specify this when attaching the handler (see the bool param in my code below).
...
var root = System.Windows.Application.Current.RootVisual;
MouseButtonEventHandler handler = HandleRootMouseLeftButtonDown;
root.AddHandler(UIElement.MouseLeftButtonDownEvent, handler, true);
...
private void HandleRootMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
// do some magic...
}
Something I have never thought too hard about but I am curiuos and want to understand the actual reasoning. In ASP.NET using VB.NET, you can define the wired up button click event (to an ASP.NET server control) in 2 different ways (for the purpose of this conversation - manually wiring up via button property not in question here):
Double click on the button in the designer which produces an event in the code behind with a Protected method.
In the code behind, select the button from the list of controls, and then select it's 'Click' event. This produces a Private method.
I understand the difference between Private and Protected; that is not in question here. I just want to know the actual reason (not guessing or speculating please) of why based on how the wired up event is autocreated it generates a different Access Level on the method?
Thanks!
The reason it's protected when declared in the control itself is the the .aspx is compiled to a class on the fly that inherits from the codebehind, so it wouldn't see the method if it was private. When the event is assigned internally to the codebehind, obviously the private member is accessible.
Both are valid approaches, just depends on how you want to skin the cat, and if a control is dynamically created, you may have to assign the event in the codebehind, so that mechanism needs to be there.
Such a simple question but if I want to add run some code in the OnPreRenderComplete Event for a Asp.Net page that inherits from a Master Page using Visual Studio Web Developer Express 2010 how can I do it?
Right clicking on the aspx page to get to properties allows me to select all the web controls in the drop down. Once I select one I can just click on the events tab and click in the event I want to have the empty method added to the .cs and register it for the event. But I don't see an option for Page.
What am I missing?
Not sure whether this feature is available in Web Developer Express but in Visual Studio you can add/select page event handler via:
Right mouse click on .aspx in solution explorer
Open "View Component Designer"
From properties windows - select "event" icon (yellow colored icon)
Double click on event name or type handler name by hand.
If AutoEventWireup page is set to "true" then the aspx page also automatically runs methods (special naming convention of page events) when certain events are raised. These names are Page_Init, Page_Load etc.
MSDN LINK : How to: Create Event Handlers in ASP.NET Web Pages
OnPreRenderComplete is a virtual method in the Page class that can be overridden with the override keyword.
protected override void OnPreRenderComplete(EventArgs e) {
// your code...
base.OnPreRenderComplete(e);
};
Don't forget, like I did, to call the base classes implementation...
actually I just remembered that I asked this very same question a while ago
and someone showed me this rather obscure way of doing it:
open the page in design view
right click on the background of the page
select view component designer
on the properties page you can now select the lightning bolt
double click an event name to generate the code
I was going through an article on event bubbling in asp.net and came to know that although it is possible to subscribe to the click event of a user control's button from the containing page, "doing so would break some of the object oriented rules of encapsulation". A better idea is to publish an event in the user control to allow any interested parties to handle the event.
My question is that exactly how does a direct subscription to the button's click event from a containing page would break the object oriented rules of encapsulation?
Apologies if its a dumb question. :|
Thanks!
The Button is supposed to be encapsulated by the UserControl.
If the Page binds directly to events on the button, then the page is now dependent on the inner workings of the UserControl.
The Page should be consuming the UserControl, not the UserControl's button. If the author of the UserControl later wants to remove the button and use some fancy new method of firing its "Submit" event, your page could be broken because the button may no longer exist.
For that matter, if the owner of the UserControl decides in v1.1 to rename the button from btnSubmit to SubmissionButton, it could break your page, as well.
Better to consume the UserControl and let it be concerned with its own inner workings.
The idea is that the button of the control is an implementation detail of the UI of the control. If you republish the click event you could reimplement that button as an ImageButton, LinkButton, etc.
I think it's OK to attach an event handler at the page level to the button if the button is a permanent fixture of the UI. It saves a lot of event code, especially with a lot of buttons.