Переключение представлений в WPF, вопрос дизайна высокого уровня - PullRequest
3 голосов
/ 01 сентября 2011

Итак, я сейчас работаю над пользовательским интерфейсом, написанным на WPF.Одна вещь, которая мне действительно нравится в WPF, это то, как она заставляет вас писать более разрозненные изолированные компоненты пользовательского интерфейса.В WPF для меня одной из проблем является то, что это заставляет вас писать более разрозненные, изолированные компоненты пользовательского интерфейса, которые иногда должны взаимодействовать друг с другом :).Вероятно, это связано с моим относительным отсутствием опыта работы с пользовательским интерфейсом, особенно в WPF (я не новичок, но большая часть моей работы гораздо ниже, чем дизайн пользовательского интерфейса).

В любом случае, здесь ситуация:

В любой момент в центральной области пользовательского интерфейса отображается одно из трех представлений, реализованных как UserControl s, назовем их представлениями A, B и C.

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

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

Сегодня я столкнулся с ошибкой, связанной с временем переключения между представлениями.Для простоты одному представлению необходимо выполнить некоторую очистку, когда оно выгружено, но эта очистка удаляет некоторые данные, необходимые для другого представления.Если очистка запускается после , загружается другое представление, проблемы гарантируются.Видишь, о чем я?Грязный.

Я пытаюсь сделать шаг назад и представить себе другой способ загрузить эти представления данными, необходимыми для их работы.Некоторые из вас, опытные в UI / WPF, наверняка сталкивались с подобной проблемой.У меня есть пара идей, но я надеюсь, что кто-то представит мне более чистый подход.Мне не нравится зависеть от порядка операций (на высоком уровне), чтобы мой код работал правильно.Заранее благодарим за любую помощь, которую вы можете предложить.

Ответы [ 3 ]

5 голосов
/ 01 сентября 2011

Я бы порекомендовал какой-нибудь родительский ViewModel, который обрабатывает CurrentView. Я написал пример здесь некоторое время назад, если вам интересно.

В основном родительское представление будет иметь List<ViewModelBase> AvailablePages, ViewModelBase CurrentPage и ICommand ChangePageCommand

Как вы решите их отобразить, зависит от вас. Мой предпочтительный метод - ContentControl с привязкой Content к CurrentPage и использованием DataTemplates для определения того, какой View должен отображаться на основе ViewModel, сохраненного в CurrentPage

2 голосов
/ 01 сентября 2011

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

Обратите внимание, что все это предполагает подход ViewModel-first, как упоминалось в комментариях.

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

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

Все сделано правильно, в дизайне должно быть мало боли и много гибкости с точки зрения того, как фактически работает представление.

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

Здесь координирующая ViewModel может действительно облегчить ситуацию.Для него не требуется одиночка, так как он фактически «владеет» отдельными ViewModel представлений.Один из вариантов, который довольно прост, заключается в реализации интерфейса в ViewModels, который включает в себя событие - ViewModel может вызывать событие (которое я бы назвал, основываясь на том, что является намерением, а не на основе «изменения вида»).Координирующая виртуальная машина подписывается на каждую дочернюю виртуальную машину и в зависимости от события изменяет свое свойство «CurrentItem» (для активной виртуальной машины) на основе соответствующего содержимого для выполнения запроса.Сведения об интерфейсе не требуются.

Сегодня я столкнулся с ошибкой, связанной с временем переключения между представлениями.Для простоты одному представлению необходимо выполнить некоторую очистку, когда оно выгружено, но эта очистка удаляет некоторые данные, необходимые для другого представления.Если очистка запускается после загрузки другого представления, проблемы гарантированы.Видишь, о чем я?Грязный.

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

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

Это правильный способ думать здесь.Если этого можно избежать, в вашем коде не должно быть зависимостей от порядка, так как со временем это сделает жизнь намного проще.

Я пытаюсь сделать шаг назад и представить себе другой способ получитьэти представления загружены данными, необходимыми для их работы.

Подход, который мы с Рэйчел придерживаемся здесь, по сути является тем же подходом, который я использовал в своей серии на MVVM для реализацииВид мастер-детали.Здесь хорошо то, что «детальная» часть View не всегда должна быть одного и того же типа ViewModel или View - если вы используете ContentPresenter, привязанный к свойству, которое является просто Object (или интерфейс, которыйобщий доступ к виртуальным машинам), вы можете легко переключать представления с совершенно разными представлениями, просто изменяя значение свойства во время выполнения.

1 голос
/ 01 сентября 2011

Мое предложение для этого состоит в том, чтобы иметь одну модель основного вида, которая координирует все (не статическое / одноэлементное), с которым вы затем используете модели подвидов для передачи данных.Это обеспечивает развязку, которую вы ищете, обеспечивает тестируемость и позволяет вам контролировать, когда данные для каждого объекта изменяются.

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