c#多个类事件

本文关键字:事件 | 更新日期: 2023-09-27 18:12:28

我正在制作一个程序,可以连接多个第三方系统。连接不同的格式,所以我创建了多个类来处理它们。我现在有三节课。

  • MainForm是第一类。

  • VMS(该类处理第2方系统给出的事件并激活SDK通信方法)

  • 事件
<

事件类/strong>

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

sdkcommunication类的一部分

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

MainForm类/strong>

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

当sdkcommunication类中的LogInState发生变化时。需要在MainForm类中触发一个事件。但遗憾的是,这不起作用。但是,当我在mainform中更改登录状态(通过单击按钮)(参见下面的代码)时,将触发事件。但那不是我想要的意图。

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

如果我的问题不够清楚,请告诉我。

VMS类添加为@ asstef的回复

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未处理

c#多个类事件

您没有使用事件类的相同实例,这就是为什么在按钮单击时捕获loginstatechange。你应该注入相同的事件类的实例到SDKCommunicatie类,然后你将能够监听事件的变化。

编辑:

Jeremy Todd和我同时在写作

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

你的SDKCommunication类和MainForm类都有自己单独的Events实例,所以你从一个触发的任何事件都不会从另一个可见——它们是在一个完全不同的对象上引发的。

你需要的是Events类的一个实例,SDKCommunicationMainForm可以共享——这样它们都能看到相同的东西。你可以采用几种不同的方法。根据它需要做什么,一种非常简单的可能性可能是使Events成为静态类,然后事件将在任何地方可见,而无需创建任何实例。

我已经解开了这个谜。当我需要一个方法是一个类时,我可以像这样直接调用该方法:

public class MainForm : Form
{
   SDKCommunication sdkcommunication = new SDKCommunication();
   public MainForm()
   { 
   }
   private void Button1_Click(oject sender, EventArgs e)
   {
      sdkcommunication.method("Test")
   }
}

这很简单。看这里的receiverclass:

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. 
   }
}

与事件一起发送的信息,您可以通过e.Username和e.Directory获得。在本例中,它们是字符串,其中e.Username = johnsmith和e.Directory = localhost。

我希望有人可以使用这些信息为自己的代码。