2013-05-07 75 views
2

我正在製作一個程序,連接到多個第三方系統。連接不同的格式,所以我創建了多個類來處理它們。我現在有三個4班。C#多個類事件

  • MainForm是第一類。這是帶有用戶界面的基本Windows窗體類。

  • SDKCommunication是第二類。

  • VMS(此類處理由二路政黨制度給出的事件並激活SDK通訊方式)

  • 活動

活動類

public class Events 
{ 
    public event EventHandler LoginStateChanged; 
    private bool loginstate; 

    public bool LogInState 
    { 
     get { return this.loginstate; } 
     set 
     { 
      this.loginstate = value; 
      if (this.LoginStateChanged != null) 
       this.LoginStateChanged(this, new EventArgs()); 
     } 
    } 
} 

SDKCommunicatie類的一部分

Events events = new Events();   
public void onLogon(string username, string directory, string system) 
{ 
    events.LogInState = false; 
} 

MainForm類

SDKCommunicatie sdkcommunicatie = new SDKCommunicatie(); 
Events events = new Events(); 
public MainForm() 
{ 
    InitializeComponent(); 
    events.LoginStateChanged += new EventHandler(events_LoginStateChanged); 
} 
void events_LoginStateChanged(object sender, EventArgs e) 
{ 
    log.Info("EventFired loginstateChanged"); 
} 

當LogInState變化在SDKCommunicatie類。需要在MainForm類中觸發一個事件。但可悲的是,這是行不通的。 但是,當我更改mainform中的loginstate(使用buttonclick)時(參見下面的代碼),事件被觸發。但那不是我想要的意圖。

private void button1_Click(object sender, EventArgs e) 
{ 
     events.LogInState = true; 
} 

如果我的問題不夠清楚,請告訴我。

VMS類添加爲答覆@Astef

class VMS  { 
     private static readonly log4net.ILog log = log4net.LogManager.GetLogger(typeof(MainForm)); 
     GxUIProxyVB m_UIProxy = new GxUIProxyVB(); 

     public string username2; 
     public string directory2; 
     public string Status; 

     public void initOmni() 
     { 

      m_UIProxy.CreateInstance(); 
      m_UIProxy.OnLogon += new _IGxUIProxyVBEvents_OnLogonEventHandler(m_UIProxy_OnLogon); 
      m_UIProxy.OnLogoff += new _IGxUIProxyVBEvents_OnLogoffEventHandler(m_UIProxy_OnLogoff); 
      m_UIProxy.OnError += new _IGxUIProxyVBEvents_OnErrorEventHandler(m_UIProxy_OnError); 
      m_UIProxy.OnAlarmStatusEx2 += new _IGxUIProxyVBEvents_OnAlarmStatusEx2EventHandler(m_UIProxy_OnAlarmStatusEx2); 

     } 



     public void login(string username, string password, string directory) 
     { 
      username2 = username; 
      directory2 = directory; 
      initOmni(); 
      m_UIProxy.LogOn(directory, username, password,false); 

     } 
     public void logOff() 
     { 
      m_UIProxy.LogOff(); 
     } 

     void m_UIProxy_OnLogon() 
     { 
      SDKCommunicatie sdkcommunicatie = new SDKCommunicatie(); 
      sdkcommunicatie.onLogon(username2, directory2, "Genetec Omnicast"); 
     } 

我有固定的這個與刪除下列:

SDKCommunicatie sdkcommunicatie = new SDKCommunicatie(); 

並增加在VMS的基礎下列內容:

SDKCommunicatie sdkcommunicatie; 

但現在我得到了一個新的錯誤的MainForm當我試圖調用類的SDKCommunicatie

connectedStatus = sdkcommunicatie.connectedStatus(); 

我得到了以下錯誤:

NullReferenceException was unhandled

+0

1.遠程協作調試你的代碼不是這個地方的目的。可能是你最好使用http://codereview.stackexchange.com/ 2.如果你想編程,你需要學習如何自己調查異常。通常有很多這是正常的。 3.你的項目設計很糟糕,瞭解固體原理(未來可能) – astef 2013-05-07 08:48:49

+0

對不起,如果這是錯誤的做法。我很害怕用C#進行編程,而對於stackoverflow來說是新的。在學習C#時,我使用了很多教程和本站,但從未在本網站上提出任何問題。 – Gulpener 2013-05-07 08:58:10

回答

2

您沒有使用Events類的同一個實例,這就是爲什麼在按鈕上單擊時捕獲LoginStateChanged。您應該將相同的Events類實例注入SDKCommunicatie類,然後您將能夠聽取事件更改。

編輯: 傑里米託德和我都在同一時間寫作。

1

SDKCommunication類和你MainForm類都有的Events自己單獨的實例,因此任何從一個觸發的事件不會從另一個觸發 - 它們是在一個完全不同的對象上引發的。

你需要的是一個Events類的單個實例,SDKCommunicationMainForm都可以共享 - 這樣他們都會看到相同的東西。您可以採取幾種不同的方法。取決於它需要做什麼,一個非常簡單的可能性可能是製作Events a static class,然後這些事件在任何地方都可見而不需要創建任何實例。

2

您的SDKCommunicatie中的事件未被解僱,因爲您已爲其創建了Events類的單個實例。這不是您放置在MainForm上的實例。

通過構造函數,屬性或其他方式將正確的實例(傳遞引用)從MainForm注入到SDKCommunicatie。例如:

的MainForm:

SDKCommunicatie sdkcommunicatie; 
Events events = new Events(); 
public MainForm() 
{ 
    InitializeComponent(); 
    events.LoginStateChanged += new EventHandler(events_LoginStateChanged); 
    sdkcommunicatie = new SDKCommunicatie(events); 
} 
void events_LoginStateChanged(object sender, EventArgs e) 
{ 
    log.Info("EventFired loginstateChanged"); 
} 

SDKCommunicatie:

Events events; 
public SDKCommunicatie(Envents eventsInstance) 
{ 
    events = eventsInstance; 
} 
public void onLogon(string username, string directory, string system) 
{ 
    events.LogInState = false; 
} 
+0

感謝您的示例代碼。這看起來應該修復它。但是現在,當我的第三個類嘗試在SDKCommunicatie中調用方法時出現錯誤。 'SDKCommunicatie sdkcommunicatie = new SDKCommunicatie(); sdkcommunicatie.onLogon(username2,directory2,「Genetec Omnicast」);' 我得到了由於其保護級別而無法訪問的錯誤。你能否給我提供一個如何解決這個問題的例子。 – Gulpener 2013-05-07 07:57:37

+0

@Gulpener確保'SDKCommunicatie'構造函數是公共的。如果沒有幫助,您需要顯示您的代碼 – astef 2013-05-07 08:19:51

+0

感謝您的幫助。我有一個新的錯誤。我在原始文章中添加了更改後的代碼。 – Gulpener 2013-05-07 08:37:58

0

我已經解決了這個謎。 當我需要一個方法是I類可直接調用的方法是這樣的:

public class MainForm : Form 
{ 
    SDKCommunication sdkcommunication = new SDKCommunication(); 

    public MainForm() 
    { 

    } 

    private void Button1_Click(oject sender, EventArgs e) 
    { 
     sdkcommunication.method("Test") 
    } 
} 

這是非常簡單的。看看這裏的接收機類:

public class SDKCommunication 
{ 
    method(string word) 
    { 
     //do something with word 
    } 
} 

最大的問題是調用類(原始類)的類。我已經用事件處理程序解決了這個問題。

class CustomEventHandler1 : EventArgs 
{ 
    public CustomEventHandler1(string u, string d) 
    { 
     msgu = u; 
     msgd = d; 
    } 
    private string msgu; 
    private string msgd; 
    public string Username 
    { 
    get { return msgu; } 
    } 
    public string Directory 
    { 
    get { return msgd; } 
    } 
} 

然後SDKCOmmunication類應該是這樣的:

class SDKCommunication 
{ 
    public event EventHandler<CustomEventHandler1> RaiseCustomEventHandler1; 

    protected virtual void OnRaiseCustomEventHandler1(CustomEventHandler1 e) 
    { 
     EventHandler<CustomEventHandler1> handler = RaiseCustomEventHandler1; 
     if (handler != null) 
     { 
     handler(this,e); 
     } 
    } 

    //Custom Method that is called somewhere 
    internal void custommethod() 
    { 
     OnRaiseCustomEventHandler1(new CustomEventHandler1("johnsmith", "localhost"); 
    } 
} 

然後在MainForm類:

public class MainForm : Form 
{ 
    public MainForm() 
    { 
     sdkcommunication.RaiseCustomEventHandler1 += new EventHandler<CustomEventHandler1>(sdkcommunication_RaiseCustomEventHandler1); 
    } 

    void sdkcommunication_RaiseCustomEventHandler1(object sender, CustomEventHandler1 e) 
    { 
     //Do something. 
    } 
} 

與事件sended的信息,您可以用e.Username得到和e.Directory。在這個例子中,它們是字符串,其中e.Username = johnsmith和e.Directory = localhost。

我希望有人可以將這些信息用於他們自己的代碼。