Вопрос

Я пытаюсь использовать MVP в WinForms и не могу понять, как лучше всего координировать действия дочерних представлений.

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

Должен ли родительский вид управлять этим напрямую? Похоже, что я обхожу шаблон MVP, делая это.

Или дочерние представления должны воспринимать друг друга как параметры конструктора? В этом случае, когда событие было запущено первым дочерним представлением, второе дочернее представление получит событие и затем уведомит своего докладчика о том, что что-то произошло? Затем докладчик должен получить данные из первого дочернего представления (о котором он даже не знает), чтобы сообщить второму дочернему представлению, что делать. Это кажется запутанным, поэтому я чувствую, что что-то упустил.

Вот некоторый псевдокод для ситуации:

public class ParentView : UserControl, IParentView
{
    private ChildViewOne childViewOne;
    private ChildViewTwo childViewTwo;
    private ParentViewPresenter presenter;

    private RegisterEvents()
    {
        childViewOne.EventOccured += new EventHandler(HandleEvent);
    }

    private void HandleEvent()
    {
        childViewTwo.DoSomething();
    }
}
Это было полезно?

Решение

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

Ваш код может выглядеть следующим образом:

public class ChildViewOne {
    private IEventAggregator evtAggregator;

    public ChildViewOne(IEventAggregator evtAggregator) {
        this.evtAggregator = evtAggregator;
    }

    private void OnEventOccured(){
        evtAggregator.GetEvent<EventOccured>().Publish();
    }
}

publish class ChildViewTwo {
    private IEventAggregator evtAggregator;

    public ChildViewTwo(IEventAggregator evtAggregator) {
     evtAggregator.GetEvent<EventOccured>().Subscribe(OnEventOccured);
    }

    private void OnEventOccured() {
        // Do something here...
    }
}

РЕДАКТИРОВАТЬ: Брайан Нойес перенес агрегатор событий призмы в winforms. Проверьте это здесь, в его блоге

Другие советы

Использование других дочерних представлений в конструкторе кажется плохой идеей. Что вы будете делать, если в будущем необходимо добавить другое дочернее представление?

Было бы лучше, если бы вы направили свое дочернее событие через родительское представление. Как вы нарушаете MVP, если вы маршрутизируете свои события через родительское представление?

Я бы создал свойство интерфейса IChildView под названием SiblingView (или что-то более подходящее, учитывая бизнес-контекст вашего приложения). Вам даже не нужно добавлять его в качестве параметра в конструкторе, но интерфейс должен включать метод SetSiblingView (). Вы могли бы назвать это из конструктора. Затем вы можете иметь событие OnSiblingEventFired ().

Это кажется мне менее запутанным, но, может быть, это только потому, что именно так я подходил к этому типу проблем в прошлом.

Но я согласен, не зная слишком много деталей, имеющих родительский элемент управления, похоже, он не следует шаблону MVC.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top