简体   繁体   中英

Implementing an interface through a form class using an event

I'm currently working on porting over some Visual Basic .NET code to c# .NET, and there's a particular part of the library I'm porting that I can't seem to get to work. Here's how it's laid out:

First, I have an interface defined as follows:

public interface IMyInterface
{
      void EnableSave(object sender, EventArgs e);
}

Next, I have an inheritable form that implements the above interface:

public partial class frmIMyInterface : Form, Globals.IMyInterface
{
      public delegate void EnableFormSaveEventHandler(object sender, EventArgs e);
      public event EnableFormSaveEventHandler EnableFormSave;

      public void EnableSave(object sender, EventArgs e)
      {
            EnableFormSave.Invoke(sender, e);
      }
}

So far so good. Then, I create a form that implements frmIMyInterface:

public partial class frmMyNewForm : frmIMyInterface
{
...

In that form, I have a method defined to handle the event:

private void EnableSave(object sender, EventArgs e)
{
    this.cmdSave.Enabled = true;
}

Then, in the designer code for the form, the handler delegate is defined as follows:

this.EnableFormSave += new frmIMyInterface.EnableFormSaveEventHandler(this.EnableSave);

My project builds normally, however, when I try to open frmMyNewForm with the form designer, I get a splash screen that says, "To prevent possible data loss before loading the designer, the following errors must be resolved: The Method 'EnableSave' cannot be the method for an event because a class this class derives from already defines the method."

The VisualBasic.NET code that I ported had everything defined exactly as I have it defined, but worked fine. I can't see any problem, and it seems like .NET should know the difference between the method definition in the base class that raises the event, and the handler defined in the derived form that gets set as the event handler.

Thank you in advance!

You have to rename either your event handler or your event. Otherwise the call is ambiguous.

So this works:

this.EnableFormSave += new frmIBGInterface.EnableFormSaveEventHandler(this.OnEnableSave);

private void OnEnableSave(object sender, EventArgs e)
{
    this.cmdSave.Enabled = true;
}

The usual pattern in c# is to name the method that invokes the event OnEnableSave, and make this virtual so that derived classes can override the behaviour without having to attach to their own events. So in frmIMyInterface:

public virtual void OnEnableSave(EventArgs e)
  {
        //EnableFormSave.Invoke(sender, e);

        // This is the usual way to invoke an event in c#
        var handler = EnableFormSave;
        if (handler != null) handler(this, e);
  }

then in frmMyNewForm

public override void OnEnableSave(EventArgs e)
{
    base.OnEnableSave(e);
    this.cmdSave.Enabled = true;
}

That said, it's quite weird to make methods that invoke events public. I'd probably name the interface method something like EnableSave(), and then call OnEnableSave() from that method and make OnEnableSave() protected.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM