2014-02-19 38 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