Как создать статическое глобальное событие, чтобы одна форма могла прослушивать событие другой формы, которое не является родительской формой? - PullRequest
0 голосов
/ 02 апреля 2019

Я использую WinForms и у меня есть 3 формы. FormA, FormB и FormC.

FormA создает FormB, FormB создает FormC.

Мне нужно, чтобы FormA знала, когда FormC закрывается. FormB не участвует. У меня также есть глобальный статический класс, к которому у каждой формы есть доступ.

Я смотрел на Как правильно слушать события формы с другой формой и Распространение событий из одной формы в другую форму в C # , но они применяются только к FormB, слушающему FormC.

Как создать событие в глобальном статическом классе, чтобы FormA могла слушать FormC?

Спасибо

Ответы [ 3 ]

0 голосов
/ 02 апреля 2019

Это глобальный статический класс со статическим событием FormClosed:

public static class GlobalStaticClass
{
    public static event FormClosedEventHandler FormClosed;
    public static void OnFormClosed(object sender, FormClosedEventArgs e)
    {
        FormClosed?.Invoke(sender, e);
    }
}

Это FormC. Вызывает событие FormClosed:

public partial class FormC : Form
{
    public FormC()
    {
        InitializeComponent();
        this.FormClosed += (sender, e) =>
        {
            GlobalStaticClass.OnFormClosed(sender, e);
        };
    }
}

И это FormA, который слушает это событие:

public partial class FormA : Form
{
    public FormA()
    {
        InitializeComponent();
        GlobalStaticClass.FormClosed += (sender, e) =>
        {
            //if (sender is FormC)
            MessageBox.Show(((Form)sender).Name + " Closed, reason: " + e.CloseReason);
        };
    }
}
0 голосов
/ 03 апреля 2019

Вы почти всегда на 100% лучше избегаете static классов и глобальных ссылок.

Лучше передать Action<FormC>, который позволяет вам сообщить, что FormC закрывается.

Попробуйте это:

FormA

public partial class FormA : Form
{
    public FormA()
    {
        InitializeComponent();
    }

    private void Button1_Click(object sender, EventArgs e)
    {
        var formB = new FormB(this.ClosingC);
        formB.Show();
    }

    private void ClosingC(FormC formC)
    {
        MessageBox.Show("Closing C");
    }
}

FormB

public partial class FormB : Form
{
    public FormB()
    {
        InitializeComponent();
    }

    private Action<FormC> _closingFormC = null;

    public FormB(Action<FormC> closingFormC)
        : this()
    {
        _closingFormC = closingFormC;
    }

    private void Button1_Click(object sender, EventArgs e)
    {
        var formC = new FormC(_closingFormC);
        formC.Show();
    }
}

FormC

public partial class FormC : Form
{
    public FormC()
    {
        InitializeComponent();
    }

    private Action<FormC> _closingFormC = null;

    public FormC(Action<FormC> closingFormC)
        : this()
    {
        _closingFormC = closingFormC;
    }

    private void FormC_FormClosing(object sender, FormClosingEventArgs e)
    {
        _closingFormC?.Invoke(this);
    }
}
0 голосов
/ 02 апреля 2019

Я бы использовал агрегацию событий.Вот маленький Install-Package Caliburn.Micro.EventAggregator

используется как

public class MyForm : Form, IHandle<MyEvent>
{
   public MyForm() 
   {
      SomeStaticPlace.EventAggregator.Subscribe(this); //Can be replaced with DI
   }

   public void Handle(MyEvent message) 
   {
      //Act on event
   }
}

И публиковать SomeStaticPlace.EventAggregator.Publish(new MyEvent(...));

...