How to Form.ShowDialog() using MVP and Passive Views?
Summary
I'm experimenting with the MVP pattern in a Windows Forms application.
I'd like to make both my Presenters and Views platform agnostic, so if I wish to port my application to another platform, say the Web or mobile, I simply need to implement the views with platform dependant GUI, and my presenters can still be platform independent.
And now I wonder, how to ShowDialog() using MVP and Passive Views?
To my understanding so far, passive views shouldn't know/care about any presenter. They don't even know it exists. So, the solution presented in this question's answer is not suitable, according to me: Refactoring Form.ShowDialog() code to MVP
Some code samples to help on the understanding:
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.
}
}
IAuthenticationView
and IAuthenticationPresenter
. 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();
}
Based on these premisses:
I came to this:
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(); }
}
So, following the logic of where I struggled so far, I solved it by doing this:
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.
}
OnShowView
event which the IAuthenticationView has subscribed. Then, back in the form, the view's response to the event is: AuthenticationForm
public partial class AuthenticationForm : Form, IAuthenticationView {
public void OnShowView() { ShowDialog(); }
}
Then, the view shows itself as a dialog/modal window.
链接地址: http://www.djcxy.com/p/30228.html上一篇: 如何在MVP被动视图中显示复杂数据