事件处理程序始终为null! [英] Event handlers are always null!

查看:87
本文介绍了事件处理程序始终为null!的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个班级 - 比如A级 - 在其中声明了一个简单的事件处理程序,以及触发该事件的空格:



公共类A 
{
公共事件EventHandler MyEvent;

private void FireEvent()
{
if(MyEvent!= null)
MyEvent(this,EventArgs.Empty);
}
}





另一个类在其构造函数中订阅该事件:



公共等级B 
{
public B()
{
B myInstanceOfB = new B();
MyInstanceOfB.MyEvent + = MyEvent_EventHandler;
}
}





问题是,当我在A类中调用MyEvent时,B类没有'响应,MyEvent显示为null。知道为什么以及如何修复它?提前感谢任何提出答案的人!

解决方案

当然是......你创建了一个实例(即使你写了我也假设它B),然后设置事件处理程序,让A超出范围,处理它。如果你想保留引用并使你的活动有效,B类看起来应该更像:



  public   class  B 
{
myInstanceOfA;

public B()
{
myInstanceOfA = new A();
MyInstanceOfA.MyEvent + = MyEvent_EventHandler;
}
}





由于引用在B的生命周期内保持活动,因此事件处理程序也将保持活动状态。





为了回应您的更多信息,这是我做的测试:



  class 程序
{
static void Main( string [] args)
{
B myB = new B();
myB.MyA.RaiseEvent();

Console.ReadKey();
}
}

class A
{
public event EventHandler MyEvent;

public void RaiseEvent()
{
Console.WriteLine( Raising Event);
Console.WriteLine( 事件处理程序是 +(MyEvent == null null set));
if (MyEvent!= null
MyEvent( this ,EventArgs.Empty);
}
}

class B:INotifyPropertyChanged
{
private A _myA;

public A MyA
{
get { return _myA; }
set
{
if (_ myA!= value
{
_myA = value ;
OnPropertyChanged( MyA);
}
}
}

public B()
{
MyA = new A();
MyA.MyEvent + = MyA_MyEvent;
}

void MyA_MyEvent( object sender,EventArgs e)
{
Console.WriteLine( 从A获得事件);
}

public event PropertyChangedEventHandler PropertyChanged;

受保护 虚拟 void OnPropertyChanged( string propertyName)
{
if (PropertyChanged!= null
PropertyChanged( this new PropertyChangedEventArgs(propertyName));
}
}





输出为:



提高事件
事件处理程序设置
从A

获得事件



所以我不确定你做错了什么。您可以将上述内容复制/粘贴到控制台应用程序中并查看它是否有效。


Ron,感谢您的解决方案!我真的错过了范围问题 - 必须是头脑风暴或其他什么!我改变了这样:



公共等级B 
{
public B()
{
MyInstanceOfA = new A();
MyInstanceOfA.MyEvent + = MyEvent_EventHandler;
}

private A _MyInstanceOfA;

public A MyInstanceOfA
{
get {return _MyInstanceOfA;}
set
{
if(_MyInstanceOfA!= value)
{
_MyInstanceOfA = value;
OnPropertyChanged(MyInstanceOfA);
}
}
}
}





...当然,当然,您应该认识到众所周知的属性更改通知模式(因为该实例必须绑定)。但是再次...... 它不起作用! :(





更新:这个darned实例在其他地方实现了!!!!!!我一定是非常愚蠢的错过了!!!!!!!!


I have a class - say class A - with a simple event handler declared in it, and a void to fire that event:

public class A
{
    public event EventHandler MyEvent;

    private void FireEvent()
    {
        if (MyEvent != null)
            MyEvent(this,EventArgs.Empty);
    }
}



Another class subscribes to that event within it's constructor:

public class B
{
    public B()
    {
        B myInstanceOfB=new B();
        MyInstanceOfB.MyEvent+=MyEvent_EventHandler;
    }
}



The problem is that, when I call MyEvent within class A, class B doesn't react and MyEvent shows null. Any idea why and how it might be fixed? Thanks in advance to anyone who comes up with an answer!

解决方案

Of course it is... You create an instance of (I assume its A even though you wrote B), and then set up the event handler, and let A go out of scope, which disposes it. If you want to hold references and have your events work, class B should look more like this:

public class B
{
    A myInstanceOfA;

    public B()
    {
        myInstanceOfA = new A();
        MyInstanceOfA.MyEvent+=MyEvent_EventHandler;
    }
}



Since the reference is kept alive for the life of B, so will the event handler.

[Edit]
In response to your additional information, here is a test I made:

class Program
{
    static void Main(string[] args)
    {
        B myB = new B();
        myB.MyA.RaiseEvent();

        Console.ReadKey();
    }
}

class A
{
    public event EventHandler MyEvent;

    public void RaiseEvent()
    {
        Console.WriteLine("Raising Event");
        Console.WriteLine("Event handler is " + (MyEvent == null ? "null" : "set"));
        if (MyEvent != null)
            MyEvent(this, EventArgs.Empty);
    }
}

class B : INotifyPropertyChanged
{
    private A _myA;

    public A MyA
    {
        get { return _myA; }
        set
        {
            if (_myA != value)
            {
                _myA = value;
                OnPropertyChanged("MyA");
            }
        }
    }

    public B()
    {
        MyA = new A();
        MyA.MyEvent += MyA_MyEvent;
    }

    void MyA_MyEvent(object sender, EventArgs e)
    {
        Console.WriteLine("Got event from A");
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}



And the output is:

Raising Event
Event handler is set
Got event from A



So I'm not sure what you are doing wrong. You can copy/paste the above into a console application and see it work.


Ron, thanks for the solution! I really missed the issue of scope - must be brainstorming or something! I changed it like that:

public class B
{
    public B()
    {
        MyInstanceOfA = new A();
        MyInstanceOfA.MyEvent+=MyEvent_EventHandler;
    }

    private A _MyInstanceOfA;

    public A MyInstanceOfA
    {
        get{return _MyInstanceOfA;}
        set
        {
            if (_MyInstanceOfA!=value)
            {
                _MyInstanceOfA=value;
                OnPropertyChanged("MyInstanceOfA");
            }
        }
    }
}



...where, of course, you should recognize the well known pattern of property changed notification (since that instance has to be binded).But again...it doesn't work! :(


Update: The darned instance was instanciated somewhere else!!!!!! I must be really stupid to have missed that!!!!!!!!


这篇关于事件处理程序始终为null!的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆