2013-08-16 129 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