Is it the wrong way I am doing this:
- first I created a class inheriting from Combobox and I am gonna override some events, so something like this:
public override void SelectedIndexChanged(object sender, EventArgs e)
but it tells me : "There is no suitable method for override"
Thanks
You should override the method OnSelectedIndexChanged instead. The On[EventName] methods are the ones that raises the events. What you should do is to override that method, do the extra things you want to do and then call base.OnSelectedIndexChanged(e) when you want to raise the event:
protected override void OnSelectedIndexChanged(EventArgs e)
{
// do extra stuff here
base.OnSelectedIndexChanged(e);
// perhaps you want to do something after the event
// handlers have been invoked as well
}
You cannot override events. Instead you will find a method called OnSelectedIndexChanged, override this.
Related
I want to be able to execute something before the actual OnClick event is called upon a Button. I tried:
public class U_Button : Bunifu.Framework.UI.BunifuThinButton2
{
protected override void OnClick(EventArgs e)
{
MessageBox.Show("Click");
base.OnClick(e);
}
}
but the Messagebox is never shown. Any ideas why it doesn't work or how i can accomplish what i want to do? Because i want to avoid to write a check at the beginning of every OnClick event of a U_Button, so i thought i could somehow override it.
Thanks in advance!
I have an issue with overriding a method. I have created a base class with custom code that I want to run during the OnLoad event. The code in this overridden method applies to 90% of the pages that inherit from it, but on a few pages I need to override the override. My issue is that I still need to run the System.Web.UI.Page's OnLoad implementation. If I include the base.OnLoad(e) line in the second class (see below), it calls the BasePageEdit's logic, but if I remove it, the Page_Load event is never called. How can I skip over the logic in BaseEditPage's, and still get the functionality from System.Web.UI.Page?
public class BasePageEdit : System.Web.UI.Page
{
protected override void OnLoad(EventArgs e)
{
// I need this to raise the Page_Load Event!
base.OnLoad(e); // Calls System.Web.UI.Page OnLoad Event which I want.
// Logic that I want to run in ADDITION to base Implementation;
}
// Other classes and methods;
}
public class WebPageThatNeedsSpecialOnLoadImplementation : BasePageEdit
{
protected override void OnLoad(EventArgs e)
{
// I need this to raise the Page_Load Event!
base.OnLoad(e); // If I include this, it runs the BasePageEdit, I don't want that...
// But I still need to run the System.Web.UI.Page onLoad event or Page_Load will not be called.
// Logic that I want to run INSTEAD of the logic from the override from BasePageEdit.
}
}
Thank you very much Slaks! I am editing my question to show how I implemented so that others viewing this post can implement the same way if they choose!
public class BasePageEdit : System.Web.UI.Page
{
protected override void OnLoad(EventArgs e)
{
BasePage_OnLoad(e);
// Logic that I want to run in ADDITION to base Implementation;
}
protected virtual void BasePage_OnLoad(EventArgs e)
{
base.OnLoad(e);
}
// Other classes and methods;
}
public class WebPageThatNeedsSpecialOnLoadImplementation : BasePageEdit
{
protected override void OnLoad(EventArgs e)
{
BasePage_OnLoad(e);
// Logic that I want to run INSTEAD of the logic from the override from BasePageEdit.
}
}
You can't do that.
However, you can make a new method in BasePageEdit which just calls its base.OnLoad, and call that directly from the derived class instead.
I am trying to fire the Button Click event without clicking the actual button. Is there a way to invoke that? I want to call the Cancel event and here is what I have so far:
protected void Cancel(object sender, EventArgs e)
{
this.BindGridView();
}
Since all you have is this.BindGridView(), which I am assuming is just another method, you can just call that instead.
However, if you wanted to do more than just that, what I usually do is create methods for all my events in the form of OnXxx and call that from the event handler.
So for your example, you would create an OnCancel method:
private void OnCancel()
{
this.BindGridView();
}
... and then in your event handler:
protected void Cancel(object sender, EventArgs e)
{
this.OnCancel();
}
Doing this allows your event to trigger naturally and still function as well as allowing you the ability to call the same thing from anywhere within your code via this.OnCancel().
You can call the cancel method directly from within the same object:
Cancel(null,null)
Server side I've done it like this:
private void Page_Load(object sender, EventArgs e)
{
//Do something
Cancel(sender, e);
}
In my product I need process wide events. For that I used code like this:
public class Global
{
public static event EventHandler<MyEventArgs> Message;
public static void ShowMessage();
}
Now let's say I have a WinForms user interface. In form's code I will subscribe to this event and handle it in some default way (eg. by using System.Windows.Forms.MessageBox.Show() method). Now the question is how do I allow user to create derived form and override my default Message event handler implementation?
Just subscribing to the event for the second time with custom implementation doesn't solve the problem (both event handlers would be executed and potentially two message boxes shown). The options I see are either:
//call OnSubscribeToMessageEvent() from either form's constructor or OnLoad event handler
protected virtual void OnSubscribeToMessageEvent()
{
Global.Message += new EventHandler<MyEventArgs>(Global_Message);
}
private void Global_Message(object sender, MyEventArgs e)
{
//my default implementation
}
or
//subscribe in either form's constructor or OnLoad event handler
protected virtual void Global_Message(object sender, MyEventArgs e)
{
//my default implementation
}
Which version is better and why? Or maybe there are any other options?
I still have some doubts as I have never seen such a design pattern in any .NET library
Yes, you're right to worry about this. These kind of event subscriptions are very fickle, the event source always outlives the subscriber. There's only one class in the framework I know that does this, SystemEvents. The problem is that every subscriber has to very carefully unsubscribe itself when its lifetime ends or the object will stay referenced forever. A memory leak that's very hard to diagnose.
A better pattern here is to use an interface. Let's declare one:
public class MyEventArgs { /* etc.. */ }
public interface IGlobalNotification {
event EventHandler Disposed;
void OnMessage(MyEventArgs arg);
}
Now you can have a form implement the interface:
public partial class Form1 : Form, IGlobalNotification {
public Form1() {
InitializeComponent();
GlobalMessages.Register(this);
}
void IGlobalNotification.OnMessage(MyEventArgs arg) {
// do something
}
}
The Register method registers the form with the GlobalMessages class, the Dispose event ensures that the class can detect that the form is dying:
public static class GlobalMessages {
public static void Register(IGlobalNotification listener) {
listener.Disposed += delegate { listeners.Remove(listener); };
listeners.Add(listener);
}
public static void Notify(MyEventArgs arg) {
foreach (var listener in listeners) listener.OnMessage(arg);
}
private static List<IGlobalNotification> listeners = new List<IGlobalNotification>();
}
Call GlobalMessages.Notify() to get the OnMessage() method to run in all live form instances. The major advantage of this approach is that a client programmer can never screw up.
I would let the derived class override the Global_Message. The subscription to the event is generic and why would you want to implement it in every child again? It also gives you the option to call base.Global_Message(sender, e) in case your child class just wants to add some decoration to it and use the default behaviour otherwise.
I would prefer your second example, as that way, classes that extend your base class only have to override one method and do not have to remove the handler added by the base class from the event.
The key is adding the virtual keyword, so that a derived type can overide the method and the method they created will be called instead.
//subscribe in either form's constructor or OnLoad event handler
protected virtual void Global_Message(object sender, MyEventArgs e)
{
//my default implementation
}
Now that you've added virtual to both, I'd go with the first and override the one that subscribes to the event, if they didn't want the event subscribed to.
Though there is another option, call it #3.
protected EventHandler GlobalMessageEvent = new EventHandler<MyEventArgs>(Global_Message);
protected virtual void OnSubscribeToMessageEvent()
{
// this could be done in the Form_Load() or constructor instead.
Global.Message += GlobalMessageEvent;
}
Then potentially an inherited class could do somewhere: (note the -=)
{
Global.Message -= GlobalMessageEvent;
}
I am still trying to learn about c#, my question is how would I pass a variable from Item1_Click to Item2_Click, is this the same thing as passing them between methods or is this different because they are event handlers?
public partial class Events : System.Web.UI.UserControl
{
protected void Item1_Click(object sender, EventArgs e)
{
//code
}
protected void Item2_Click(object sender, EventArgs e)
{
//code
}
}
They are still regular methods, so you're still able to call them the same way you normally would.
protected void Item1_Click(object sender, EventArgs e)
{
// Call the event handler for Item2, passing the arguments
// Item1 received
Item2_Click(sender, e);
}
protected void Item2_Click(object sender, EventArgs e)
{
// Make it happen.
}
If you want to re-use Item1_Click just bind the click event of the other object to Item1_Click as well.
See the links below for some more information on events in C#.
MSDN Event Tutorial
MSDN C# Programming Guide (Events)
Event handlers are called by the publisher of the event. So you'd need to cache the value in a member variable if both handlers are in the same type. Item1 click caches something (e.g. the selection in a variable) and Item2 click uses this member variable for its own handling.
However nothing stops you from calling the event-handler#2 from event-handler#1 ; since it is a method after all. In this case, you could slot in the parameter in the EventHandler argument but it is a bit non-intuitive.
What you've shown above, is a method. It's just that I imagine you've subscribed your methods to events on a couple of buttons.
It is then up to the buttons to populate the EventArgs instances themselves. If you wish to alter what goes into an EventArgs then you'd need to inherit from a Button and override the OnClick method to fire the event manually.
You could have some state information on your form (if you want shared information between the two methods). Or if you're literally wanting to pass information from Item1_Click to Item2_click then you can just call:
protected void Item1_Click(object sender, EventArgs e)
{
this.Item2_Click(sender new EventArgs()); // <== Stick information in EventArgs
}
If you want to preserve some value from a first click you can set a variable and read it from your other handler.
public partial class Events : System.Web.UI.UserControl
{
private SomeType variable;
protected void Item1_Click(object sender, EventArgs e)
{
variable = someValue;
//code
}
protected void Item2_Click(object sender, EventArgs e)
{
//code + do stuff with variable
}
}
Event handlers are methods themselves, so no difference there. Sending data (variables if you will) between methods is done through parameters, however, Event handlers are required to have a specific signature, so you can't just add more parameters. The way to go here is to use a class member (field or property) as some sort of "global variable" (global to the class) as mentioned in #Zebi's answer
Hope this helps :)
An event handler is just a method, that is called in some specific scenario. There's nothing to prevent you from explicitlly calling those methods, so
protected void Item1_Click(object sender, EventArgs e)
{
Item2_Click(sender, e); //pass the original arguments
Item2_Click(null, null); //pass some other arguments
Item1_Click(null, null); //recursively call the handler.
}
is perfectly valid C# code. However, it's a bad practice to use event handler for anything else than, basically handling the event. If two handlers need to use some same logic, it's better to do:
protected void Item1_Click(object sender, EventArgs e)
{
CommonLogic();
}
protected void Item2_Click(object sender, EventArgs e)
{
CommonLogic();
}
private void CommonLogic()
{
//the common logic goes here
}
Instead of calling your event handler directly, you might want to create methods that wrap the functionality of Item1_Click and Item2_Click. For example..
public partial class Events : System.Web.UI.UserControl
{
protected void Item1_Click(object sender, EventArgs e)
{
var theParam = GetParamValue();
//code
Item1Method(theParam);
}
protected void Item2_Click(object sender, EventArgs e)
{
Item2Method();
}
private void Item1Method(object param1)
{
// Item 1 code goes here...
}
private void Item2Method()
{
//item 2 code goes here...
// then call Item1Method
var param2 = GetParamValue();
Item1Method(param2);
}
}
This is just an example of how to avoid calling your event handlers. Doing this will make your code more maintainable down the road.
In addition, now you don't have to worry about providing a sender and Event Args as parameters when trying to run the functionality in Item1_Click