In a composite control, how can I make an event fire internally?
Ie. I populate with some data, see that it's in the right condition (only one item) and then fire off my item selected event, calling the source page's OnItemSelected event.
Thanks,
Some controls implement the ISupportInitialize interface, which has the BeginInit()/EndInit() methods. If you're doing batch updates to a control you can block events using BeginInit() and after you're done call EndInit(). Finally you set the selected item to fire the event or invoke the event directly.
Related
I'm trying to add a generic MouseClick event handler for every Control in my C# Winforms Application with a recursive method, but when I get the ToolStripBar the ToolStripItems are not in the Controls list and so they are not intercepted.
Do I have to do a test like this one?
"if the Control is a ToolStripBar then for every Items ToolStripItem attach the event handler"
Is there not a more general way?
thanks a lot
I am creating a custom control. Let's say I'm reinventing the wheel and creating a custom Button control that derives from the UserControl class(only for example)
Well, it of course has a Click event handler. Now my problem is, when do I call this event handler? I know it happens sometime between the Pages OnLoad and OnLoadComplete, but I'm not quite sure what event I can hookup to so that the Click event is raised at the same time as other control events.
When are you suppose to call custom control events?
In general you should raise the event as soon as you know that the underlying event has happened.
For example, how does the ASP.NET Button control know that the it was clicked by the use? It implements IPostBackEventHandler and the RaisePostBackEvent() method. That method will get called if there is postback event data associated with the control. I believe the association is determined by the "name" attribute that it renders. In RaisePostBackEvent() it then raises the Click event.
The question you need to answer is: How does your control know that it should raise its event? Once you find that our the rest is easy.
If your control has similarities to existing ASP.NET controls I would recommend stepping through the ASP.NET source code and seeing how those controls work.
If you implement IPostbackEventHandler, you can do something like this, taken from decompiling System.Web.Ui.WebControls.Button
protected virtual void RaisePostBackEvent(string eventArgument)
{
base.ValidateEvent(this.UniqueID, eventArgument);
if (this.CausesValidation)
{
this.Page.Validate(this.ValidationGroup);
}
this.OnClick(EventArgs.Empty);
this.OnCommand(new CommandEventArgs(this.CommandName, this.CommandArgument));
}
How to get the value of usercontrol to page holding usercontrol?
If I understand correctly, the problem is that you are trying to access the user control's StudentId property in page_load of the page that hosts the user control?
If that's the case, it is quite likely that you are just trying to read the data before the user control has fired the SelectedIndexChanged event on the dropdown list.
The simplest solution is to move the code that reads the property to the Page_PreRender event. This event happens late in the page life-cycle, and after all the user events have had a chance to fire off.
As an alternative, you can expose your own event (I'll call it "UserControlDropDownChanged") in the user control and have the code in your SelectedIndexChanged event handler fire the user control's UserControlDropDownChanged event. In your page, during page_load or page_init you'd register an event handler to listen to UserControlDropDownChanged from the user control... and in that event handler perform whatever functions you need to when the drop down list's value changes.
I provided an example of how to use events this way in response to another question here on SO if you aren't familiar with this technique.
You'll need to expose this value as a public property of the user control.
Say that I have a web user control that has several drop down lists in it. They are all set to AutoPostBack = true, BUT each SelectedIndexChanged event handler in my control will fire/chain the other SelectedIndexChanged handlers I have defined for the other DDLs. This means that when the user changes a single DDL, the event handlers are chained/fired for several other DDLs. The logic for which events are chained is very complicated, data driven, and can change depending on which list was actually changed by the user. Therefore, it is very difficult to determine which event handler would fire last.
From the page's point of view, I want to subscribe to a single SelectionChanged Event on the user control that will only fire one time per postback and not until all of the event handlers have fired. I don't care which event handlers have fired, only that the state of the control as a whole has changed.
I'm using C# 3.5/ASP.NET 2.0/VisualStudio 2008
How can I go about doing this?
EDIT: Moved clarification into original description. I think the fact that I specified AutoPostBack=true without specifying that chaining was happening was misleading. I apologize for the confusion.
It depends on when you need the event handler to fire in the page lifecycle.
Here's one strategy:
1) In your user control, track the selection changing of your dropdown lists. If the event handler is executed, update your local tracking variables.
2) In your usercontrol's PreRender handler, check your tracking variables and if called for, fire the user control's SelectionChangedEvent.
This strategy will guarantee that the event handling phase of the page lifecycle is done, but has the drawback that your main page won't receive the "SelectionChanged" on your user control until the PreRender phase. This may or may not work for your situation.
If you need to handle the SelectionChanged event for your usercontrol earlier, then you will likely have to put in more complicated tracking logic in your dropdownlist handlers, and add a tracking variable to ensure that the usercontrol's "SelectionChanged" event only ever gets fired once.
I think you need to create a delgate in child control and then reference that delegate into parent control.
I have a ListView where each item has a checkbox. Initially there are no events attached and I set the state of the checkboxes programatically. After this I attach an ItemCheckedEventHandler and the event handler fires for each of the events that occurred before the handler was attached. Is there a way that I can clear the event queue before attaching the handler?
I was able to re-create when the event was added in the form constructor/InitializeComponent method.
And I was able to get around the problem by adding the event in the form's load event instead of the constructor/InitializeComponent method.
It's hacky, and I don't like it, but Application.DoEvents() might work for you.