I've got a custom control we'll call "TheGrid".
In TheGrid's controls is another control we'll call "GridMenu".
GridMenu has a button control in its own control collection.
I'd like to enable the developer using this control to associate a page level method with the OnClick of that button deep down inside GridMenu ala:
<customcontrols:TheGrid id="tehGridz" runat="server" onGridMenuButtonClick="mypagemethod" />
On the GridMenu (which I assume is another custom control), expose the event ButtonClick by declaring it as public:
public event EventHandler ButtonClick;
If you like, you can create a custom event handler by defining a delegate, and a custom event argument class. Somewhere in the logic of this control, you will need to raise the event (perhaps in the Clicked event handlers of buttons contained on GridMenu; events can cascade). Coding in C#, you'll need to check that the event is not null (meaning at least one handler is attached) before raising the event.
Now this event is visible to TheGrid, which contains your GridMenu. Now you need to create a "pass-through" to allow users of TheGrid to attach handlers without having to know about GridMenu. You can do this by specifying an event on TheGrid that resembles a property, and attaches and detaches handlers from the inner event:
public event EventHandler GridMenuButtonClick
{
add{ GridMenu.ButtonClick += value;}
remove { GridMenu.ButtonClick -= value;}
}
From the markup of a control containing a TheGrid control, you can now specify the event handler by attaching it to OnGridMenuButtonClicked the way you wanted.
You can register an event handler for this event using delegates. See the following MSDN articles:
http://msdn.microsoft.com/en-us/library/system.eventhandler%28VS.71%29.aspx
http://msdn.microsoft.com/en-us/library/aa720047%28v=VS.71%29.aspx
Related
I have a user control that contains a textbox and some buttons.
I can't respond to the text changed event from the textbox from outside of that user control (say from the parent form that the control is placed on).
How can I get an event that raised when the text has changed from outside of the user control?
Please see this answer on how to create a custom event in WPF.
Following this approach, you can handle the "TextChanged" event for the textbox inside your user control, then raise a custom event from there.
in your textcontrol event change, put this:
Me.OnTextChanged(e)
Or create your own event
Upper code:
Public Event ClaveModificada(Causa As String)
and when you need:
RaiseEvent ClaveModificada("")
My understanding about events in C# for a console application:
create a delegate that has the same signature as the event handler method in the subscriber class.
declare an event based on this delegate
raise the event
My understanding of this step is: it is simply an wrapper function where parameters are passed to the event to invoke the event handler functions pointed to by the event.
So raising the event is just invoking the wrapper function in the publish class.
Now when I create a very simple Windows form application, I am not able to apply this general concept.
Consider a WinForms application with just one button.
// registering statement
Button1.Click += new EventHandler (this.button1_click)
I can identify the first step. It is the pre-defined System.EventHandler delegate.
Click event for the button is also pre-defined. No problem with that.
event raising step : here I fail to make the connection between a console application and an Windows application.
Where is the code kept that actually RAISES the event for a WinForms application? We don't seem to have to code it.
I understand click event is raised when someone "clicks" on the button, but how is that realized in the C# code for WinForms application?
How does the compiler "just" knows that a Click event for a button means someone clicking on a button and therefore an event should be raised?
How is click event raised? How are the parameters passed to the event?
The Control class has protected function called WndProc, when the OS needs to tell the program something it generates a Message object and passes it in to the WndProc function.
That WndProc function then looks at the message and sees what kind of message it is, if it is the "mouse left button up" message it runs the the OnClick method with the correct parameters parsed out of the Message object that was passed in to WndProc.
That OnClick method is the thing that raises the event to the subscriber.
From the soruce of .NET:
The entry point of WndProc
It detecting the message type
It parsing and calling the OnClick method
It raising the Click event
Your understanding is a bit backwards. I think this is why you have issues.
You are not creating a delegate that has the same signature as the event handler method in the subscriber class.
What you are doing is declaring what a function to which to delegate execution will look like. Here is the signature for EventHandler:
public delegate void EventHandler(object sender, EventArgs e)
So, if you want a function to be able to handle delegation of the event, it must follow that signature.
Now, the class that will delegate execution to subscribers needs a reference to those functions so it can call them when the event takes place. That is why you implement an event property. It follows then that the Button class must expose this property for you to be able to "hook" your delegates:
public event EventHandler Click
(Notice this is inherited from Control)
When you register an "event handler":
Button1.Click += new EventHandler (this.button1_click)
You are essentially saying that you want this.button1_click(object sender, EventArgs e) to fire whenever the Click event is raised by the Button1 instance.
The Button1 instance will internally decide when to fire the event at which point it will use the event property to delegate execution to the subscribed functions. It will call them with the above mentioned parameters where sender will most likely be the instance itself and the EventArgs class will give you additional information about the conditions that raised the event. The property is also usually implemented to add additional checks (like if there is anything to call in the first place).
As you can see, the code that actually raises the click is internal to the implementation of the Button (or its inheritance chain). It obviously involves mouse tracking and what not, which is the benefit of using the controls by the way, unless you want to write all that detection stuff from scratch.
Quick one:
I've created
public event GridViewEditEventHandler invGridEdit {}.
Can I put code in this event to allow my end user to edit the DB entry, or do I need to point this to a new method for editing?
Edit: It's probably obvious that this is the first time I've looked at events. My apologies if this is a stupid question.
Check the documentation.
In general you have to register your own methods on specific events:
When you create a GridViewEditEventHandler delegate, you identify the
method that will handle the event. To associate the event with your
event handler, add an instance of the delegate to the event. The event
handler is called whenever the event occurs, unless you remove the
delegate. For more information about event-handler delegates, see
Events and Delegates.
In your case:
gridview.RowEditing += new GridViewEditEventHandler(myEditHandler);
Registered methods must have the signature your handler expects. In your case it's the delegate
public delegate void GridViewEditEventHandler(
Object sender,
GridViewEditEventArgs e
)
So the method myEditHandler looks like
void myEditHandler(Object sender, GridViewEditEventArgs e)
To access the firing gridview, perform a cast on sender:
GridView gv = (GridView)sender;
Your method is now called, if the event RowEditing is fired. This is the case, when:
The RowEditing event is raised when an Edit button (a button with its
CommandName property set to "Edit") is clicked, but before the
GridView control enters edit mode. This allows you to provide an
event-handling method that performs a custom routine, such as
canceling the edit operation, whenever this event occurs.
Hope it helps =)
Basically this is for any code you want to run to set up the editing on the grid.
From here:
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.gridviewediteventhandler(v=vs.110).aspx
The RowEditing event is raised when an Edit button (a button with its CommandName property set to "Edit") is clicked, but before the GridView control enters edit mode. This allows you to provide an event-handling method that performs a custom routine, such as canceling the edit operation, whenever this event occurs.
When you create a GridViewEditEventHandler delegate, you identify the method that will handle the event. To associate the event with your event handler, add an instance of the delegate to the event. The event handler is called whenever the event occurs, unless you remove the delegate. For more information about event-handler delegates, see Events and Delegates.
My UserControl contains various controls. I made an event handler for its click event. I want the event handler to fire / be called when the user clicks anywhere on my user control.
This is the method I use to add my UserControl to my WinForms application.
private void addContact(some parameters here)
{
//This is my usercontrol
contactsListItem.contactsListItem contact = new contactsListItem.contactsListItem();
//
//some codes here
//
//Adding an event handler for the click event
contact.Click += new EventHandler(contact_Click);
//Adding the UserControl to my application
flowLayoutPanel_contactsList.Controls.Add(contact);
}
The contact_Click(...) event handler should change the background of my UserControl. I have tried stepping into the code to see if the event handler fires and I found out that it doesn't fire no matter where I click on my UserControl.
I have searched through the internet. I encountered terms like delegate, subscribers and publishers.
What should I do to make the event handler for my UserControl's click event to fire?
What is the structure of your user control? Click events are not bubbled in WindForms, hence if you are clicking on a control WITHIN your user control, the latter won't fire any Click event.
EDIT:
The simplest solution is to manually bubble the event from each child by attaching a handler in your user control:
child1.Click += new EventHandler(child_Click);
child2.Click += new EventHandler(child_Click);
child3.Click += new EventHandler(child_Click);
and inside child_Click fire off your Click event:
this.OnClick(e);
You seem to be on the right track however it is not clear what your contact here is. Typically you use delegates (essentially pointers to functions) for methods that have arguments to be passed:
if (bDeleteRdClick)
DeleteRD.Click -= delegate { DeleteRDClick(this.Object); };
DeleteRD.Click += delegate { DeleteRDClick(this.Object); };
where you are sure to remove pre-existing delegates, otherwise they will 'stack-up', firing multiple methods when not required.
For the method above, using an EventHandler seems to me to be the right approach, but as I state above, a check on whether contact is of the correct type would not go unmissed:
if (this.contact.GetType() == typeof(RibbonButton))
{
RibbonButton Rb = (RibbonButton)contact;
Rb.Click += new EventHandler(contact_Click);
}
I hope this is of some help.
I have some user controls. The hierarchy is as follows:
A contains B
B contains C
Inside my C control I have a button. When I click on it want my event
public event EventHandler Print;
to by raised and then I want control A to catch this event. How can I do this?
EDIT 1:
I want to raise my event on User Control C's ViewModel
There are 2 topics that can help you fulfill your need:
Commanding
and
Routed Events
Both mechanisms are built specifically for wpf's hierarchical structure.
Read up on both, they will help your wpf experience immeasurably.
EDIT: Something more helpful. Put Button.Click="" on the control where you want to catch the event. You can use the button's Tag property to store identifying information so your event handler knows that the correct button was clicked.
<Grid Button.Click="Button_ClickHandler">
<Button Tag="PrintButton/>
</Grid>
In your code behind for the user control you will require the handler named Button_ClickHandler.
The above method uses Router Events. I really recommend using Commands however.
You can wrap the event like so:
class B
{
private A a;
public event EventHandler Print
{
add { a.Print += value; }
remove { a.Print -= value; }
}
}
I think you want to look at bubbling events.
Update: I didn't see the wpf tag, you should be looking at routed events