Выполнение методов ViewModel из Xamarin Forms Pages легко, но как можно вызывать методы страницы внутри ViewModels?
В Xamarin Forms, если вы привязываете команды ViewModel к кнопкам страницы, вся логика действия нажатия кнопки выполняется в ViewModel. Проблема в том, что ViewModel не имеет доступа к элементам управления Xamarin Forms, и поэтому трудно получить доступ к функциям Views из вашей ViewModel. Делегаты обычно не используются, поэтому я надеюсь, что эта статья добавит еще один инструмент в ваш арсенал, который вы можете использовать для решения ваших задач кодирования. Обратите внимание, что делегаты действия могут использоваться для всех платформ пользовательского интерфейса, использующих C #.
Пример использования: сосредоточить внимание на записи
Давайте рассмотрим сценарий, в котором у нас есть пароль Entry
и логин Button
для входа Page
. Наше требование состоит в том, что если пароль неверен, мы хотим, чтобы ввод пароля автоматически находился в фокусе клавиатуры. Как правило, действительность пароля определяется через ViewModel с использованием вашего уровня служб, и этот класс отвечает за навигацию, если пароль правильный. Но если пароль неверен и вы хотите, чтобы пользовательский интерфейс отреагировал на эту ошибку, будет сложно сделать это традиционными средствами.
Привет Action Invoke
Теперь мы можем создать событие в ViewModel и соответствующий обработчик событий в Page. Таким образом, каждый раз, когда это событие вызывается где-нибудь в ViewModel, этот метод обработчика событий автоматически вызывается на странице.
ViewModel изменения
Как вы можете видеть в этом образце, все, что вам нужно, когда сервисы определяют, что логин не удался и вы хотите, чтобы ввод пароля получил фокус, - это две строки кода в вашей ViewModel:
объявление события public Action<bool> OnLoginFailed { get; set; }
, а затем просто выполнив thisOnLoginFailed?.Invoke(true);
.
Изменения страницы
На странице вы просто назначаете обработчик событий для выполнения действия:
ViewModel.OnLoginFailed = ((obj) => { PasswordEntry.Focus(); });
Обратите внимание, что объявление Action имеет тип bool
, поэтому, когда мы вызываем его, мы должны передать значение соответствующего типа. Затем в обработчике событий страницы вы можете дополнительно получить доступ к этому конкретному значению (obj).
При использовании событий, чтобы избежать утечек памяти, вы можете попробовать WeakEventManager в Xamarin Community Toolkit. Если вы используете MvvmCross, вы можете использовать больше MvxInteraction, реализованное аналогичным образом. Behaviors - официальный способ реализации этой функциональности. Как предлагает Адам, вы можете использовать центр обмена сообщениями, но я думаю, что в этом нет необходимости. Если у вас есть какие-либо вопросы или мысли, не стесняйтесь обращаться каждый ко мне здесь. Вам нравится наша работа? Поддержите нас, следя за нами в социальных сетях и подписываясь на последние обновления здесь. Вы также можете узнать больше о Типе действий делегатов в C # здесь.