我正在构建一个Windows Forms应用程序,我希望将来可能会移植到WPF和GTK#。我有兴趣使用MVP模式来实现这一目标。
对于一个简单的首选项对话框,我有一个设计器创建的表单,它实现了一个视图界面,其中包含演示者在保存或关闭对话框时可以监听的事件。我使用设计器在首选项框架的控件和.NET项目设置之间创建数据绑定,所以我正在监督演示者。
interface IPreferencesDialogView
{
event EventHandler Save;
event EventHandler Cancel;
}
public partial class PreferencesDialog : Form, IPreferencesDialogView
{
private PreferencesDialogPresenter presenter = null;
public event EventHandler Save;
public event EventHandler Cancel;
public PreferencesDialog()
{
InitializeComponent();
presenter = new PreferencesDialogPresenter(this);
}
private void PreferencesDialog_FormClosing(object sender, FormClosingEventArgs e)
{
if (this.DialogResult == DialogResult.OK)
{
Save?.Invoke(this, EventArgs.Empty);
}
else
{
Cancel?.Invoke(this, EventArgs.Empty);
}
}
}
我的模型使用.NET项目设置来存储应用程序设置,因为它在Mono中可用,我可以将它与WPF和GTK#一起使用。
class PreferencesDialogPresenter
{
private readonly IPreferencesDialogView view;
public PreferencesDialogPresenter(IPreferencesDialogView view)
{
this.view = view;
view.Save += (o, e) => { Properties.Settings.Default.Save(); };
view.Cancel += (o, e) => { Properties.Settings.Default.Reload(); };
}
}
在我的主窗体上,我还有一些非常具体的Windows窗体代码,一个级联按钮,级联所有打开的MDI窗口。使用Windows Forms提供的LayoutMdi方法非常简单(Java Swing没有)。
private void cascade_Click(object sender, EventArgs e)
{
this.LayoutMdi(MdiLayout.Cascade);
}
到目前为止,这对我来说似乎很有效。视图对模型或演示者一无所知,模型对视图或演示者一无所知。但是,我有几个问题。
答案 0 :(得分:2)
有没有简化我的活动模式?我真的不想传递我不使用的参数。
理想情况下,我只有一个事件,已关闭,我会将对话框结果转发给演示者。我不喜欢视图中的保存/取消逻辑。但是,DialogResult类型是特定于Windows窗体的,因此我不能将它与GTK#一起使用。我可以创建自己的包装类型吗?这是通常做的吗?
是的,我所做和所相信的最佳做法是创建与发生的操作相关的特定事件。不只是从UI传递事件。因此,单个Close事件包括一个简单的枚举,指示是保存还是取消。您的演示者将包含基于该枚举确定是否要执行Properties.Settings.Default.Save();或Properties.Settings.Default.Reload();
然后在非Windows窗体视图中,您仍然需要调用该事件,但是由视图决定是始终保存还是取消,或者是否实现自定义保存/取消对话框从用户那里获取此信息。