我正在制作一个程序,可以连接多个第三方系统。连接不同的格式,所以我创建了多个类来处理它们。我现在有三节课。
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未处理
您没有使用事件类的相同实例,这就是为什么在按钮单击时捕获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
类的一个实例,SDKCommunication
和MainForm
可以共享——这样它们都能看到相同的东西。你可以采用几种不同的方法。根据它需要做什么,一种非常简单的可能性可能是使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。
我希望有人可以使用这些信息为自己的代码。