【问题标题】:How to Form.ShowDialog() using MVP and Passive Views?如何使用 MVP 和被动视图 Form.ShowDialog()?
【发布时间】:2014-03-17 17:06:39
【问题描述】:

总结

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

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

现在我想知道,如何使用 MVP 和被动视图来 ShowDialog()?

到目前为止,据我了解,被动视图不应该知道/关心任何演示者。他们甚至不知道它的存在。因此,根据我的说法,这个问题的答案中提出的解决方案不合适: 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 就像Universer 中的master,可以通过IAuthenticationViewIAuthenticationPresenter 了解用户身份验证

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&lt;V&gt;

public interface IPresenter<V> where V : IView {
    V View { get; }

    OnViewInitialize();
    OnViewLoad();
    ShowView();
}

【问题讨论】:

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


    【解决方案1】:

    基于这些前提:

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

    我来了:

    IView

    public interface IView {
        void OnShowView();
    }
    

    IPresenter&lt;V&gt;

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

    Presenter&lt;V&gt;

    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 事件。然后,回到表单中,视图对事件的响应是:

    AuthenticationForm

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-09-08
      • 2021-09-04
      • 1970-01-01
      • 2011-03-17
      • 2012-05-20
      • 2020-08-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多