C#:我的应用程序是否可以共享在我的其他一个类中触发的事件?

时间:2020-03-26 01:23:43

标签: c# events event-handling

请原谅我,如果我不能正确地解释这一点,我是编程新手,我不确定如果可能的话会叫什么。

首先,让我解释一下我班上的一些事情。我们将此类称为TextStats。 TextStats类将创建一个计时器,如下所示:

 private Timer timer;

稍后,这些值将在初始化时设置为计时器:

timer = new Timer(1000);
timer.Elapsed += OnTimedEvent;
timer.AutoReset = true;
timer.Enabled = true;

然后我的班级内部有一个事件,每秒触发一次,就像这样:

    private void OnTimedEvent(object sender, ElapsedEventArgs e)
    {
        Console.WriteLine("Timed event has fired!");
    }

稍后我将向其添加代码,但是基本上我正在尝试重构和清理主类中的某些代码。

现在,在程序的主类中,我正在创建一个实例,我想它被称为TextStats类的实例:

TextStats textStats = new TextStats();

好的,现在这是我难受的部分! TextStats类会像我希望的那样触发计时器事件,并将在我的主类的幕后运行所有代码……。但是,我也希望能够在我的内部“共享” TextStats的计时器事件主班。

换句话说,我的TextStats类仍然按其应有的每秒触发一次计时器事件,但是我还想以某种方式在我的主类中创建一个事件,即TextStats类中的计时器事件也将触发,或共享,or带或附加到...这个过程称为...大声笑。

我想这将是英语形式的

share event OnTimedEvent from textStats and map it to this.TimedEvent;

public void TimedEvent()
{
   //Additional code to run with OnTimedEvent event from class TextStats
}

好的,我试图使这一点尽可能清楚。非常抱歉,冗长的解释。有什么办法可以做我想要的吗?我不想显示我的所有代码,因为我只是跳进去,而且我确定一切都乱七八糟,我不想让人们分心,只想专注于这一件事。非常感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

您要为两个班级共享相同的时钟。

至少有两种方法可以实现。

  1. 简便但以后难以重构:触发主表单TimedEvent时调用TextStats中的OnTimedEvent

要实现这一目标,您需要将TextStats设为班级成员。

    // Make your TextStats as a class member.
    TextStats textStats = new TextStats();
    private void OnTimedEvent(object sender, ElapsedEventArgs e)
    {
        Console.WriteLine("Timed event has fired!");
        textStats.TimedEvent();
    }
  1. 将时钟注入TextStats。这有点复杂,但重构起来更容易。
        public class TextStats
        {
            readonly System.Windows.Forms.Timer _tmr;

            public TextStats( System.Windows.Forms.Timer tmr )
            {
                _tmr = tmr;
                tmr.Tick += TimedEvent;
            }

            private void TimedEvent( object sender, EventArgs e )
            {
                // Implementation here
            }
        }

// When instantiating class, put your timer into it
    TextStats _textStats;
    void YourMainFormConstructor(){

         // Timer initialization.
         _textStats = new TextStats( timer );
    }

答案 1 :(得分:1)

可以附加到事件的内容称为EventHandlerEventHandlerdelegate types in C#,代表对另一种方法的引用。

在您的情况下,您可以创建一个ElapsedEventHandler委托/对要附加到timer.Elapsed类中的TextStats事件的方法的引用,然后可以将其附加到计时器事件:

class TextStats
{
    public void AddToTimer(ElapsedEventHandler handler)
    {
        timer.Elapsed += handler;
    }
}

在您的主课堂上,您可以这样做:

var textStats = new TextStats();
// By doing this, when the timer inside TextStats fires, both OnTimedEvent
// in TextStats class and AnotherOnTimedEvent in main class will be called.
textStats.AddToTimer(AnotherOnTimedEvent);

private void AnotherOnTimedEvent(object sender, ElapsedEventArgs e)
{
}

调用AddToTimer(AnotherOnTimedEvent)时,它将通过AnotherOnTimedEvent方法作为对AddToTimer方法的引用,其中该方法作为另一个< / em>事件处理程序。

注意

这说明了如何将事件处理程序传递给您的类并附加到timer.Elapsed概念。但是,当您考虑设计原则时,会有更好的解决方案。

例如,您的主类不应该知道timer.Elapsed在内部使用计时器,因为这是实现细节。应该知道,TextStats每1秒触发一次事件。因此,执行此操作的更好方法是让TextStats公开您的主类可以附加的另一个事件,并在您的TextStats类中,将这两个事件挂钩,因此,只要计时器计时,您的新事件也会触发。

类似这样的东西:

TextStats

在您的主要班级:

class TextStats
{ 
    private System.Timers.Timer timer;

    public event EventHandler EventFiresEveryOneSecond;

    public TextStats()
    {
        timer = new System.Timers.Timer(1000);
        timer.Elapsed += OnTimedEvent;
        timer.AutoReset = true;
        timer.Enabled = true;
    }

    private void OnTimedEvent(object sender, ElapsedEventArgs e)
    {
        EventFiresEveryOneSecond?.Invoke(sender, e);
    }
}