it-swarm.com.ru

Команда вызова из кода позади

Так что я искал вокруг и не могу узнать точно, как это сделать. Я создаю пользовательский элемент управления с использованием MVVM и хотел бы запустить команду для события «Loaded». Я понимаю, что для этого нужно немного кода, но я не могу понять, что нужно. Команда находится в ViewModel, которая установлена ​​как текстовый текст представления, но я не уверен, как именно направить это, чтобы я мог вызвать его из кода позади загруженного события. По сути, я хочу что-то вроде этого ...

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

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

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

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

56
Kevin DiTraglia

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

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

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

118
H.B.

Предисловие. Не зная больше о ваших требованиях, кажется, что пахнет кодом выполнение команды из кода при загрузке. Должен быть лучший путь, с точки зрения 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);
} 

Опять же - попробуйте найти лучший способ ...

5
Wonko the Sane

У меня есть более компактное решение, которым я хочу поделиться. Поскольку я часто выполняю команды в своих 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();

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

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

1
Stefan Vasiljevic

Попробуй это:

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)
}
1
Alain

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

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

0
Joilson Cardoso