Контроллер модельного вида - PullRequest
3 голосов
/ 24 января 2009

В моем графическом интерфейсе есть элемент управления деревом (естественно, с большим количеством функций, специфичных для графического интерфейса / платформы, для обработки узлов).
У меня есть модель данных с собственным сложным набором узлов, дочерних элементов, свойств и т. Д.
Я хочу, чтобы дерево отображало представление модели, позволяло отправлять сообщения узлам внутри модели и получать указание перерисовывать себя при изменении модели.

Но я не хочу, чтобы код GUI нуждался в подробностях типов данных модели, и я не хочу загрязнять модель, связывая ее с классами GUI.

Я не могу понять, как контроллер должен это делать и какие функции он должен обеспечивать?

(это на C ++, но это не должно иметь значения)

Ответы [ 6 ]

2 голосов
/ 24 января 2009

GUI-элементы управления не совсем вписываются в шаблон модель-представление-контроллер, потому что они обычно имеют собственную внутреннюю модель, а не принимают ссылку на нее. Если элемент управления структурирован таким образом, вам потребуется класс адаптера, который «связывает данные» внутренней модели элемента управления с базовой моделью данных.

Это может выполнить нечто похожее на то, что сделал бы модель-представление-контроллер, за исключением того, что класс адаптера играет роль как компонента подключения представления (обновление GUI из модели данных), так и контроллера (интерпретация событий GUI в действия модели). ).

1 голос
/ 24 января 2009

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

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

Третье решение: Использовать шаблон MVP. Модельный вид Presenter. Этот шаблон используется всякий раз, когда в контроллере нет большого количества вычислений, то есть работа контроллера состоит в том, чтобы просто обновить его соответствующее представление. Здесь контроллер становится Presenter.

1 голос
/ 24 января 2009

Я думаю, что твои проблемы начинаются с неудачного выбора слов. «контрольные» вещи не имеют никакого отношения к «контроллеру» в MVC. вот почему некоторые библиотеки GUI используют другие имена (виджеты являются общими). ​​

ваш «древовидный элемент управления» - это представление, а не контроллер. он должен быть привязан к графическому интерфейсу как для отображения, так и для получения событий графического интерфейса и превращения их в «древовидные события».

контроллер получает эти «древовидные события» и вносит необходимые изменения в модель. вот где вы соединяете «действие» с «ответом».

1 голос
/ 24 января 2009

Ваши требования:

  • Дерево отображает представление модели
  • Узлы в дереве могут отправлять сообщения узлам внутри модели
  • Дерево перерисовывается на основе изменений модели

Я не знаю точно, с какими данными вы здесь работаете, но иерархическая модель - довольно простая вещь. Я приму это как данность, вы знаете, как перебирать иерархические данные и заполнять древовидное представление.

Ваш контроллер должен иметь функции-члены для отправки сообщений в модель. Параметры должны быть элементом модели и сообщением, которое вы хотите отправить. Таким образом, пользовательский интерфейс полностью не знает, как сообщение попадает в элемент, но может получать сообщения через него.

Последнее требование является более сложным и зависит от нескольких вещей (например, времени жизни контроллера, архитектуры приложения и т. Д.) Я собираюсь предположить, что контроллер живет столько же, сколько и древовидное представление. Если это так, то ваш контроллер должен предоставить способ установить обратный вызов при изменении модели. Затем, когда контроллер меняет модель, он может выполнить обратный вызов к пользовательскому интерфейсу, не зная об этом пользовательском интерфейсе.

1 голос
/ 24 января 2009

Qt предоставляет группу классов для программирования вида модели . Например, вы можете подключить дерево представление к файловой системе модель , и ни один из них напрямую не знает ничего друг о друге (кроме указателя на модель в представлении).

0 голосов
/ 24 января 2009

Вам нужен контроллер, который находится за пределами виджета дисплея, но имеет состояние дерева (в MFc есть классы CTreeView / CTreeCtrl - в Qt есть похожее разделение), контроллер дерева обрабатывает все хранилище данных и вызывает перерисовки виджет дерева.
Изменения в виджете дерева отправляются на контроллер дерева - поэтому этот контроллер должен знать о функциях графического интерфейса.

Модель должна будет установить / получить функции для всех соответствующих параметров для узлов. Но они могут возвращать простые типы, поэтому не зависят от графического интерфейса.

Обновление формы представления модели требует отправки сообщения, если вы не хотите, чтобы модель знала о вашем графическом обмене сообщениями, лучшее, что вы можете сделать, это зарегистрировать функцию обратного вызова (указатель на функцию void) из контроллера дерева - и позвоните, чтобы сделать обновление. Эта функция обновления может затем запросить модель на предмет изменений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...