C# 是否将命令参数传递给WPF中ViewModel中的方法?

C# 是否将命令参数传递给WPF中ViewModel中的方法?,c#,wpf,mvvm,icommand,C#,Wpf,Mvvm,Icommand,我正在尝试将CommandParameter传递给我的ViewModel中的方法。 如何做到这一点 private void Open(object sender) { if (sender==this.objMainWindow.btnHistory) { objMainWindow.Container.Child = objHistory; } if (sender == this.objMainWindow.btnNew_Item)

我正在尝试将
CommandParameter
传递给我的
ViewModel
中的方法。 如何做到这一点

private void Open(object sender)
{
    if (sender==this.objMainWindow.btnHistory)
    {
        objMainWindow.Container.Child = objHistory;
    }

    if (sender == this.objMainWindow.btnNew_Item)
    {
        objMainWindow.Container.Child = objNewItem;
    }

    if (sender == this.objMainWindow.btnSide_Effects)
    {
        objMainWindow.Container.Child = objSideEffect;
    }
}
这是我想传递的
CommandParameter
视图模型中的meyhod。我对按钮使用了
CommandParameter

“视图模型”意味着MVVM。如果您正在使用MVVM,则不应该将视图传递到视图模型中。通常在XAML中执行以下操作:

<Button Content="Edit" 
        Command="{Binding EditCommand}"
        CommandParameter="{Binding ViewModelItem}" >

然后在您的视图模型中:

private ViewModelItemType _ViewModelItem;
public ViewModelItemType ViewModelItem
{
    get
    {
        return this._ViewModelItem;
    }
    set
    {
        this._ViewModelItem = value;
        RaisePropertyChanged(() => this.ViewModelItem);
    }
}

public ICommand EditCommand { get { return new RelayCommand<ViewModelItemType>(OnEdit); } }
private void OnEdit(ViewModelItemType itemToEdit)
{
    ... do something here...
}
私有ViewModelItemType\u ViewModelItem;
公共ViewModelItemType ViewModelItem
{
得到
{
返回此项。\u ViewModelItem;
}
设置
{
此项。_ViewModelItem=值;
RaisePropertyChanged(()=>this.ViewModelItem);
}
}
public ICommand EditCommand{get{返回新的RelayCommand(OnEdit);}
私有void OneEdit(ViewModelItemType itemToEdit)
{
…在这里做点什么。。。
}

显然,这只是为了说明这一点,如果您只有一个名为ViewModelItem的属性需要编辑,那么您就不需要将其作为命令参数传入。

如果您特别想将元素传递给viewmodel,您可以使用它

 CommandParameter="{Binding ElementName=ManualParcelScanScreen}"

仅使用数据绑定语法。比如说,

<Button x:Name="btn" 
         Content="Click" 
         Command="{Binding ClickCmd}" 
         CommandParameter="{Binding ElementName=btn,Path=Content}" /> 

我们不仅可以使用数据绑定从视图模型中获取一些数据,还可以将数据传递回视图模型。在CommandParameter中,必须使用ElementName显式声明绑定源。

尝试以下操作:

 public class MyVmBase : INotifyPropertyChanged
{
  private ICommand _clickCommand;
   public ICommand ClickCommand
    {
        get
        {
            return _clickCommand ?? (_clickCommand = new CommandHandler( MyAction));
        }
    }
    
       public void MyAction(object message)
    {
        if(message == null)
        {
            Notify($"Method {message} not defined");
            return;
        }
        switch (message.ToString())
        {
            case "btnAdd":
                {
                    btnAdd_Click();
                    break;
                }

            case "BtnEdit_Click":
                {
                    BtnEdit_Click();
                    break;
                }

            default:
                throw new Exception($"Method {message} not defined");
                break;
        }
    }
}

  public class CommandHandler : ICommand
{
    private Action<object> _action;
    private Func<object, bool> _canExecute;

    /// <summary>
    /// Creates instance of the command handler
    /// </summary>
    /// <param name="action">Action to be executed by the command</param>
    /// <param name="canExecute">A bolean property to containing current permissions to execute the command</param>
    public CommandHandler(Action<object> action, Func<object, bool> canExecute)
    {
        if (action == null) throw new ArgumentNullException(nameof(action));
        _action = action;
        _canExecute = canExecute ?? (x => true);
    }
    public CommandHandler(Action<object> action) : this(action, null)
    {
    }

    /// <summary>
    /// Wires CanExecuteChanged event 
    /// </summary>
    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }

    /// <summary>
    /// Forcess checking if execute is allowed
    /// </summary>
    /// <param name="parameter"></param>
    /// <returns></returns>
    public bool CanExecute(object parameter)
    {
        return _canExecute(parameter);
    }

    public void Execute(object parameter)
    {
        _action(parameter);
    }
    public void Refresh()
    {
        CommandManager.InvalidateRequerySuggested();
    }
}
公共类MyVmBase:INotifyPropertyChanged
{
专用ICommand_clickCommand;
公共ICommand ClickCommand
{
得到
{
返回_clickCommand??(_clickCommand=newcommandhandler(MyAction));
}
}
公共void MyAction(对象消息)
{
如果(消息==null)
{
通知($“未定义方法{message}”);
返回;
}
开关(message.ToString())
{
案例“btnAdd”:
{
点击按钮();
打破
}
案例“BtnEdit_Click”:
{
BtnEdit_Click();
打破
}
违约:
抛出新异常($“未定义方法{message}”);
打破
}
}
}
公共类CommandHandler:ICommand
{
私人行动;
私人职能执行;
/// 
///创建命令处理程序的实例
/// 
///要由命令执行的操作
///包含执行命令的当前权限的bolean属性
公共命令处理程序(操作,Func canExecute)
{
如果(action==null)抛出新的ArgumentNullException(nameof(action));
_行动=行动;
_canExecute=canExecute??(x=>true);
}
公共CommandHandler(操作):此(操作,null)
{
}
/// 
///导线可以执行更改事件
/// 
公共事件事件处理程序CanExecuteChanged
{
添加{CommandManager.RequerySuggested+=value;}
删除{CommandManager.RequerySuggested-=value;}
}
/// 
///强制检查是否允许执行
/// 
/// 
/// 
公共布尔CanExecute(对象参数)
{
返回_canExecute(参数);
}
public void Execute(对象参数)
{
_作用(参数);
}
公共无效刷新()
{
CommandManager.InvalidateRequestSuggested();
}
}
在xaml中:

     <Button
    Command="{Binding ClickCommand}"
    CommandParameter="BtnEdit_Click"/>


如何使用RaisePropertyChanged()?这只是属性更改通知MVVM Lite的实现,您可以通过NuGet添加它(从ViewModelBase派生视图模型)。不过,还有许多其他方法可以进行编辑,包括显示的和。@marbel82确实是这样,感谢您的更正(很遗憾,无法编辑注释)。“如果您只有一个名为ViewModelItem的属性可编辑,则不需要将其作为命令参数传入。”。无论视图模型上有多少个属性,我认为传递属性值的目的是为了避免可能发生的争用条件(因为该属性可能在用户单击按钮和单击后读取的属性之间发生变化),没有比赛条件。如果在处理程序中首先执行异步调用,然后获取参数,则该参数的值可能与传入参数时的值不同。