Вызов команды из кода - программирование
Подтвердить что ты не робот

Вызов команды из кода

Итак, я искал и не могу точно узнать, как это сделать. Я создаю пользовательский элемент управления с помощью MVVM и хотел бы запустить команду в событии "Loaded". Я понимаю, что это требует немного кода, но я не могу понять, что нужно. Команда расположена в ViewModel, которая задана как datacontext представления, но я не уверен точно, как ее маршрутизировать, поэтому я могу назвать ее из кода, стоящего за загруженным событием. В принципе, я хочу что-то вроде этого...

private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
    //Call command from viewmodel
}

Оглядываясь, я не могу найти синтаксис для этого где угодно. Нужно ли мне сначала привязать команду в xaml, чтобы иметь возможность ссылаться на нее? Я замечаю, что параметр привязки команд в пользовательском элементе управления не позволит вам связывать команды так, как вы можете, что-то вроде кнопки...

<UserControl.CommandBindings>
    <CommandBinding Command="{Binding MyCommand}" /> <!-- Throws compile error -->
</UserControl.CommandBindings>

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

4b9b3361

Ответ 1

Ну, если DataContext уже установлен, вы можете его набросить и вызвать команду:

var viewModel = (MyViewModel)DataContext;
if (viewModel.MyCommand.CanExecute(null))
    viewModel.MyCommand.Execute(null);

(При необходимости измените параметр)

Ответ 2

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

Но если вам действительно нужно сделать это в коде, что-то вроде этого, вероятно, будет работать (обратите внимание: я не могу проверить это на данный момент):

private void UserControl_Loaded(object sender, RoutedEventArgs e)     
{
    // Get the viewmodel from the DataContext
    MyViewModel vm = this.DataContext as MyViewModel;

    //Call command from viewmodel     
    if ((vm != null) && (vm.MyCommand.CanExecute(null)))
        vm.MyCommand.Execute(null);
} 

Снова - попытайтесь найти лучший способ...

Ответ 3

Попробуйте следующее:

private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
    //Optional - first test if the DataContext is not a MyViewModel
    if( !this.DataContext is MyViewModel) return;
    //Optional - check the CanExecute
    if( !((MyViewModel) this.DataContext).MyCommand.CanExecute(null) ) return;
    //Execute the command
    ((MyViewModel) this.DataContext).MyCommand.Execute(null)
}

Ответ 4

У меня есть более компактное решение, которое я хочу поделиться. Поскольку я часто выполняю команды в своих моделях ViewModels, я устал писать один и тот же оператор if. Поэтому я написал расширение для интерфейса ICommand.

using System.Windows.Input;

namespace SharedViewModels.Helpers
{
    public static class ICommandHelper
    {
        public static bool CheckBeginExecute(this ICommand command)
        {
            return CheckBeginExecuteCommand(command);
        }

        public static bool CheckBeginExecuteCommand(ICommand command)
        {
            var canExecute = false;
            lock (command)
            {
                canExecute = command.CanExecute(null);
                if (canExecute)
                {
                    command.Execute(null);
                }
            }

            return canExecute;
        }
    }
}

И вот как вы будете выполнять команду в коде:

((MyViewModel)DataContext).MyCommand.CheckBeginExecute();

Надеюсь, это ускорит ваше развитие чуть больше.:)

P.S. Не забудьте также включить пространство имен ICommandHelper. (В моем случае это SharedViewModels.Helpers)

Ответ 5

Вы также могли бы встроить свой код в любой MessaginCenter.Subscribe и работать с моделью MessagingCenter. Если вы намерены выполнять только что-то из кода, вместо того, чтобы щелкнуть кнопкой просмотра с помощью свойства Command, это сработало отлично для меня.

Надеюсь, это поможет кому-то.