Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#多个班级活动_C#_Class_Event Handling - Fatal编程技术网

C#多个班级活动

C#多个班级活动,c#,class,event-handling,C#,Class,Event Handling,我正在制作一个连接到多个第三方系统的程序。连接使用不同的格式,所以我创建了多个类来处理它们。我现在有三节四节课 主要形式是第一类。这是具有用户界面的基本windows窗体类 SDKCommunication是第二类 VMS(此类处理第二方系统给出的事件,并激活SDK通信的方法) 事件 事件类 public class Events { public event EventHandler LoginStateChanged; private bool loginstate;

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

  • 主要形式是第一类。这是具有用户界面的基本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());
        }
    }
}
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课程的一部分

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

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());
        }
    }
}
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类中更改时。MainForm类中需要触发一个事件。但遗憾的是,这不起作用。 但是,当我在mainform中更改loginstate时(使用按钮单击)(请参见下面的代码),就会触发事件。但这不是我想要的意图

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();
并在VM的基础上添加以下内容:

SDKCommunicatie sdkcommunicatie;
但是现在,当我试图调用SDKCommunicatie中的类时,main表单中出现了一个新错误

connectedStatus = sdkcommunicatie.connectedStatus();
我得到了以下错误:

未处理NullReferenceException


您的
SDKCommunication
类和
MainForm
类都有各自独立的
事件实例,因此您从一个类触发的任何事件都不会从另一个类中可见——它们是在完全不同的对象上引发的


您需要的是
Events
类的一个实例,
SDKCommunication
MainForm
都可以共享,这样他们就会看到相同的东西。有几种不同的方法可供选择。根据需要执行的操作,一种非常简单的可能性是将
事件设置为a,然后事件将在任何地方都可见,而无需创建任何实例。

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

编辑:
Jeremy Todd和我在同一时间写作。

您的
SDKCommunication
中的事件不会被激发,因为您已经为它创建了类
事件的单个实例。这不是您在
MainForm
上放置的实例

通过构造函数、属性或其他方式从
MainForm
sdkcommunicatione
注入正确的实例(传递引用)。例如:

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");
}
Events events;
public SDKCommunicatie(Envents eventsInstance)
{
    events = eventsInstance;
}
public void onLogon(string username, string directory, string system)
{
  events.LogInState = false;
}
SDKCommunication:

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");
}
Events events;
public SDKCommunicatie(Envents eventsInstance)
{
    events = eventsInstance;
}
public void onLogon(string username, string directory, string system)
{
  events.LogInState = false;
}
我解开了这个谜。 当我需要一个方法是一个类时,我可以像这样直接调用该方法:

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

   public MainForm()
   { 

   }

   private void Button1_Click(oject sender, EventArgs e)
   {
      sdkcommunication.method("Test")
   }
}
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 SDKCommunication
{
    method(string word)
    {
       //do something with word
    }
}
最大的问题是使用表单调用类(原始类)。我已经用eventhandler解决了这个问题

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类应该如下所示:

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

   public MainForm()
   { 

   }

   private void Button1_Click(oject sender, EventArgs e)
   {
      sdkcommunication.method("Test")
   }
}
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");
   }
}
类SDK通信
{
公共事件事件处理程序raiseCustomEventHandler 1;
受保护的虚拟无效OnRaiseCustomMeventhandler1(CustomEventHandler1 e)
{
EventHandler=RaiseCustomEventHandler1;
if(处理程序!=null)
{
处理者(本,e);
}
}
//在某处调用的自定义方法
内部无效自定义方法()
{
OnRaiseCustomMeventhandler1(新的CustomEventHandler1(“约翰史密斯”、“本地主机”);
}
}
然后在mainform类中:

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

   void sdkcommunication_RaiseCustomEventHandler1(object sender, CustomEventHandler1 e)
   {
      //Do something. 
   }
}
公共类主窗体:窗体
{
公共表格(
{
sdkcommunication.raiseCustomeMEventHandler1+=新事件处理程序(sdkcommunication\u raiseCustomeMEventHandler1);
}
无效sdkcommunication_RaiseCustomEventHandler1(对象发送者,CustomEventHandler1 e)
{
//做点什么。
}
}
与事件一起发送的信息可以通过e.Username和e.Directory获得。在本例中,它们是字符串,其中e.Username=johnsmith和e.Directory=localhost


我希望有人可以将此信息用于自己的代码。

谢谢您提供的示例代码。这看起来应该可以修复。但现在,当我的第三个类尝试调用SDKCommunitie中的方法时,我遇到了一个错误。
SDKCommunitie SDKCommunitie=new SDKCommunitie();SDKCommunitie.onLogon(username2,directory2,“Genetec Omnicast”)
我得到一个错误,由于它的保护级别而无法访问。你能给我一个例子来解决这个问题吗。@Gulpener请确保
SDKCommunication
构造函数是公共的。如果没有帮助,你需要显示你的代码谢谢你的帮助。我得到了一个新错误。我在原始帖子中添加了更改后的代码。1.Re远程协作调试代码不是这个地方的目的。可能你最好使用2.如果你想编程,你需要学习如何自己调查异常。通常异常很多,这是正常的。3.你的项目设计很糟糕,了解可靠的原则(可能在将来)如果这样做是错误的,我很抱歉。我对C语言编程很陌生,对stackoverflow也很陌生。在学习C语言的过程中,我使用了很多教程和这个网站,但从未在这个网站上提问。