Я реализовал триаду MVP с использованием пассивного шаблона представления - то есть в представлении содержатся только простые геттеры и сеттеры. Однако у меня возникают проблемы с разделением данных представления и данных модели. В частности, при обработке изменения состояния представления.MVP Пассивный просмотр - сохранение данных и данных модели отдельно
Триада используется, чтобы позволить пользователю выбрать деталь из списка. Список деталей предоставляется моделью, каждая из которых уникально идентифицируется уникальным идентификатором.
Давайте говорить части выглядеть следующим образом:
class Part
{
int ID; // this code uniquely identifies the part within the model
String partCode;
String description;
double voltage;
}
Вид отображает список пользователей и позволяет им выбрать часть
Список отображается в DataGridView и часть выбрана нажав на строку в файле dataGridView.
Идентификатор пользователя не должен отображаться, и ни одно из них не является напряжением, поэтому модель создает DataTable, который содержит только код детали и описание. Этот DataTable назначается презентатором для свойства в представлении, которое сопоставляется с свойством DataSource DataGridView.
class Presenter
{
IView _view;
IModel _model;
//...///
_view.Data = _model.GetFilteredData();
}
class Model
{
public DataTable GetFilteredData()
{
// create a DataTable with the partCode and Description columns only
// return DataTable
}
}
class View //winform
{
public DataTable Data
{
set
{
this.dataGridView.Source = value;
}
}
}
Пока все хорошо. В представлении «Отбросить» отфильтрованные данные в DataGridView.
Проблема у меня есть возврат части, выбранной пользователем.
Представление не знает уникальный идентификатор, так как оно не отображается, а другая информация не может быть уникальной - поэтому невозможно однозначно идентифицировать выбранную деталь.
По сути, я пытаюсь преобразовать данные просмотра (выбранную строку) для моделирования данных (выбранная часть) без одного компонента с использованием других данных.
До сих пор у меня есть следующие решения:
1) Представление передается DataTable, который содержит идентификатор, а затем фильтрует дисплей так, чтобы он не отображается пользователю. Затем тривиально вернуть идентификатор для выбранной строки. Проблема здесь в том, что я теперь загрязнил представление логикой, которая не тестировалась (фильтрация дисплея).
2) Представление возвращает индекс строки, а модель соответствует этому индексу строке в исходных данных. Это означало бы, что порядок в представлении никогда не меняется, что, по возможности, ограничивает то, как представление может показывать (и манипулировать) данными. Это также загрязняет модель с данными просмотра (индекс строки).
public int RowIndexSelected { get; private set; }
//...//
private void gridParts_CellEnter(object sender, DataGridViewCellEventArgs e)
{
if (SelectedPartChangedEvent != null)
{
RowIndexSelected = e.RowIndex;
SelectedPartChangedEvent();
}
}
3) Вариант на (2). Создайте объект адаптера, чтобы сидеть между презентатором и представлением. Переместите код преобразования строки в ID из модели в адаптер. Затем ведущий обрабатывает измененное событие детали dataGridAdapters.
public PartSelectDataGridAdapter(IPartSelectView view, PartCollection data)
{
_view = view;
_data = data;
_view.SelectedPanelChangedEvent += HandleSelectedPartChanged;
}
void HandleSelectedPartChanged()
{
int id = _data[_view.RowIndexSelected].ID;
if (SelectedPartChanged != null)
{
SelectedPartChanged(id);
}
}
В настоящее время им обучения на 3, так как это проверяемым, хранит логику из данных, и вид из модели и ведущий.
Как бы вы справились с этим - есть ли лучшее решение?
Я должен добавить, что я следовал методологии Presenter First, описанной здесь http://www.atomicobject.com/pages/Presenter+First. – Kildareflare 2010-12-08 13:31:51