将参数传递给MVVM命令

luc*_*cas 14 c# wpf mvvm

有谁知道如何传递参数Command使用CommandHandler?我们假设我想从XAML传递字符串硬编码值.我知道如何从XAML传递,但不知道如何在后面的MVVM代码中处理它.如果不需要传递任何参数,下面的代码可以正常工作.

public ICommand AttachmentChecked
{
    get
    {
        return _attachmentChecked ?? (_attachmentChecked = new CommandHandler(() => ExecuteAttachmentChecked(), CanExecuteAttachmentChecked()));
    }
}

private void ExecuteAttachmentChecked()
{        
}

private bool CanExecuteAttachmentChecked()
{
    return true;
}
Run Code Online (Sandbox Code Playgroud)

CommandHandler:

public class CommandHandler : ICommand
{
    private Action _action;
    private bool _canExecute;

    public CommandHandler(Action action, bool canExecute)
    {
        _action = action;
        _canExecute = canExecute;
    }

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

    public event EventHandler CanExecuteChanged;

    public void Execute(object parameter)
    {
        _action();
    }
}
Run Code Online (Sandbox Code Playgroud)

Kyl*_*Ren 12

你需要改变两件事

1.更改您Commandhandler的接受参数

 public class CommandHandler : ICommand
{
    private Action<object> _action;
    private bool _canExecute;
    public CommandHandler(Action<object> action, bool canExecute)
    {
        _action = action;
        _canExecute = canExecute;
    }

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

    public event EventHandler CanExecuteChanged;

    public void Execute(object parameter)
    {
        _action(parameter);
    }
}
Run Code Online (Sandbox Code Playgroud)

2.更改方法接受CommandParameter:

public ICommand AttachmentChecked
{
    get
    {
        return _attachmentChecked ?? (_attachmentChecked = new CommandHandler(param => ExecuteAttachmentChecked(param), CanExecuteAttachmentChecked()));
    }
}

private void ExecuteAttachmentChecked(object param)
{
 //param will the value of `CommandParameter` sent from Binding
}

private bool CanExecuteAttachmentChecked()
{
    return true;
}
Run Code Online (Sandbox Code Playgroud)


Ste*_*pUp 10

您应该将您的字符串写入CommandParameter:

<Button Command="{Binding NextCommand}" 
CommandParameter="Hello" 
Content="Next" />
Run Code Online (Sandbox Code Playgroud)

并改为:

private Action _action;
private bool _canExecute;
Run Code Online (Sandbox Code Playgroud)

允许接受参数:

readonly Action<object> _execute;        
readonly Predicate<object> _canExecute;
Run Code Online (Sandbox Code Playgroud)

假设您RelayCommandobj方法参数中使用的DoSmth将是"Hello":

public RelayCommand YourCommand { get; set; }
public YourViewModel()
{
    NextCommand = new RelayCommand(DoSmth);
}

private void DoSmth(object obj)
{
    Message.Box(obj.ToString()); 
}
Run Code Online (Sandbox Code Playgroud)


小智 7

这已经得到了解答,但您可能不知道有一些框架可以避免与MVVM中的命令(和INotifyPropertyChanged)相关的样板代码.

其中最着名的是MVVM Light,它将为您处理一些事情.

使用此框架,您可以使用以下参数处理命令:

(注意:我们将创建一个更改UserControl显示的命令,因为UserControl是应用程序的"主要部分")

1)在ViewModel中,定义一个带有参数类型的RelayCommand(在本例中为UserControl)

public RelayCommand<UserControl> changePageCommand { get; private set; }
Run Code Online (Sandbox Code Playgroud)

2)定义要绑定到命令的方法(这里简化)

public void navigate(UserControl nextPage)
{
    currentUserControl = nextPage; 
}
Run Code Online (Sandbox Code Playgroud)

3)将命令绑定到刚刚定义的方法

changePageCommand = new RelayCommand<UserControl>((page) => navigate(page));
Run Code Online (Sandbox Code Playgroud)

您的命令现在已全部设置好并可以在XAML中使用,假设您要切换带有菜单选项的页面,例如......

4)使用参数绑定命令到控件(XAML)

<Menu>
    <MenuItem Header="_Pages">
        <MenuItem Header="_Account"
                  Command="{Binding changePageCommand}"
                  CommandParameter="{Binding pageManager.accountPage}" />
        <MenuItem Header="_Profile"
                  Command="{Binding changePageCommand}"
                  CommandParameter="{Binding pageManager.profilePage}" />
    </MenuItem>
</Menu>
Run Code Online (Sandbox Code Playgroud)

注意:pageManager只是一个将我的所有页面初始化为默认状态的类,显然在我的ViewModel中引用了它.

希望这可以帮助你或任何路过的人


Eld*_*iev 6

该参数在ICommand.Execute方法中传递,您只需将其传递给您的处理程序.

public class CommandHandler : ICommand
{
    private Action<object> _action;
    private bool _canExecute;
    public CommandHandler(Action<object> action, bool canExecute)
    {
        _action = action;
        _canExecute = canExecute;
    }

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

    public event EventHandler CanExecuteChanged;

    public void Execute(object parameter)
    {
        _action(parameter);
    }
}
Run Code Online (Sandbox Code Playgroud)