84

所以我一直在四处寻找,无法确切地知道如何做到这一点。我正在使用 MVVM 创建用户控件,并希望在“加载”事件上运行命令。我意识到这需要一些代码,但我不太清楚需要什么。该命令位于 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>

我敢肯定有一种简单的方法可以做到这一点,但我终其一生都无法弄清楚。

4

6 回答 6

161

好吧,如果 DataContext 已经设置,你可以转换它并调用命令:

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

(根据需要更改参数)

于 2012-04-12T15:44:01.137 回答
8

前言:在不了解您的要求的情况下,在加载时从代码隐藏执行命令似乎是一种代码味道。必须有更好的方法,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);
} 

再次 - 尝试找到更好的方法......

于 2012-04-12T15:45:46.927 回答
2

我想分享一个更紧凑的解决方案。因为我经常在 ViewModel 中执行命令,所以我厌倦了编写相同的 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();

我希望这将加快您的开发速度。:)

PS 不要忘记也包括 ICommandHelper 的命名空间。(在我的情况下,它是 SharedViewModels.Helpers)

于 2016-02-17T20:30:26.080 回答
1

试试这个:

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)
}
于 2012-04-12T15:43:42.977 回答
1

要在代码后面调用命令,您可以使用此代码行

例如:调用按钮命令

Button.Command?.Execute(Button.CommandParameter);
于 2020-07-29T12:04:20.403 回答
0

您也可能已将代码嵌入到任何 MessaginCenter.Subscribe 并使用 MessagingCenter 模型。如果您只想从后面的代码中执行某些操作,而不是单击具有 Command 属性的视图按钮,那么它对我来说非常有效。

我希望它可以帮助某人。

于 2018-03-29T15:29:32.087 回答