从Code Behind调用命令

时间:2012-04-12 15:37:54

标签: c# wpf xaml data-binding command

所以我一直在寻找并且无法确切地知道如何做到这一点。我正在使用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>

我确信有一个简单的方法可以做到这一点,但我不能为我的生活弄清楚。

6 个答案:

答案 0 :(得分:120)

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

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

(根据需要更改参数)

答案 1 :(得分:5)

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

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

答案 2 :(得分: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)
}

答案 3 :(得分:1)

我想要分享一个更紧凑的解决方案。因为我经常在我的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();

我希望这会加快你的开发速度。 :)

P.S。不要忘记包含ICommandHelper的命名空间。 (在我的例子中,它是SharedViewModels.Helpers)

答案 4 :(得分:0)

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

我希望它有所帮助。

答案 5 :(得分:0)

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

例如: 调用按钮命令

#trapezoid {
border-bottom: 500px solid #555;
    border-left: 0px solid transparent;
    border-right: 125px solid transparent;
    height: 0;
    width: 500px;
}