2

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

  • MainForm 是第一类。这是带有用户界面的基本窗体类。

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

主窗体类

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

当 SDKCommunicatie 类中的 LogInState 发生变化时。需要在 MainForm 类中触发一个事件。但遗憾的是,这行不通。但是,当我更改主窗体中的登录状态时(使用按钮单击)(请参见下面的代码),该事件被触发。但这不是我想要的意图。

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;

但是现在当我尝试在 SDKCommunicatie 中调用一个类时,我在主窗体中遇到了一个新错误

connectedStatus = sdkcommunicatie.connectedStatus();

我收到以下错误:

NullReferenceException 未处理

4

4 回答 4

2

您没有使用Events 类的同一个实例,这就是为什么单击按钮时您会捕获LoginStateChanged。您应该将相同的 Events 类实例注入 SDKCommunicatie 类,然后您将能够监听事件更改。

编辑: 杰里米·托德和我同时写作。

于 2013-05-07T07:43:06.577 回答
2

你的事件SDKCommunicatie不会被触发,因为你已经Events为它创建了一个单独的类实例。那不是您放置在MainForm.

通过构造函数、属性或其他方式向SDKCommunicatiefrom注入正确的实例(传递引用) 。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");
}

SDK通讯:

Events events;
public SDKCommunicatie(Envents eventsInstance)
{
    events = eventsInstance;
}
public void onLogon(string username, string directory, string system)
{
  events.LogInState = false;
}
于 2013-05-07T07:47:42.453 回答
1

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

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

于 2013-05-07T07:40:41.153 回答
0

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

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

然后在主窗体类中:

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。

我希望有人可以将这些信息用于他们自己的代码。

于 2013-05-08T08:19:16.510 回答