Resumiendo comandos en el Modelo de Vista es una práctica valiosa con proyectos XAML/MVVM. Lo entiendo. Y, veo ICommand en WinRT; pero, ¿cómo lo implementamos? No he encontrado una muestra que realmente funcione. ¿Nadie sabe?¿Alguna implementación de WinRT iCommand/CommandBinding por ahí?
Respuesta
Mi favorito de todos los tiempos tiene que ser el DelegateCommand proporcionado por el equipo de PnP. Se le permite crear un comando escrito:
MyCommand = new DelegateCommand<MyEntity>(OnExecute);
...
private void OnExecute(MyEntity entity)
{...}
También permite que proporciona una manera de provocar el evento CanExecuteChanged (para activar/desactivar el comando)
MyCommand.RaiseCanExecuteChanged();
Aquí está el código:
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
}
No me gusta la parte genérica (por defecto) pero me gusta la muestra! –
@ JerryNixon-MSFT: ¿por qué no "[no] me gusta la parte genérica"? Si desea evitar el genérico, deberá complicar el código tomando la Acción
@Shawn Kendrot - en ICommand. CanExecute, podrías reemplazar ese potencialmente costoso try ... catch block, ¿no podrías hacer 'return CanExecute (parámetro como T)', luego en 'CanExecute', agregar una verificación para' parameter == null'? –
Consulte RelayCommand clase (solo código METRO). La clase NotifyPropertyChanged
se puede encontrar here. La clase NotifyPropertyChanged
solo se usa para permitir enlaces en CanExecute
y la actualiza con RaiseCanExecuteChanged
.
La clase original mando del relé se puede encontrar here
Por desgracia, no parece ser una clase nativa que lo implementa para usted. La interfaz no es demasiado complicada si quiere implementarla usted mismo, y el popular MVVM Lite toolkit incluye su propia versión de RelayCommand. Puede agregar MVVM Lite a su proyecto haciendo clic derecho en Referencias y seleccionando "Administrar paquetes NuGet". Si no tiene esta opción, habilite Nuget en Herramientas -> Extensiones y actualizaciones.
He estado buscando una implementación end-to-end mínima de un comando XAML-MVVM, y todavía no lo he encontrado.
Entonces, siguiendo la respuesta de # Rico terminé con lo siguiente como un RelayCommand mínimo que funciona. Utilizo una versión mínima similar en un proyecto grande.
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);
}
}
La clase más grande RelayCommand parece proporcionar un mayor control sobre CanExecute
y CanExecuteChanged
, pero no es necesario que para empezar - y puede que no lo necesita en absoluto.
para usarlo en un modelo de vista:
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");
});
}
}
}
(No necesitamos la INotifyPropertyChanged para el comando, pero cualquier modelo de vista normalmente implementa.)
Por último, el 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>
yo encontramos este muy buen ejemplo en 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();
}
}
Probé esto con x: Bind y funciona muy bien. Todo lo que necesito es exponer una propiedad en mi ViewModel que devuelva una nueva instancia de la clase "MyCommand" y todo está bien.
Como estoy configurando el DataContext en mi XAML, no tuve que meterme con ninguna de las cosas de "MyCommandCollection". Yay compilado vinculante.
- 1. ¿Hay alguna herramienta de DRYer por ahí?
- 2. ¿Alguna herramienta de animación SVG por ahí?
- 3. ¿Hay una implementación de lista sin duplicados por ahí?
- 4. ¿Alguna buena gema de aplicación de consola Ruby por ahí?
- 5. ¿Hay alguna demostración de Pinax en vivo por ahí?
- 6. ¿Hay alguna buena API de películas/películas por ahí?
- 7. ¿Hay alguna herramienta virtualenv como C++ por ahí?
- 8. ¿Hay un asesino de NHibernate por ahí?
- 9. ¿Alguna buena guía de publicación/suscripción de WCF tutoriales por ahí?
- 10. ¿Hay un JSF Webhost gratis por ahí?
- 11. ¿alguien por ahí usando Chicago Boss?
- 12. ¿Hay una plantilla jQueryUI LessCss por ahí?
- 13. ¿Hay buenas bibliotecas de control WPF por ahí?
- 14. ¿Qué tipo de trabajos de inteligencia artificial hay por ahí?
- 15. alguna excepción cuando el acceso al archivo en WinRT
- 16. ¿Por qué los tipos WinRT deben sellarse?
- 17. ¿Hay una buena biblioteca interactiva de gráficos 3D por ahí?
- 18. ¿Alguna buena implementación de los atajos de teclado estilo Fogbugz?
- 19. WCF Peer to Peer, ¿Hay nodos por ahí?
- 20. UIScrollView. ¿Alguna idea sobre la implementación de desplazamiento/zoom "infinito"?
- 21. ¿Alguna buena implementación de Zend Framework + Minify?
- 22. ¿Existe una buena aplicación/tarea/sistema para desarrolladores por ahí?
- 23. Cualquier .NET Fluent Argument revisando bibliotecas por ahí?
- 24. ¿Hay alguien programando en Visual FoxPro por ahí?
- 25. WinRT Documentación de tipos proyectados
- 26. ¿Hay alguna implementación LRU de IDictionary?
- 27. JDBC DAO - ¿Alguna buena implementación de referencia?
- 28. ¿Alguna buena implementación de Qt + Lisp?
- 29. WinRT Reemplazo de System.Environment.TickCount
- 30. STAThread falta, pero está ahí
usted debe aceptar una respuesta –
usted debe crecer algo de paciencia! –