Это не только в отношении вкладок, хотя мы используем вкладки, полученные аналогичным образом.Отправка событий в произвольном порядке через пользовательский интерфейс вызывает у меня большую путаницу (сохранение порядка, в котором запускаются различные события, и так далее).Вместо этого я создаю класс контроллера, который передается различным компонентам пользовательского интерфейса, и эти компоненты уведомляют контроллер об изменениях, а элементы пользовательского интерфейса подписываются на события на контроллере для получения информации об окружающей среде.
Чтобы сделать это конкретнымкаждой из производных вкладок передается ссылка на контроллер.Они могут изменять состояние контроллера в зависимости от действий пользователя.Скажем, текущая запись изменена, пользовательский интерфейс вызывает метод на контроллере, сообщая ему новую запись.
Другие элементы пользовательского интерфейса на странице уведомляются об этом изменении, поскольку они подписываются на событие контроллера OnCurrentRecordChange
.
Хотя это вводит в класс еще один класс, преимущество состоит в том, что у вас есть один контроллер, управляющий изменениями в пользовательском интерфейсе, а не куча событий, просачивающихся и передающих информацию.Я обнаружил, что это также нарушает зависимости от взаимодействия элементов пользовательского интерфейса: я могу добавлять, удалять или изменять элементы пользовательского интерфейса, и до тех пор, пока все они обращаются к контроллеру за обновлениями, кода гораздо меньше переделывается.
Если вы когда-либо сталкивалисьВы обнаружили, что отлаживаете «циклы» пользовательского интерфейса (когда изменения в одном элементе управления вызывают изменения в других элементах управления, которые вызывают еще больше изменений, которые в конечном итоге влияют на исходный компонент), тогда дополнительная работа класса контроллера немедленно окупится.
Обновление: отвечая на ваш комментарий ... Сначала остановимся на чтении архитектуры Model View Controller: http://en.wikipedia.org/wiki/Model%E2%80%93View%E2%80%93Controller
Для конкретного примера: http://www.dotnetheaven.com/Uploadfile/rmcochran/MVC_intro02012006001723AM/MVC_intro.aspx
При работе с WindowsФормы Многие люди застревают в двухуровневом дизайне: UI + Data Layer.Система привязки делает это очень естественным, поскольку есть простой способ получить данные (Entity Framework, LINQ) и простой способ привязать данные к пользовательскому интерфейсу (проектировщикам).Добавление контроллера между ними не так сложно, как может показаться.
В своей работе я использую LLBLGen (http://www.llblgen.com/defaultgeneric.aspx) для моего низкоуровневого уровня данных, но вы можете заменить LINQ или Entity Frameworkили любой другой инструмент доступа к данным, и общий обзор был бы таким же.
Над этим слоем я строю свои бизнес-объекты. Многие из них - не более чем фасады для объектов LLBLGen (если мои бизнес-правила этого не делают)много говорят о сущности), в то время как другие имеют много встроенных проверок и объединяют несколько низкоуровневых объектов в более удобные для использования бизнес-объекты. Наконец, есть бизнес-объекты, которые непосредственно не имеют сущностей позади них (объекты связи между системами,например).
Объект контроллера, о котором я упоминаю, живет рядом с моими бизнес-объектами, поскольку он знает об этих объектах и даже передает их в интерфейс пользователя для целей привязки данных. Когда пользовательский интерфейс хочет внести изменение, онуведомляет контроллер, и он использует бизнес-объекты дляубедитесь, что обновления разрешены и, если это так, передает изменения обратно на уровень данных.
На диаграмме в Википедии вид - это мой пользовательский интерфейс.Контроллер - это мой координационный объект, который обеспечивает изменения в обоих направлениях, в то время как Модель - это уровень моего бизнес-объекта (уровень которого ниже этого уровня, но это детали реализации, скрытые от верхних уровней).
Несмотря на то, что переход от «View <-> Model» (классическая привязка данных) к «View <-> Controller <-> Model» кажется сложным, основное преимущество заключается в том, что контроллер становится единым местом для покупок для«правда» о приложении.Пользовательский интерфейс запрашивает данные у контроллера, поэтому контроллер знает о всех элементах пользовательского интерфейса, которые имеют данную привязку данных.Если что-то меняется, событие уведомляет все элементы пользовательского интерфейса, и они визуально изменяются для пользователя.Приятно то, что в состоянии системы есть одна «истина», и именно эту истину контролирует контроллер для пользовательского интерфейса.
Когда необходимо сохранить данные, запрос отправляется на контроллер для обновления модели.Опять же, у нас есть единое место для координации сохранения и последующих обновлений.Все правила целостности проверки данных находятся на уровне бизнес-логики (Модель), поэтому код контроллера остается светлым.
Разделяя проблемы пользовательского интерфейса, проблемы координации и проблемы бизнес-логики, вы в конечном итоге получаетеимея очень "легкие" методы и свойства.Что еще более важно, каждая подсистема может иметь очень упрощенное представление о приложении, поскольку они сосредоточены на этом фрагменте головоломки вместо потоковых событий, обновлений пользовательского интерфейса и обновлений данных в одном монолитном фрагменте кода.
Для дальнейшего чтения я бы порекомендовал любую из статей или книг о ASP.NET MVC.Хотя это не Winforms, основные ideas , лежащие в основе MVC, могут быть применены к winforms.Здесь также есть несколько хороших комментариев: https://stackoverflow.com/questions/2406/looking-for-a-mvc-sample-for-winforms
Мне должно быть ясно, что то, что я делаю с моими проектами, вероятно, не считается "чистым" MVC, а просто разделением интересов по естественной ошибке.линии, найденные в приложениях, которые мы разрабатываем.Мы не используем для этого «фреймворк» (хотя требуется некоторое генерирование кода).