Получение 2 классов, которые ничего не знают друг о друге, чтобы поделиться событиями в C #? - PullRequest
0 голосов
/ 10 июля 2011

У меня есть три класса, один класс загружает файл конфигурации в память для последующего доступа. Мой другой класс - основная форма. Я пытаюсь добиться того, чтобы при загрузке определенных элементов класса конфигурации они добавлялись в представление списка в графическом интерфейсе (WindowsForm).

Я знаю, что вы не можете получить доступ к графическому интерфейсу напрямую из других классов, не относящихся к основной форме, что после чтения я не хочу делать в любом случае, поэтому я пытался вызвать события, чтобы сказать "config updated", что основная форма будет прослушивать и обновлять просмотр списка, когда это необходимо. Поэтому я создал третий класс, который определяет события, делегаты и т. Д., Но во всех примерах, которые я видел, если разные классы вызывают событие, им всем передается общий экземпляр класса события.

Так я должен поступать? Когда я создал класс конфигурации из класса mainform, я должен передать экземпляр класса события? Или есть способ для двух классов, которые ничего не знают друг о друге, поделиться событием?

Я изменил приведенный ниже пример для Microsoft, чтобы продемонстрировать, что мне нужно.

    using System;

public class FireEventArgs : EventArgs
{
    public FireEventArgs(string room, int ferocity)
    {
        this.room = room;
        this.ferocity = ferocity;
    }
    public string room;
    public int ferocity;
}

public class FireAlarm
{
    public delegate void FireEventHandler(object sender, FireEventArgs fe);
    public event FireEventHandler FireEvent;

    public void ActivateFireAlarm(string room, int ferocity)
    {
        FireEventArgs fireArgs = new FireEventArgs(room, ferocity);
        if(FireEvent!=null)FireEvent(this, fireArgs);
    }
}

public class FireEventTest
{

    public static void ExtinguishFire(object sender, FireEventArgs fe)
    {

        Console.WriteLine("\nThe ExtinguishFire function was called by {0}.", sender.ToString());
        if (fe.ferocity < 2)
            Console.WriteLine("This fire in the {0} is no problem.  I'm going to pour some water on it.", fe.room);
        else if (fe.ferocity < 5)
            Console.WriteLine("I'm using FireExtinguisher to put out the fire in the {0}.", fe.room);
        else
            Console.WriteLine("The fire in the {0} is out of control.  I'm calling the fire department!", fe.room);
    }

    public static void Main()
    {
        FireAlarm myFireAlarm = new FireAlarm();
        FireAlarm fireAlarm = new FireAlarm();
        fireAlarm.FireEvent += new FireAlarm.FireEventHandler(ExtinguishFire);
        myFireAlarm.ActivateFireAlarm("Kitchen", 3);
        myFireAlarm.ActivateFireAlarm("Study", 1);
        myFireAlarm.ActivateFireAlarm("Porch", 5);
        return;

    }   
}

Заранее спасибо за любую помощь.

Ответы [ 3 ]

1 голос
/ 10 июля 2011

Ну, я не думаю, что полностью вас понимаю, но вы можете иметь класс EventDispatcher, сделать его Singleton, если хотите, и внутри него есть публичное событие

ConfigurationElementLoaded(object sender, ConfigurationElementLoadedArgs args)

и общедоступный метод для запуска события:

void FireConfigurationElementLoaded(ConfigurationElement element)

, в котором вы запускаете событие.

Ваша mainForm может подписаться через синглтон: EventDispatcher.Instance.ConfigurationElementLoaded += ...

и ваша Конфигурация может инициировать событие с помощью FireConfigurationElementLoaded.

Если этот ответ не помог, пожалуйста, опишите подробнее, что именно вы хотите сделать ...

0 голосов
/ 10 июля 2011

Используйте dindindind для элементов управления, если вы просто хотите обновить содержимое в пользовательском интерфейсе формы Windows.

Создайте слой данных, который содержит информацию о вашем файле конфигурации, и свяжите его свойства с элементами управления вашего интерфейса.В данный момент вы изменяете значения этого свойства, механизм привязки данных будет заботиться об обновлении вашего пользовательского интерфейса.

В общем, мое мнение таково: если что-то уже существует в используемой вами платформе (в данном случае .NET Framework), что соответствует вашим потребностям, просто используйте это, не изобретайте велосипед, потому что кто-то уже пострадалпридумывая это:)

Пример привязки данных для WindowsForm

Рассматривая все эти события, я предположил, что речь идет о приложении WindowsForm.Если нет, уточните.

Надеюсь, это поможет.

0 голосов
/ 10 июля 2011

Хм, если классы вообще ничего не знают друг о друге, я думаю, что это будет немного грязно, но разве это не так, правда?Пользовательский интерфейс знает, какое событие он хочет прослушать.

Это абсолютно нормально, хотя пользователь может абсолютно точно знать, что он должен отображать, по крайней мере, через интерфейс.Чего вы не хотите, так это чтобы бизнес-классы зависели от пользовательского интерфейса (вам нужен однонаправленный поток зависимостей)

Я бы сказал, определите интерфейс, содержащий ваши события, и реализуйте его в FireAlarm или слушайте напрямуюк событиям в FireAlarm.

Кроме того, строго говоря, это не тот случай, когда код вне формы не может использоваться внутри формы.Абсолютно хорошо для пользовательского интерфейса слушать и использовать событие с вашими собственными EventArgs, включая объект sender.

Что действительно важно, так это то, какой поток выполняет рассматриваемый код.Пока пользовательский интерфейс доступен из потока пользовательского интерфейса (потока, который создал пользовательский интерфейс), вы можете запускать любой код.

Существует ли причина, по которой опубликованный вами код не работает?

...