Представьте простой 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);
}
}
Кто вызывает методы «Сохранить и отменить»? Это мнение? –
Да, в представлении есть методы SaveButton_Click/CancelButton_Click, которые вызывают методы Save/Cancel в презентаторе. – BoroDrummer