2012-10-11 79 views
5

En mi aplicación WPF tengo una especie de gráfico de nodos. He agregado un ContextMenu a estos nodos, que aparece cuando hago clic derecho en cosas, etc.Retraso RaiseCanExecuteChanged con ContextMenu

Los comandos en el menú contextual provienen de un Servicio (Microsoft.Practices.ServiceLocation.ServiceLocator) con DelegateCommands, y esos comandos se actualizan con RaiseCanExecuteChanged(). El nodo al que se hizo clic derecho se pasa a este servicio de comando, que se usa en los diversos métodos CanExecute para los comandos.

Los nodos todos tienen algunas propiedades que se utilizan en estas condiciones, como si puede ser renombrado o eliminado, etc.

private void ContextMenu_ContextMenuOpening(object sender, RoutedEventArgs e) { 
     ServiceLocator.Current.GetInstance<IMenuCommandService>().ReloadICommandConditions(); 
    } 

en IMenuCommandService:

public void ReloadICommandConditions() { 
     ((DelegateCommand<Node>) MyCommand).RaiseCanExecuteChanged(); 
    } 

Mi ContextMenu (dentro de una DataTrigger & Setter):

<ContextMenu> 
    <MenuItem Header="Rename" 
       Command="{Binding MenuCommandService.Rename}" 
       CommandParameter="{Binding Node}" /> 
    <MenuItem Header="Delete" 
       Command="{Binding MenuCommandService.Delete}" 
       CommandParameter="{Binding Node}" /> 
    ... 
</ContextMenu> 

Mi problema es que cuando hago clic con el botón derecho en uno de estos nodos, el menú contextual que se muestra parece estar configurado para el nodo anterior seleccionado. Al igual que si hago clic con el botón derecho en un nodo eliminable y luego en un nodo no eliminable, aún se podrá hacer clic en el comando "Eliminar" en el menú contextual. (Si hago clic con el botón derecho en el nodo no borrable, el menú contextual será correcto y el comando "Eliminar" aparecerá atenuado)

Parece que hay algún tipo de retraso desde que se hicieron los cambios después RaiseCanExecuteChanged() está realmente allí para que el menú contextual "recoja". Podría hacer un arreglo crudo y solo mostrar el menú contextual después de haber sido actualizado (es decir, se han llamado a sus métodos CanExecute), pero me gustaría mantener las dos partes relativamente separadas.

¿Hay algo obvio que me falta, estoy haciendo esto de la manera incorrecta, o alguien tiene alguna otra sugerencia?

Gracias

+0

¿Ha depurado hasta el CanExecute() de cualquiera de sus comandos y verificado las condiciones allí? No creo que esto sea un problema de retraso, pero serán los valores de condición que verifique en su CanExecute como, por ejemplo, elNodo Seleccionado actual o algo así. ¿Quizás su SelectedNode sigue siendo el anterior cuando llama a ContextMenuOpening? – KroaX

+0

@Kroax El parámetro de los métodos CanExecute() es provisto por ContextMenu: ''. Este parámetro se proporciona correctamente cuando se hace clic en los elementos reales en el menú contextual, pero no cuando se abre por primera vez. – Pyritie

Respuesta

0

clase-de-solucionado - Ahora estoy pasando manualmente el nodo que se hace clic derecho en mi MenuCommandService a través de ese método ReloadICommandConditions(), y está sosteniendo una referencia local a la misma, que luego utiliza en lugar del parámetro en sus métodos CanExecute(). Crudo, pero al menos funciona.

Voy a mantener esto abierto por ahora en caso de que alguien sepa de una manera que es un poco más ... elegante.