將命令抽象到視圖模型中是XAML/MVVM項目的一個有價值的實踐。我明白了。而且,我在WinRT中看到了ICommand;但是,我們如何實現它?我還沒有找到真正有效的樣本。有人知道嗎?任何WinRT的iCommand/CommandBinding實現樣本在那裏?
回答
我一直的最愛必須是由PnP團隊提供的DelegateCommand。它允許你創建一個類型的命令:
MyCommand = new DelegateCommand<MyEntity>(OnExecute);
...
private void OnExecute(MyEntity entity)
{...}
它還可以提供一種方式來提高CanExecuteChanged事件(禁用/啓用命令)
MyCommand.RaiseCanExecuteChanged();
下面的代碼:
public class DelegateCommand<T> : ICommand
{
private readonly Func<T, bool> _canExecuteMethod;
private readonly Action<T> _executeMethod;
#region Constructors
public DelegateCommand(Action<T> executeMethod)
: this(executeMethod, null)
{
}
public DelegateCommand(Action<T> executeMethod, Func<T, bool> canExecuteMethod)
{
_executeMethod = executeMethod;
_canExecuteMethod = canExecuteMethod;
}
#endregion Constructors
#region ICommand Members
public event EventHandler CanExecuteChanged;
bool ICommand.CanExecute(object parameter)
{
try
{
return CanExecute((T)parameter);
}
catch { return false; }
}
void ICommand.Execute(object parameter)
{
Execute((T)parameter);
}
#endregion ICommand Members
#region Public Methods
public bool CanExecute(T parameter)
{
return ((_canExecuteMethod == null) || _canExecuteMethod(parameter));
}
public void Execute(T parameter)
{
if (_executeMethod != null)
{
_executeMethod(parameter);
}
}
public void RaiseCanExecuteChanged()
{
OnCanExecuteChanged(EventArgs.Empty);
}
#endregion Public Methods
#region Protected Methods
protected virtual void OnCanExecuteChanged(EventArgs e)
{
var handler = CanExecuteChanged;
if (handler != null)
{
handler(this, e);
}
}
#endregion Protected Methods
}
我不喜歡通用部分(默認),但我喜歡這個示例! – 2012-08-22 02:00:15
@ JerryNixon-MSFT - 你爲什麼不「像通用部分」?如果你想避免泛型,你必須通過執行Action
@Shawn Kendrot - 在ICommand中使代碼更復雜。 CanExecute,你可以替換那個潛在的昂貴的try ... catch塊,你能不能'返回CanExecute(參數爲T)',然後在'CanExecute'中添加一個'parameter == null'的檢查? – 2013-08-03 16:33:54
退房RelayCommand類(只有METRO代碼)。 NotifyPropertyChanged
類可以找到here。 NotifyPropertyChanged
類僅用於允許在CanExecute
上進行綁定並使用RaiseCanExecuteChanged
進行更新。
原來的繼電器命令類可以發現here
遺憾的是,似乎沒有要實現它爲你的本地類。如果您想自己實現接口,則接口不會過於複雜,並且流行的工具包包括其自己的RelayCommand版本。您可以通過右鍵單擊引用並選擇「管理NuGet包」來將MVVM Lite添加到您的項目中。如果您沒有此選項,請在工具 - >擴展和更新下啓用Nuget。
我一直在尋找一個XAML-MVVM命令的最小端到端實現,但還沒有找到它。
因此,下面#Rico的回答結束了以下作爲一個最小的RelayCommand工作。我在一個大型項目中使用了類似的最小版本。
public class RelayCommand : System.Windows.Input.ICommand {
readonly Action<object> execute;
public RelayCommand(Action<object> execute) {
this.execute = execute;
}
public bool CanExecute(object parameter) {
return true;
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter) {
this.execute(parameter);
}
}
較大RelayCommand類好像在CanExecute
和CanExecuteChanged
提供更多的控制,但你並不需要一個上手 - 你可能不需要它。
要在視圖模型使用它:
class ViewModel : INotifyPropertyChanged {
<< ... snip VM properties and notifications ...>>
public RelayCommand DoSomethingCommand {
get {
return new RelayCommand(param => {
this.DoSomething(param as AType);
Debug.WriteLine("Command Executed");
});
}
}
}
(我們並不需要INotifyPropertyChanged的有關命令,但任何視圖模型通常實現它。)
最後,XAML。 ..
<Grid>
<!-- Set the data context here, for illustration. -->
<Grid.DataContext>
<local:ViewModel/>
</Grid.DataContext>
<!-- A sample control bind to a property -->
<TextBlock
Text="{Binding AProp}"/>
<!-- Bind a command -->
<Button Command="{Binding DoSomethingCommand}" CommandParameter="foo">Change!</Button>
</Grid>
我發現這真的是很好的例子,在 https://code.msdn.microsoft.com/windowsapps/Working-with-ICommand-690ba1d4
<Page.Resources>
<local:MyCommandsCollection x:Key="MyCommands" />
</Page.Resources>
<Button Width="280"
Height="59"
Margin="513,280,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Command="{Binding MyFirstCommand}"
CommandParameter="{Binding Text,
ElementName=myTextBox}"
Content="Execute Command" />
public class MyCommandsCollection
{
public MyCommand MyFirstCommand
{
get { return new MyCommand(); }
}
}
public class MyCommand : ICommand
{
public bool CanExecute(object parameter)
{
return true;
}
public event EventHandler CanExecuteChanged;
public async void Execute(object parameter)
{
MessageDialog message = new MessageDialog(
"The command is executing, the value of the TextBox is " + parameter as String);
await message.ShowAsync();
}
}
我用x:Bind試了一下,它工作的很好。我需要的只是公開ViewModel中的一個屬性,它返回一個「MyCommand」類的新實例,這很好。
由於我在我的XAML中設置了DataContext,因此我不需要混淆任何「MyCommandCollection」的東西。耶編譯綁定。
- 1. C++ 0x的任何實現在那裏?
- 2. 那裏有任何樣本電視數據庫?
- 3. 任何現有的PHP代碼在那裏爲condorcet比較?
- 4. 任何AppWidgetHost-教程在那裏?
- 5. 任何PHP - > jQuery庫在那裏?
- 6. 如何在WinRT中實現UserControl
- 7. 如何在winRT中實現AddressFamily
- 8. 的Oracle SQL選擇在那裏同樣
- 9. 如何讓div出現在那裏
- 10. 那裏有任何入門套件/開源支持中心實現?
- 11. UPDATE語法錯誤在那裏同樣
- 12. 那裏有任何錦標賽API嗎?
- 13. 那裏有任何檢索系統嗎?
- 14. 那裏有任何SVG動畫工具?
- 15. 如何實現像WCF那樣的Asp.net MVC OneWay/FireAndForget調用?
- 16. 任何樣本或任何建議,以實現動畫像Thirteen23「藍光」應用?
- 17. WinRT中的GridSplitter在哪裏?
- 18. WinRT的TcpListener類在哪裏?
- 19. DoJo AMD在那裏有任何真實世界的應用程序?
- 20. 那裏有什麼樣的CSS庫嗎?
- 21. 在winRT中實現CaseInsensitiveComparer功能
- 22. 在WinrT中實現加載圖像
- 23. 任何在Visual Foxpro中編程的人都在那裏?
- 24. 實體框架,並在那裏與像
- 25. 那裏有什麼好的花栗鼠/ cocos2d樣本源?
- 26. PHP:在那裏
- 27. 任何好的表達混合教程在那裏?
- 28. 任何基於Silverlight的Thumbstick控件都在那裏?
- 29. 任何優秀的UML電話篩選問題都在那裏?
- 30. Array.map的實現在哪裏?
你應該接受一個答案 – 2012-08-20 18:25:56
你應該有一定的耐心! – 2012-08-22 02:00:31