C# 从viewmodel调用方法的命令

C# 从viewmodel调用方法的命令,c#,wpf,xaml,mvvm,command,C#,Wpf,Xaml,Mvvm,Command,好吧,我倾向于避免使用命令,因为它们总是让我感到困惑,但我正在进行一个新项目,并且正在尝试正确地构建它,而视图中没有代码落后。基本上,我现在要做的就是连接一个按钮,启动一个命令,在我的视图模型上做一些事情,但不知何故,这么简单的事情仍然给我带来麻烦。我想我离这里很近,但还没到那里。这是我现在拥有的 <Window.Resources> <RoutedUICommand x:Key="GetMusic" /> </Window.Resources> &l

好吧,我倾向于避免使用命令,因为它们总是让我感到困惑,但我正在进行一个新项目,并且正在尝试正确地构建它,而视图中没有代码落后。基本上,我现在要做的就是连接一个按钮,启动一个命令,在我的视图模型上做一些事情,但不知何故,这么简单的事情仍然给我带来麻烦。我想我离这里很近,但还没到那里。这是我现在拥有的

<Window.Resources>
    <RoutedUICommand x:Key="GetMusic" />
</Window.Resources>
<Window.DataContext>
    <core:ViewMain />
</Window.DataContext>
<Window.CommandBindings>
    <CommandBinding Command="{StaticResource GetMusic}" Executed="GetMusicExecuted"/>
</Window.CommandBindings>

现在我要做的是连接我在命令绑定中设置的这个命令,以便在视图模型中调用我执行的方法,但是它试图在视图本身中找到该方法。有没有一种方法可以将它直接指向视图模型中的方法,或者有更好的方法来设置它以完成相同的任务?希望一开始就保持简单,这样我就不会过早地发疯。

我倾向于使用自己的命令类,实现ICommand。然后将按钮命令属性绑定到视图模型中的命令属性。单击该按钮时,它将执行绑定到Command属性的Execute方法

这是一个丑陋的两分钟版本,但它展示了如何创建一个命令类,然后将其委托给视图模型上您喜欢的任何方法

ViewModel:

public class MyViewModel
{
    public MyCommand ActionCommand
    {
        get;
        set;
    }

    public MyViewModel()
    {
        ActionCommand = new MyCommand();
        ActionCommand.CanExecuteFunc = obj => true;
        ActionCommand.ExecuteFunc = MyActionFunc;
    }

    public void MyActionFunc(object parameter)
    {
        // Do stuff here 
    }

}

public class MyCommand : ICommand 
{
    public Predicate<object> CanExecuteFunc
    {
        get;
        set;
    }

    public Action<object> ExecuteFunc
    {
        get;
        set;
    }

    public bool CanExecute(object parameter)
    {
        return CanExecuteFunc(parameter);
    }

    public event EventHandler CanExecuteChanged;

    public void Execute(object parameter)
    {
        ExecuteFunc(parameter);
    }
}
公共类MyViewModel
{
公共MyCommand操作命令
{
得到;
设置
}
公共MyViewModel()
{
ActionCommand=新的MyCommand();
ActionCommand.CanExecuteFunc=obj=>true;
ActionCommand.ExecuteFunc=MyActionFunc;
}
public void MyActionFunc(对象参数)
{
//在这里做事
}
}
公共类MyCommand:ICommand
{
公共谓词CanExecuteFunc
{
得到;
设置
}
公共行动执行委员会
{
得到;
设置
}
公共布尔CanExecute(对象参数)
{
返回CanExecuteFunc(参数);
}
公共事件处理程序CanExecuteChanged;
public void Execute(对象参数)
{
ExecuteFunc(参数);
}
}
视图将绑定到它(假设DataContext设置为视图模型的实例):


行动

您需要通过xaml或后面的代码设置绑定。您是否考虑过在标准MVVM框架(如Prism)中使用delegateCommand?我认为这使命令更容易执行,因为您的命令驻留在VM中,您可以绑定它而无需定义CommandBinding。看起来不错,在这种情况下,您是否使用MyCommand作为每个命令的基础,因为您可以为每个命令发送不同的函数来执行?在这种情况下,是的。如果您只想调用视图模型上的现有方法,那么就不必创建大量不同的命令类。如果需要,可以创建不同的命令。
public class MyViewModel
{
    public MyCommand ActionCommand
    {
        get;
        set;
    }

    public MyViewModel()
    {
        ActionCommand = new MyCommand();
        ActionCommand.CanExecuteFunc = obj => true;
        ActionCommand.ExecuteFunc = MyActionFunc;
    }

    public void MyActionFunc(object parameter)
    {
        // Do stuff here 
    }

}

public class MyCommand : ICommand 
{
    public Predicate<object> CanExecuteFunc
    {
        get;
        set;
    }

    public Action<object> ExecuteFunc
    {
        get;
        set;
    }

    public bool CanExecute(object parameter)
    {
        return CanExecuteFunc(parameter);
    }

    public event EventHandler CanExecuteChanged;

    public void Execute(object parameter)
    {
        ExecuteFunc(parameter);
    }
}
<Window x:Class="exp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Button Command="{Binding Path=ActionCommand}">Action</Button>
    </Grid>
</Window>