按钮命令类获取参数

时间:2016-05-14 12:43:58

标签: c# wpf mvvm datagrid command

使用c#+ wpf + mvvm我试图在http://www.codeproject.com/Articles/819294/WPF-MVVM-step-by-step-Basics-to-Advance-Level

之后的第4级创建一个或多或少的通用“buttoncommand”类

我有一个绑定到observablecollection<mySpecialClass>的数据网格,并且一个按钮绑定了一个添加行的命令,并且没有任何参数可以正常工作。 但是我希望有一些按钮来插入和删除网格中的行,这将占用当前活动/选择的行的索引。

我尝试将按钮命令更改为以下内容(将Action what更改为Action<object> what):

public class ButtonCommandi : ICommand
  {
    private Action<object> _whattoExecute;
    private Func<bool> _whentoExecute;
    public ButtonCommandi(Action<object> what, Func<bool> when)
    {
      _whattoExecute = what;
      _whentoExecute = when;
    }

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

    public event EventHandler CanExecuteChanged;

    public void Execute(object parameter)
    {
      _whattoExecute(parameter); 
    }
  }
}

但是,在我的viewmodel中,当我尝试在构造函数中创建类的实例时:

public class MyViewModelClass
{
  private ButtonCommand _objAppendTerrainPointCommand;
  private ButtonCommandi _objInsertTerrainPointCommand;
  private MyModelClass _mymodel;  
  public MyVeiwModelClass()
    {
      ...
      _objAppendRowCommand = new ButtonCommand(_mymodel.Append, _mymodel.IsPossibleToAppend);
      _objInsertRowCommand= new ButtonCommandi(
        delegate(object i) { _mymodel.InsertRow(i); }, _mymodel.IsPossibleToInsert);
      ...
    }

它说“最好的重载方法匹配'MyModelClass.InsertRow(int)'有一些无效的参数”。我尝试了new ButtonCommandi(..)的一些不同版本,但似乎找不到方法。

在MyModelClass中,该函数如下所示:

internal void InsertRow(int idx)
    {
        _myObsColSpecial.Insert(idx);
    }

有没有人有一个很好的提示如何让这项工作? (我是wpf,mvvm和c#的新手。所以请耐心等待。据我所知,似乎有很多方法可以完成这样的事情,但是自从我开始这样做以后,最好不要重写“吨”的代码:))

1 个答案:

答案 0 :(得分:0)

对于传递对象的RelayCommand,请尝试这个....

class RelayCommand<T> : ICommand
{
    #region Fields

    readonly Action<T> _execute = null;
    readonly Predicate<T> _canExecute = null;

    #endregion

    #region Constructors

    /// <summary>
    /// Initializes a new instance of <see cref="DelegateCommand{T}"/>.
    /// </summary>
    /// <param name="execute">Delegate to execute when Execute is called on the command.  This can be null to just hook up a CanExecute delegate.</param>
    /// <remarks><seealso cref="CanExecute"/> will always return true.</remarks>
    public RelayCommand(Action<T> execute)
        : this(execute, null)
    {
    }

    /// <summary>
    /// Creates a new command.
    /// </summary>
    /// <param name="execute">The execution logic.</param>
    /// <param name="canExecute">The execution status logic.</param>
    public RelayCommand(Action<T> execute, Predicate<T> canExecute)
    {
        if (execute == null)
            throw new ArgumentNullException("execute");

        _execute = execute;
        _canExecute = canExecute;
    }

    #endregion

    #region ICommand Members

    ///<summary>
    ///Defines the method that determines whether the command can execute in its current state.
    ///</summary>
    ///<param name="parameter">Data used by the command.  If the command does not require data to be passed, this object can be set to null.</param>
    ///<returns>
    ///true if this command can be executed; otherwise, false.
    ///</returns>
    public bool CanExecute(object parameter)
    {
        return _canExecute == null ? true : _canExecute((T)parameter);
    }

    ///<summary>
    ///Occurs when changes occur that affect whether or not the command should execute.
    ///</summary>
    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }

    ///<summary>
    ///Defines the method to be called when the command is invoked.
    ///</summary>
    ///<param name="parameter">Data used by the command. If the command does not require data to be passed, this object can be set to <see langword="null" />.</param>
    public void Execute(object parameter)
    {
        _execute((T)parameter);
    }

    #endregion
}

在您的视图模型中......

class MainWindowVM
{
    public RelayCommand<string> WindowCommand { get; set; }

    public MainWindowVM()
    {
          WindowCommand = new RelayCommand<string>(OnWindowCommand);
    }

    private void OnWindowCommand(string obj)
    {
        // obj is the string passed from the Button CommandParameter
    }
}

在你的XAML中

<Window.DataContext>
    <local:MainWindowVM/>
</Window.DataContext>

<Grid>
    <Button Command="{Binding WindowCommand}" CommandParameter="Test" />
</Grid>