2013-08-16 94 views
1

想象一下带有一个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

谁调用Save和Cancel方法?这是观点吗? –

+0

是的,查看有SaveButton_Click/CancelButton_Click方法在演示者中调用保存/取消方法。 – BoroDrummer

回答

0

如果您的设计是MVP(模型视图展示器),您应该在演示者内部创建模型。这就是这种模式背后的想法。 该视图与演示者通信,演示者为他提供他需要的所有方法,属性和事件。 在你的例子中,你也决定创建一个模型。你可以做到这一点,但请将它从视图中隐藏起来。 与您的示例相关,请删除构造函数中的IModel参数,然后在代码中创建一个新的参数。

考虑通过方法设置视图改变(_view.SetName(“我”)。这可能使您的生活更轻松后面。

有没有必要建立一个新的WinForms形式。也许,我不明白您点这里..

更新:

看看下面的例子中你有看法,主持人和模型(从您的代码为基础)我只是改名IModel到ICustomer接口,使我的观点明确。 。主持人创建一个模型来做一些I/O的东西,并获得更新窗口的视图界面或int erface。

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; 
    } 
} 
+0

我不明白如何在演示者中创建模型。假设模型是从数据库的Customers表中检索的Customer对象。演示者如何知道要检索哪个客户。它意识到的是实例化它的视图。 – BoroDrummer

+0

在这种情况下,演示者必须通知有关新客户的观点。我明白你的观点。您的IModel接口是处理模型实例的Model而不是类。但回到你的例子。该视图可以要求演示者说明他想向客户展示x。演示者然后调用任何数据库并更新视图(即通过方法)。您应该将您的IModel重命名为ICustomer,以便您更轻松地遵循。 – Bjoern

+0

好的,说IModel确实定义了处理客户实例的类。它仍然不可能在演示者内创建模型。这将如何启用当前客户的状态信息?另外,我认为MVP的优点之一是模型作为接口传递给演示者,因此任何符合IModel的模型都是兼容的。 – BoroDrummer