2016-05-14 79 views
0

使用C#+ WPF + MVVM我試圖做一個或多或少通用「buttoncommand」級以下級別4在http://www.codeproject.com/Articles/819294/WPF-MVVM-step-by-step-Basics-to-Advance-Level按鈕命令類帶參數

我有一個綁定到observablecollection<mySpecialClass>和一個按鈕一個DataGrid多數民衆贊成綁定了一個添加行並且沒有任何參數可以正常工作的命令。 但是,我想要有按鈕來插入和刪除網格中的行,這將採取當前活動/選擇行的索引。

我試圖給buttoncommand更改爲以下(改變Action whatAction<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); 
    } 
    } 
} 

然而,在我的視圖模型,我嘗試在構造函數來創建類的實例:

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#都很陌生,據我所知,據我所知,似乎有很多方法可以完成這樣的事情,但自從我開始這樣做以後,最好不要重寫代碼:))

+2

_mymodel.InsertRow((int)i); –

回答

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> 
+0

非常感謝,它可以很好地處理一個參數。它在評論中說,它適用於不帶參數的函數(null),但是我似乎沒有開始工作。你能詳細說明一下嗎?或者我必須爲此創建一個單獨的RelayCommand類,而不需要''?? –