2014-02-19 30 views
0

我目前正致力于将一些Visual Basic .NET代码移植到c#.NET,并且我正在移植的库中有一个特定部分是我无法看到的去上班。下面是它是如何布局:通过使用事件的表单类实现接口

首先,我有一个接口定义如下:

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

接下来,我有一个实现上述接口的继承形式:

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); 
     } 
} 

到目前为止好。然后,我创建一个实现frmIMyInterface形式:

public partial class frmMyNewForm : frmIMyInterface 
{ 
... 

在这种形式,我已经定义了处理事件的方法:

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

然后,在窗体的设计代码,处理程序委托定义如下:

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

我的项目通常建立,但是,当我尝试打开frmMyNewForm与窗体设计器,我得到一个闪屏,上面写着:“为了避免在加载设计器之前可能会丢失数据,必须解决以下错误:Method'EnableSave'不能作为事件的方法,因为此类派生的类已经定义了该方法。“

我移植的VisualBasic.NET代码已经完全按照我的定义进行了定义,但工作正常。我看不到任何问题,并且似乎.NET应该知道引发事件的基类中的方法定义与作为事件处理程序设置的派生形式中定义的处理程序之间的区别。

预先感谢您!

+0

你的frmMyNewForm有*两个* EnableSave()方法。它从基类继承而来的另一个私有类。如果您打算这么做,您也会收到警告,建议使用* new *关键字。你不想这样做,没有意义。您还在frmIMyInterface.EnableSave()方法中犯了一个错误,当没有事件处理程序订阅该事件时,它会崩溃并烧毁。它也不遵循事件引发模式,它应该是一个名为OnEnableSave()的受保护的虚拟方法。请记住,C#不像VB.NET。 –

回答

0

您必须重命名您的事件处理程序或您的事件。否则,呼叫不明确。

所以此工程:

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

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

谢谢。所以...我想VisualBasic.NET只是不在乎,并没有错误地计算出来? 另外...该事件被命名为'EnableFormSave' ...因此它是不同的。 – John

+0

我的不好,拿错了代码来编辑。这一个应该工作。 –

+0

不知道为什么,我认为它不应该在那里工作。 –

0

在C#中常用的模式是名称调用事件OnEnableSave的方法,使这种虚拟的,这样派生类可以重写的行为,而不必连接到自己的事件。因此,在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); 
    } 

然后在frmMyNewForm

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

这就是说,它是相当怪异,使该调用公共事件的方法。我可能会将接口方法命名为EnableSave(),然后从该方法调用OnEnableSave()并使OnEnableSave()受保护。

+0

你能否展开你认为应该如何正确实施?我不反对改变它的做法......请记住,这是一个端口。我宁愿做得比它做得好,只是因为这是如何在VB中完成的。 :) 目标是让事件继承,并在数据更改时触发,并强制派生窗体实现方法以在事件触发时执行某些操作(如启用保存按钮)。 – John

+0

那么你的应用程序目前的结构如何?检测数据更改并调用IMyInterface.EnableSave()的代码在哪里? – Dominic

+0

对不起,仍然在学习如何在这里工作... 这个想法是,它是一个库,有一个类,你传递你的表单,它通过窗体上的所有控件旋转,并添加事件处理程序基于控件类型的相应“...更改”事件。 ' private frmIMyInterface frmFoo; if(_ctrl is TextBox){ _ctrl.TextChanged + = new EventHandler(frmFoo.EnableSave); } else if ... ' 因此,当表单构建时,它应该将事件添加到每个控件,并且当控件数据更改时,事件应该触发并允许启用保存按钮。 – John