2016-02-12 139 views
6

有谁知道如何使用CommandHandler将参数传递给Command?假设我想从XAML传递字符串硬编码值。我知道如何从XAML传递,但不知道如何在MVVM代码中处理它。下面的代码工作正常,如果没有必要传递任何参数。传递参数给MVVM命令

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

private void ExecuteAttachmentChecked() 
{   
} 

private bool CanExecuteAttachmentChecked() 
{ 
    return true; 
} 

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(); 
    } 
} 

回答

7

你需要改变两个东西

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); 
    } 
} 

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; 
} 
5

的参数在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); 
    } 
} 
7

你应该只写你的串入CommandParameter:

<Button Command="{Binding NextCommand}" 
CommandParameter="Hello" 
Content="Next" /> 

与变革:

private Action _action; 
private bool _canExecute; 

允许接受参数:

readonly Action<object> _execute;   
readonly Predicate<object> _canExecute; 

假设你是使用RelayCommand的方法DoSmth的参数obj将是 “你好”:

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

private void DoSmth(object obj) 
{ 
    Message.Box(obj.ToString()); 
} 
3

这已经回答了,但你可能不知道,有一些框架周围,以避免相关命令(和INotifyPropertyChanged的)在MVVM样板代码。

其中最有名的是MVVM Light,可以为您处理几件事。

利用这个框架,这是你如何处理带有参数的命令:

(注:我们要创建改变了用户控件显示的命令,因为用户控件是“主要部件”的应用程序)

1)在你的视图模型,定义与类型参数的RelayCommand(在这种情况下,用户控件)

public RelayCommand<UserControl> changePageCommand { get; private set; } 

2)定义的方法将被绑定到的命令(在此简化的)

public void navigate(UserControl nextPage) 
{ 
    currentUserControl = nextPage; 
} 

3)绑定你的命令,你只需定义

changePageCommand = new RelayCommand<UserControl>((page) => navigate(page)); 

你的命令现在所有的设置和准备在您的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> 

注:PageManager是仅仅是INI类将我的所有页面都设置为默认状态,显然在我的ViewModel中引用了它。

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