2013-10-14 31 views
3

在我的項目中,我想使用MVVM(&命令)。我已經開始瞭解ICommand的命令和實現。如何實現沒有參數的ICommand

我想創建不帶參數的ICommand的實現。 (要觸發數據的數據/沖洗等的負荷 - 我不需要任何參數來做到這一點,所以它只是很自然地嘗試不帶參數創建命令)

這是我的代碼「M使用:

using System.Windows.Input; 

public class NoParameterCommand : ICommand 
{ 
    private Action executeDelegate = null; 
    private Func<bool> canExecuteDelegate = null; 
    public event EventHandler CanExecuteChanged = null; 

    public NoParameterCommand(Action execute) 
    { 
     executeDelegate = execute; 
     canExecuteDelegate =() => { return true; }; 
    } 
    public NoParameterCommand(Action execute, Func<bool> canExecute) 
    { 
     executeDelegate = execute; 
     canExecuteDelegate = canExecute; 
    } 

    public bool CanExecute() 
    { 
     return canExecuteDelegate(); 
    } 
    public void Execute() 
    { 
     if (executeDelegate != null) 
     { 
      executeDelegate(); 
     } 
    } 
} 

但我得到了正確的方式 ('XXX.YYYY.NoParameterCommand' does not implement interface member 'System.Windows.Input.ICommand.Execute(object)'

所以我想過做這樣反而不執行ICommand接口錯誤:

(由來自CanExecute中缺少的參數和Execute

public class NoParameterCommand : ICommand 
{ 
    ...omitted - no changes here... 

    public bool CanExecute(object parameter) //here I added parameter 
    { 
     return canExecuteDelegate(); 
    } 
    public void Execute(object parameter) //and here 
    { 
     if (executeDelegate != null) 
     { 
      executeDelegate(); 
     } 
    } 
} 
  1. IS就是一個很好的辦法做到這一點?
  2. 我應該使用其他方式嗎? (如果這樣,我該怎麼辦呢?)
+0

這是一個很好的方法,當然除了把你的領域和事件初始化爲空是沒有意義的。默認情況下,字段爲空,事件背後的字段也爲空。 –

+0

@KrisVandermotten這只是一種我無法擺脫的舊習慣。直到你指出它,甚至沒有意識到它在那裏。 :) – mishan

回答

4
  1. 這是做一個好辦法。
  2. 不,你不應該用另一種方式。

補充建議:

考慮這個,我再次將通過引入額外的層次水平,CanExecute()Execute()abstract提高你的架構。從那個類中,派生你的調用委託的命令類。

這樣,您可以稍後決定是否要通過委託或通過繼承基類命令類爲您的無參數命令提供邏輯。

+0

我不知道如果我做對了。比對不起更安全。感謝您提供快速的回覆和建議,這次我將使用代表 - 對我更合適,但我會牢記在心。 – mishan

3

我不太確定你的擔憂是什麼。通常忽略接口中的參數。

如果您確實想要CanExecuteExecute方法沒有參數,您可以明確(而不是隱含地)實現接口。該ICommand方法將仍然存在,但任何人看着從外面你的對象,他們將無法看到這些方法:

bool ICommand.CanExecute(object parameter) { this.CanExecute(); } 

public bool CanExecute() 
{ 
    //do work 
} 

你基本上是隱藏接口實行。如果有人想從界面直接調用CanExecute方法,他們必須鍵入cast到ICommand才能完成。這樣做你真的沒有獲得任何東西,但是如果你關心你的類對外部開發人員的看法(例如,你正在開發一個API),那麼這可以讓它看起來更清晰,因爲你讓他們知道你不需要任何參數。

+0

我只是不確定我是否做得對,所以我問。我是WP8開發的新手,我只是在學習如何去做。網絡上有成千上萬的教程,但我無法找到我所想的是否正確。 – mishan

1

我個人比較喜歡這種方式:

public class MyCommand : ICommand 
{ 
    private static bool True() { return true; } 

    private readonly Action _execute; 
    private Func<bool> _canExecute; 
    private Func<bool> _isVisible; 

    public event EventHandler IsVisibleChanged; 
    public event EventHandler CanExecuteChanged; 

    public MyCommand(Action execute, Func<bool> canExecute = null, Func<bool> isVisible = null) 
    { 
     _execute = execute; 
     _canExecute = canExecute ?? True; 
     _isVisible = isVisible ?? True; 
    } 

    public void Execute() 
    { 
     _execute(); 
    } 

    public Func<bool> CanExecute 
    { 
     set 
     { 
      _canExecute = value ?? True; 
      CanExecuteChanged(this, new EventArgs()); 
     } 
     get { return _canExecute; } 
    } 

    public Func<bool> IsVisible 
    { 
     set 
     { 
      _isVisible = value ?? True; 
      IsVisibleChanged(this, new EventArgs()); 
     } 
     get { return _isVisible; } 
    } 

    bool ICommand.CanExecute(object parameter) 
    { 
     return CanExecute(); 
    } 

    void ICommand.Execute(object parameter) 
    { 
     Execute(); 
    } 
} 

然而,由於代表通常不會改變,我更喜歡一個不變的版本:

[ImmutableObject(true)] 
public class MyImmutableCommand : ICommand 
{ 
    private static bool True() { return true; } 

    private readonly Action _execute; 
    private readonly Func<bool> _canExecute; 
    private readonly Func<bool> _isVisible; 

    [Obsolete("Will not be invoked, because the implementation never changes.")] 
    public event EventHandler CanExecuteChanged; 

    public MyImmutableCommand(Action execute, Func<bool> canExecute = null, Func<bool> isVisible = null) 
    { 
     _execute = execute; 
     _canExecute = canExecute ?? True; 
     _isVisible = isVisible ?? True; 
    } 

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

    public bool IsVisible() 
    { 
     return _isVisible(); 
    } 

    public void Execute() 
    { 
     _execute(); 
    } 

    bool ICommand.CanExecute(object parameter) 
    { 
     return CanExecute(); 
    } 

    void ICommand.Execute(object parameter) 
    { 
     Execute(); 
    } 
} 
相關問題