如何使用MVP和被动视图Form.ShowDialog()?

时间:2014-03-17 17:06:40

标签: c# winforms mvp passive-view platform-agnostic

摘要

我在Windows窗体应用程序中试验MVP模式。

我想让我的Presenters和Views平台不可知,所以如果我希望将我的应用程序移植到另一个平台,比如Web或移动,我只需要使用平台相关的GUI实现视图,并且我的演示者仍然可以独立于平台。

现在我想知道,如何使用MVP和被动视图显示对话题?

据我所知,到目前为止,被动观点不应该知道/关心任何演示者。他们甚至不知道它存在。因此,根据我的说法,在这个问题的答案中提出的解决方案是不合适的: Refactoring Form.ShowDialog() code to MVP

一些代码示例有助于理解:

ApplicationView

public partial class ApplicationForm : Form, IApplicationView {
    // I ensure that all the IApplicationView events are raised 
    // upon button clicks text changed, etc.
    // The presenter, which this view ignores the existence, 
    // is subscribed to the events this view raises.
}

ApplicationPresenter

public class ApplicationPresenter 
    : Presenter<IApplicationView>
    , IApplicationPresenter {
    public ApplicationPresenter(IApplicationView view) : base(view) {
        View.OnViewShown += OnViewShown;
    }

    public void OnViewShown() {
        IAuthenticaitonView authView = new AuthenticationForm();
        IAuthenticationPresenter authPresenter = new AuthenticationPresenter(authView);
        authPresenter.ShowDialog(); // 1.                       
    }
}
  1. 这是我挣扎的地方。 ApplicationPresenter就像Universe中的master,可能通过IAuthenticationViewIAuthenticationPresenter 了解用户身份验证。
  2. IAuthenticationView

    public interface IAuthenticationView : IDialogView {
        string ErrorMessage { get; set; }
        string Instance { get; set; }
        IEnumerable<string> Instances { get; set; }
        string Login { get; set; }
        string Password {get; set; }
    
        void EnableConnectButton(bool enabled);
    
       event VoidEventHandler OnConnect;
       event SelectionChangedEventHandler OnDatabaseInstanceChanged;
       event VoidEventHandler OnLoginChanged;
       event VoidEventHandler OnPasswordChanged;
    }
    

    IDialogView

    public interface IDialogView : IView {
        void ShowDialog();
    }
    

    IView

    public interface IView { 
        void Show();
    
        event VoidEventHandler OnViewInitialize;
        event VoidEventHandler OnViewLoad;
        event VoidEventHandler OnViewShown;
    }
    

    IAuthenticationPresenter

    public interface IAuthenticationPresenter : IPresenter<IAuthenticationView> {
        void OnConnect();
        void OnViewDatabaseInstanceChanged(SelectionChangedEventArgs e);
        void OnViewLoginChanged();
        void OnViewPasswordChanged();
    }
    

    IPresenter<V>

    public interface IPresenter<V> where V : IView {
        V View { get; }
    
        OnViewInitialize();
        OnViewLoad();
        ShowView();
    }
    

1 个答案:

答案 0 :(得分:1)

基于这些前提:

  • 演示者应与平台无关
  • 只有视图知道如何展示/展示自己(WPF,Mobile,Silverlight,Web,WinForms ......)
  • 视图必须提供展示自己的方式
  • 视图不一定是与平台无关的,因为显示器会因平台而异。
  • 但是演示者应该在何时展示自己

我来到这里:

  

<强> IView

public interface IView {
    void OnShowView();
}
  

<强> IPresenter<V>

public interface IPresenter<V>where V : IView {
    void ShowView();
    event VoidEventHandler OnShowView;
}
  

<强> Presenter<V>

public abstract class Presenter<V> : IPresenter<V> {
    public Presenter(V view) { 
        View = view;
        OnShowView += View.OnShowView;
    }

    public void ShowView() { raiseShowViewEvent(); }

    public event VoidEventHandler OnShowView;

    private void raiseShowViewEvent() { if (OnShowView != null) OnShowView(); }
}

所以,按照我到目前为止奋斗的逻辑,我通过这样做解决了这个问题:

  

<强> ApplicationForm

public partial class ApplicationForm : Form, IApplicationView {
    private void ApplicationForm_Shown(object sender, EventArgs e) { raiseOnViewShown();  }            

    private void raiseOnViewShownEvent() { if (OnViewShown != null) OnViewShown(); }
}
  

<强> ApplicationPresenter

public void OnViewShown() {
    // This method is the subscriber of the IView.OnViewShown event
    // The event is raised with the ApplicationForm_Shown event.
    IAuthenticationView authView = new AuthenticationForm();
    IAuthenticationPresenter authPresenter = new AuthenticationPresenter(authView);
    authPresenter.ShowView(); // 1.
}
  1. 这会引发IAuthenticationView订阅的OnShowView事件。然后,回到表单中,视图对事件的响应是:
  2.   

    <强> AuthenticationForm

    public partial class AuthenticationForm : Form, IAuthenticationView {
        public void OnShowView() { ShowDialog(); }
    }
    

    然后,视图将自身显示为对话框/模态窗口。