2013-08-16 3 views
1

Представьте простой UserControl с одним текстовым полем (CustomerName) и двумя кнопками (Save/Cancel).Изменение модели

Это UserControl сидит внутри родительского элемента управления с еще двумя кнопками (PreviousCustomer/NextCustomer)

Проблема заключается в том, я не знаю, где пройти в модели к ведущему. Пройти ли я через конструктор вида? Что делать, если модель изменяется (нажата кнопка «Предыдущий клиент/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); 
    } 
} 

Edit: Как указано в комментариях ниже, я думаю, что лучше всего, чтобы иметь представление, чтобы быть полностью тупой и ничего не знают о предъявителю или модели. Вот мой пересмотренный код.

Модель:

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

Presenter:

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

Да, в представлении есть методы SaveButton_Click/CancelButton_Click, которые вызывают методы Save/Cancel в презентаторе. – BoroDrummer

ответ

0

Если ваш проект MVP (Model View Presenter), вы должны создать свою модель внутри презентатора. Это идея этой картины. Вид связан с ведущим, и ведущий предлагает ему все методы, свойства, необходимые ему события. В вашем примере вы также решили создать модель. Вы можете это сделать, но, пожалуйста, скройте его из представления. Связанный с вашим примером, удалите параметр IModel в конструкторе и создайте вместо него новый код.

Рассмотрим настройки просмотра изменений с помощью методов (_view.SetName («Я»). Это может сделать вашу жизнь проще позже.

Там нет необходимости создавать новую форму WinForms. Может быть, я не понимаю Ваша точка здесь ..

Update:

Посмотрите на примере ниже Вы интерфейсы для просмотра, ведущего и моделей (на основе из вашего кода) Я просто переименованная IModel к ICustomer, чтобы сделать мою точку ясно.. . Ведущий создает модель для выполнения некоторых операций ввода-вывода и получает интерфейс просмотра для обновления окон или что-то, что находится за 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

Я не понимаю, как модель может быть создана в презентаторе. Предположим, что модель представляет собой объект Customer, который извлекается из таблицы Customers в базе данных. Как ведущий знает, какой клиент должен получить. Все, что ему известно, - это представление, которое его создало. – BoroDrummer

+0

В этом случае ведущий должен сообщить о новом клиенте. Теперь я понимаю вашу точку зрения. Ваш интерфейс IModel - это модель, а не класс, который обрабатывает экземпляры модели. Но вернемся к вашему примеру.Представление может спросить вашего докладчика, что он хочет показать клиента x. Затем ведущий вызывает любую базу данных и обновляет представление (т. Е. Методом). Вы должны переименовать свой IModel в ICustomer, что упростит вам следовать. – Bjoern

+0

Хорошо, скажем, IModel определяет класс, который обрабатывает экземпляры клиента. Невозможно создать модель внутри презентатора. Как это позволит включить информацию о состоянии, такую ​​как текущий клиент? Кроме того, я думал, что одним из преимуществ MVP было то, что модель была передана в презентатор в качестве интерфейса, поэтому любая модель, соответствующая IModel, была бы совместимой. – BoroDrummer

Смежные вопросы