想象一个简单的UserControl,其中包含一个TextBox(CustomerName)和两个按钮(Save / Cancel)。
此UserControl位于具有两个以上按钮的父控件中(PreviousCustomer / NextCustomer)
问题是我不知道将模型传递给演示者的位置。我是否通过视图构造函数?如果模型更改(单击PreviousCustomer / NextCustomer),该怎么办?我每次都要创建一个新视图吗?如果UserControl与许多孩子很复杂,这似乎很浪费。我可以在视图和演示者中实现UpdateModel方法,还是不正确?
这是我的代码:
public interface IModel
{
string CustomerName { get; set; }
}
public class Presenter
{
private IView _view;
private IModel _model;
public Presenter(IView view, IModel model)
{
_view = view;
_model = model;
_view.CustomerName = _model.CustomerName;
}
public void Save()
{
_model.CustomerName = _view.CustomerName;
}
public void Cancel()
{
_view.CustomerName = _model.CustomerName;
}
public void UpdateModel(IModel newModel)
{
_model = newModel;
_view.CustomerName = _model.CustomerName;
}
}
public interface IView
{
string CustomerName { get; set; }
}
public class View : UserControl, IView
{
private Presenter _presenter;
public string CustomerName
{
get { return CustomerNameEditBox.Text; }
set { CustomerNameEditBox.Text = value; }
}
//Is this the right place to pass in the model?
public View(IModel model)
{
_presenter = new Presenter(this, model);
}
private void SaveButton_Click(object sender, EventArgs e)
{
_presenter.Save();
}
private void CancelButton_Click(object sender, EventArgs e)
{
_presenter.Cancel();
}
public void UpdateModel(IModel newModel)
{
_presenter.UpdateModel(newModel);
}
}
编辑:如下面的评论中所述,我认为最好让视图完全愚蠢,对演示者或模型一无所知。这是我修改后的代码。
型号:
public interface IModel
{
string CustomerName { get; set; }
}
public class Model : IModel
{
public string CustomerName { get; set; }
public Model(string name)
{
CustomerName = name;
}
}
查看:
public interface IView
{
event EventHandler SaveClick;
event EventHandler CancelClick;
string CustomerName { get; set; }
}
public class View : UserControl, IView
{
public event EventHandler SaveClick
{
add { SaveButton.Click += value; }
remove { SaveButton.Click -= value; }
}
public event EventHandler CancelClick
{
add { CancelButton.Click += value; }
remove { CancelButton.Click -= value; }
}
public string CustomerName
{
get { return CustomerNameEditBox.Text; }
set { CustomerNameEditBox.Text = value; }
}
}
主讲人:
public class Presenter
{
private IView _view;
private IModel _model;
public Control View
{
get { return (Control)_view; }
}
public Presenter(IView view, IModel model)
{
_view = view;
_view.SaveClick += new EventHandler(_view_SaveClick);
_view.CancelClick += new EventHandler(_view_CancelClick);
_model = model;
_view.CustomerName = _model.CustomerName;
}
void _view_SaveClick(object sender, EventArgs e)
{
_model.CustomerName = _view.CustomerName;
}
void _view_CancelClick(object sender, EventArgs e)
{
_view.CustomerName = _model.CustomerName;
}
public void ChangeModel(IModel newModel)
{
_model = newModel;
_view.CustomerName = _model.CustomerName;
}
}
用法:
public class MainProgram : Form
{
public void ArbitraryMethod()
{
//Create a new model object
IModel model1 = new Model("test1");
//Create the presenter with the model and any view implementing IView
Presenter presenter = new Presenter(new View(), model1);
//Add the view to a panel control in this form
mainPanel.Controls.Add(presenter.View);
//Change the model
IModel model2 = new Model("test2");
presenter.ChangeModel(model2);
}
}
答案 0 :(得分:0)
如果您的设计是MVP(模型视图展示器),则应在演示者中创建模型。这就是这种模式背后的想法。 视图与演示者进行通信,演示者为他提供了所需的所有方法,属性和事件。 在您的示例中,您还决定创建模型。你可以这样做,但请从视图中隐藏它。 与您的示例相关,删除构造函数中的IModel参数,然后在代码中创建一个新参数。
考虑通过方法设置视图更改(_view.SetName(“me”)。这可以让您以后的生活更轻松。
无需创建新的winforms表单。也许,我在这里不明白你的观点..
更新
看一下下面的例子。您有视图,演示者和模型的接口(基于您的代码)。我刚刚将IModel重命名为ICustomer以明确我的观点。演示者创建一个模型,用于执行一些I / O操作,并获取一个视图界面,用于更新窗口或界面后面的任何内容。
public interface IView
{
public string CustomerName { get; set; }
}
public interface ICustomer
{
string CustomerName { get; set; }
}
public interface IModel
{
void Save(ICustomer entity);
void Update(ICustomer entity);
ICustomer Create();
}
public class Customer : ICustomer
{
public string CustomerName {get;set;}
}
public class MyModel : IModel
{
public void Save(ICustomer entity)
{
//Do something here..
}
public void Update(ICustomer entity)
{
//Do something here..
}
public ICustomer Create()
{
return new Customer();
}
}
public class Presenter
{
private IView _view;
private ICustomer _entity;
private IModel _model = new MyModel();
public Presenter(IView view)
{
_view = view;
_model = new MyModel();
_entity = _model.Create();
_view.CustomerName = _entity.CustomerName;
}
public void Save()
{
_model.Save(_entity);
}
public void Cancel()
{
_entity = _model.Create();
}
public void UpdateModel(ICustomer customer)
{
_model.Update(customer);
_view.CustomerName = customer.CustomerName;
}
}