C#冒泡/传播一次事件 [英] C# Bubbling/Passing Along An Event

查看:136
本文介绍了C#冒泡/传播一次事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我知道这听起来很可笑(就是这样),但是在过去的一段时间里,而。搜索没有出现类似的问题,所以我想我会提出它。



这里是涉及的对象:

  WinForm  - >扬声器 - > Tweeter 
- > Woofer

[Speaker,Tweeter,Woofer]都声明一个SpeakToMe事件,发送一个简单的字符串消息。事件使用标准模式声明:

  public delegate void SpeakToMeHandler(object sender,SpeakToMeEventArgs e); 
public event SpeakToMeHandler SpeakToMe;
protected virtual void OnSpeakToMe(string message)
{
if(SpeakToMe!= null)SpeakToMe(这是新的SpeakToMeEventArgs(DateTime.Now.ToString()+ - + message)) ;
}

SpeakToMeEventArgs是一个继承自EventArgs&包含一个字符串属性(Message)。



自己,这些事件都可以正常工作。例如,我为[Speaker,Tweeter,Woofer]创建,订阅和启动该事件的形式设置了一个按钮。每个人都报告正确。



问题是当Speaker创建一个[Tweeter,Woofer]并订阅他们的事件。



我想要的是[Tweeter,Woofer]发起他们的活动,演讲者消费它并启动自己的事件。我认为这应该是非常简单的:

  void tweeter_SpeakToMe(object sender,SpeakToMeEventArgs e)
{
Console.Out.WriteLine(tweeter is speaking:+ e.Message);
this.OnSpeakToMe(tweeter rockin'out [+ e.Message +]);
}

通过此功能(在Speaker中),Console.Out.WriteLine可以正常工作。继续浏览OnSpeakToMe,显示委托是空的。



Speaker的SpeakToMe事件由表单订阅。我明白这应该可以防止事件的代理为空。



我确定这是一个很简单的,我错过了什么?



Btw,如果你好奇为什么我正在寻找这个。 [扬声器,高音扬声器,低音扬声器]是我的演示版本,用于长时间的数据处理操作。该表单同时运行其中的几个,并且需要每个类的进度更新。



一如以往,非常感谢任何和所有的帮助!



更新:感谢大家的所有反馈。我非常感谢帮助!我收到了几个很好的提示(@David Basarab& @Brian)以及关于如何组织事物的几个不同的想法。再次非常感谢!

解决方案

如果我在基本意义上了解你想要的东西。是要让Tweeter和Woofer触发扬声器订阅的事件,然后触发自己的。



这是我的代码,具有此输出



OUTPUT



OnSpeak Message = OnSpeakToMeHander原始消息: em>



$ OnSpeak Message = OnSpeakToMeHander原始消息:由Woofer发起 b
$ b

  class Program 
{

static void Main(string [] args)
{
Console.Clear();

try
{
扬声器扬声器=新扬声器();
speaker.speakerEvent + = new SpeakToMeHandler(Program.OnSpeak);

//原因事件被发现
speaker.Tweeter.CauseEvent();
speaker.Woofer.CauseEvent();

}
catch(Exception ex)
{
Console.WriteLine(Error:{0},ex.Message);
Console.WriteLine(StackTrace:{0},ex.StackTrace);
}
}

public static void OnSpeak(object sendere,SpeakToMeEventArgs e)
{
Console.WriteLine(OnSpeak Message = {0} ,e.Message);
}

}

public delegate void SpeakToMeHandler(object sender,SpeakToMeEventArgs e);

public class SpeakToMeEventArgs:EventArgs
{
public string Message {get;组; }
}

public class Speaker
{
public event SpeakToMeHandler speakerEvent;

public Tweeter Tweeter {get;组; }
public Woofer Woofer {get;组; }

public void OnSpeakToMeHander(object sender,SpeakToMeEventArgs e)
{
if(this.speakerEvent!= null)
{
SpeakToMeEventArgs args = new SpeakToMeEventArgs
{
Message = string.Format(OnSpeakToMeHander原始消息:{0},e.Message)
};

this.speakerEvent(this,args);
}
}

public Speaker()
{
this.Tweeter = new Tweeter();
this.Woofer = new Woofer();

Tweeter.tweeterEvent + = new SpeakToMeHandler(this.OnSpeakToMeHander);
Woofer.wooferEvent + = new SpeakToMeHandler(this.OnSpeakToMeHander);
}
}

public class Tweeter
{
public event SpeakToMeHandler tweeterEvent;

public void CauseEvent()
{
SpeakToMeEventArgs args = new SpeakToMeEventArgs()
{
消息=由Tweeter发起
} ;

if(this.tweeterEvent!= null)
{
this.tweeterEvent(this,args);
}
}
}

public class Woofer
{
public event SpeakToMeHandler wooferEvent;

public void CauseEvent()
{
SpeakToMeEventArgs args = new SpeakToMeEventArgs()
{
Message =被Woofer烧
} ;

if(this.wooferEvent!= null)
{
this.wooferEvent(this,args);
}
}
}


How do I pass along an event between classes?

I know that sounds ridiculous (and it is) but I've been stumped on this for the past little while. Search didn't turn up a similar question so I figured I would pose it.

Here are the objects involved:

WinForm -> Speaker -> Tweeter
                   -> Woofer

[Speaker, Tweeter, Woofer] all declare a "SpeakToMe" event that sends a simple string message. The events are declared using the standard pattern:

public delegate void SpeakToMeHandler(object sender, SpeakToMeEventArgs e);
public event SpeakToMeHandler SpeakToMe;
protected virtual void OnSpeakToMe(string message)
{
   if (SpeakToMe != null) SpeakToMe(this, new SpeakToMeEventArgs(DateTime.Now.ToString() + " - " + message));
}

SpeakToMeEventArgs is a simple class inheriting from EventArgs & containing a string property (Message).

On their own, each of these events works fine. E.g., I set a button in the form to create, subscribe, and fire the event for [Speaker, Tweeter, Woofer]. Each reports back properly.

The problem is when Speaker creates a [Tweeter, Woofer] and subscribes to their events.

What I want is for [Tweeter, Woofer] to fire their event, Speaker to consume it and fire it's own event. I thought this should be very straight forward:

void tweeter_SpeakToMe(object sender, SpeakToMeEventArgs e)
{
   Console.Out.WriteLine("the tweeter is speaking: " + e.Message);
   this.OnSpeakToMe("tweeter rockin' out [" + e.Message + "]");
}

Stepping through this function (in Speaker), Console.Out.WriteLine works. Continuing to step through OnSpeakToMe, shows that the delegate is null.

Speaker's SpeakToMe event is subscribed to by the form. I understood that this should prevent the event's delegate from being null.

I'm sure this is an easy one, what am I missing?

Btw, in case you're curious as to why I'm looking for this. [Speaker, Tweeter, Woofer] are my demo stand-ins for a really long data processing operation. The form runs several of these concurrently and requires progress updates from each class.

As always, any and all help is greatly appreciated!

Update: Thanks for all of the feedback everyone. I really appreciate the help! I picked up a couple of good tips (@David Basarab & @Brian) and a few different ideas on how to structure things. Again, much appreciated!

解决方案

If I understood what you wanted in the basic sense. Is to have the Tweeter and Woofer fire an event that the Speaker is subscribed too then fire its own.

Here is my code that has this output

OUTPUT

OnSpeak Message = OnSpeakToMeHander Orginal Message: Fired By Tweeter

OnSpeak Message = OnSpeakToMeHander Orginal Message: Fired By Woofer

class Program
{

    static void Main(string[] args)
    {
        Console.Clear();

        try
        {
            Speaker speaker = new Speaker();
            speaker.speakerEvent += new SpeakToMeHandler(Program.OnSpeak);

            // Cause events to be fied
            speaker.Tweeter.CauseEvent();
            speaker.Woofer.CauseEvent();

        }
        catch (Exception ex)
        {
            Console.WriteLine("Error: {0}", ex.Message);
            Console.WriteLine("Stacktrace: {0}", ex.StackTrace);
        }
    }

    public static void OnSpeak(object sendere, SpeakToMeEventArgs e)
    {
        Console.WriteLine("OnSpeak Message = {0}", e.Message);
    }

}

public delegate void SpeakToMeHandler(object sender, SpeakToMeEventArgs e);

public class SpeakToMeEventArgs : EventArgs
{
    public string Message { get; set; }
}

public class Speaker
{
    public event SpeakToMeHandler speakerEvent;

    public Tweeter Tweeter { get; set; }
    public Woofer Woofer { get; set; }

    public void OnSpeakToMeHander(object sender, SpeakToMeEventArgs e)
    {
        if (this.speakerEvent != null)
        {
            SpeakToMeEventArgs args = new SpeakToMeEventArgs
                {
                    Message = string.Format("OnSpeakToMeHander Orginal Message: {0}", e.Message)
                };

            this.speakerEvent(this, args);
        }
    }

    public Speaker()
    {
        this.Tweeter = new Tweeter();
        this.Woofer = new Woofer();

        Tweeter.tweeterEvent += new SpeakToMeHandler(this.OnSpeakToMeHander);
        Woofer.wooferEvent += new SpeakToMeHandler(this.OnSpeakToMeHander);
    }
}

public class Tweeter
{
    public event SpeakToMeHandler tweeterEvent;

    public void CauseEvent()
    {
        SpeakToMeEventArgs args = new SpeakToMeEventArgs()
            {
                Message = "Fired By Tweeter"
            };

        if (this.tweeterEvent != null)
        {
            this.tweeterEvent(this, args);
        }
    }
}

public class Woofer
{
    public event SpeakToMeHandler wooferEvent;

    public void CauseEvent()
    {
        SpeakToMeEventArgs args = new SpeakToMeEventArgs()
            {
                Message = "Fired By Woofer"
            };

        if (this.wooferEvent != null)
        {
            this.wooferEvent(this, args);
        }
    }
}

这篇关于C#冒泡/传播一次事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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