2011-08-04 13 views
7

Al usar ICommand s en XAML, WPF usa el método CanExecute para habilitar o deshabilitar los controles asociados con el comando. ¿Pero qué sucede si llamo al Execute desde el código de procedimiento? ¿Debo verificar primero CanExecute para asegurarme de que el comando se puede ejecutar, o debería Execute hacerse cargo de este control por mí?¿Debo verificar el método CanExecute de ICommand antes de llamar a Execute desde el código de procedimiento?

En otras palabras, debería hacer esto:

if (someCommand.CanExecute(parameter, target)) 
    someCommand.Execute(parameter, target); 

O simplemente esto:

someCommand.Execute(parameter, target); 
+0

¿Por qué no hacer esta parte de Execute()? –

Respuesta

6

buen estilo dictaría que usted debe hacer lo primero, comprobar CanExecute primero. Esto impondrá una descomposición adecuada y una coherencia en la implementación. Además, si alguna vez desea utilizar este comando vinculado a un botón, funcionará como se espera.

+1

Contractualmente, esto se siente "más adecuado". También agregaría que si la condición que está comprobando se basa de alguna manera en el estado extrínseco al comando (y, por lo tanto, modificable por otro hilo, etc.), querría bloquear la secuencia CanExecute/Execute. – JerKimball

3

Simplemente debe llamar a Execute y dejar que la implementación del comando maneje la validación. CanExecute se proporciona principalmente para enlaces de estado de UI.

Excepto en el caso de escenarios simples de un solo subproceso, aunque llame a CanExecute primero podría haber fácilmente una condición de carrera por la cual la validez del comando cambia entre las llamadas CanExecute y Execute, haciendo inútil la llamada a CanExecute.

+0

No veo cómo una condición de carrera se comportaría de manera diferente dependiendo de llamar a CanExecute y luego ejecutar frente a llamar a Execute. Esas llamadas se ejecutarán secuencialmente independientemente. Si se refiere a un hilo de fondo, es posible que exista un cambio de contexto en el medio de Execute, ya que hay uno entre CanExecute y Execute. – themaestro

+1

Como acaba de señalar, no necesariamente se ejecutarán de forma secuencial e, incluso si lo son, ¿qué impide que otro hilo cambie los datos subyacentes de los comandos o el estado entre esas dos llamadas secuenciales? Mientras que la implementación del comando conoce el contexto en el que opera y puede sincronizar el acceso a los datos compartidos de forma atómica si es necesario. También es la mejor opción para determinar si el comando es válido en el punto de ejecución. –

+0

Los datos subyacentes del comando pueden cambiar en cualquier punto de la ejecución independientemente de si marca o no dentro de la llamada Execute o la llamada CanExecute. Sin embargo, veo el caso para sincronizar el acceso si es necesario. Sin embargo, yo diría que esto es una minoría de casos, y que si bien es necesario en un nicho propenso a las condiciones de carrera, en el diseño general es mejor utilizar CanExectue estilísticamente. – themaestro

2

Primero debe llamar a CanExecute, no hay nada que diga que las clases que implementan ICommand verifiquen su CanExecute en su método Execute.

Cuestiones relacionadas