C# 如何在MVP中最好地处理子视图的协调?
我试图在WinForms中使用MVP,但对如何最好地处理子视图之间的协调感到困惑C# 如何在MVP中最好地处理子视图的协调?,c#,winforms,model-view-controller,user-interface,mvp,C#,Winforms,Model View Controller,User Interface,Mvp,我试图在WinForms中使用MVP,但对如何最好地处理子视图之间的协调感到困惑 例如,我有一个父视图,它有两个子视图。一个子视图上的事件需要导致第二个子视图执行操作 父视图是否应直接对此进行控制?我这样做似乎是在绕过MVP模式 或者子视图应该将彼此作为构造函数参数吗?在这种情况下,当第一个子视图触发事件时,第二个子视图将接收事件,然后通知其演示者发生了什么?然后,演示者需要从第一个子视图(它甚至不知道)获取数据,以便告诉第二个子视图要做什么。这看起来很复杂,所以我觉得我错过了什么 下面是一些针
例如,我有一个父视图,它有两个子视图。一个子视图上的事件需要导致第二个子视图执行操作 父视图是否应直接对此进行控制?我这样做似乎是在绕过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();
}
}
在构造函数中获取其他子视图似乎不是一个好主意。如果将来需要添加另一个子视图,您会怎么做 如果通过父视图路由子事件,效果会更好。如果您通过父视图发送事件,您是如何违反MVP的?您可以查看。它将允许您保持一切松散耦合。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...
}
}
公共类ChildViewOne{
私家侦探evtAggregator;
公共儿童视图一(IEventAggregator evtAggregator){
this.evtAggregator=evtAggregator;
}
私有无效OneVentochared(){
evtAggregator.GetEvent().Publish();
}
}
发布类ChildViewTwo{
私家侦探evtAggregator;
公共儿童视图二(IEventAggregator evtAggregator){
evtAggregator.GetEvent().Subscribe(OneVentochared);
}
私有无效OneVentochared(){
//在这里做点什么。。。
}
}
编辑:Brian Noyes已将prism事件聚合器移植到winforms。查看它我将创建一个名为SiblingView的IChildView接口属性(或者根据应用程序的业务上下文更合适的属性)。您甚至不必将其作为参数添加到构造函数中,而是让接口包含一个名为SetSiblingView()的方法。您可以从构造函数调用它。然后,您可以在siblingeventfired()上创建一个事件 对我来说,这似乎不那么复杂,但也许这只是因为我过去处理这类问题的一般方式
但我同意,在不了解太多关于父控件的细节的情况下,它似乎没有遵循MVC模式。“一个子视图上的事件需要导致第二个子视图执行操作。”具体执行的操作是什么?例如,假设childViewOne是时间线,ChildView2是视频。时间线公开了一个TimeChanged事件,视频需要通过更改视频的当前帧来响应该事件。您的意思是像我当前所做的那样,还是ParentView公开了其子级的所有事件的联合,并将事件传递给其演示者?