2010-09-21 12 views
42

elementos de menú por defecto se convierten en discapacitados cuando su comando no se puede ejecutar (CanExecute = false). ¿Cuál es la forma más fácil de hacer que el elemento del menú sea visible/contraído en función del método CanExecute?WPF: cómo ocultar el elemento de menú si el comando CanExecute es falso? Por

Gracias

para su conveniencia aquí está la solución: obligar a la propiedad de visibilidad a la propiedad IsEnabled utilizando convertidor "Boolean a la visibilidad".

+1

Ohhhh - tan simple! Excelente truco! – sergtk

Respuesta

40

Puede Visibilidad simplemente se unen a IsEnabled (establecido en false en CanExecute == false). Aún necesitaría un IValueConverter para convertir el bool a visible/colapsado.

public class BooleanToCollapsedVisibilityConverter : IValueConverter 
    { 
     #region IValueConverter Members 

     public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
     { 
      //reverse conversion (false=>Visible, true=>collapsed) on any given parameter 
      bool input = (null == parameter) ? (bool)value : !((bool)value); 
      return (input) ? Visibility.Visible : Visibility.Collapsed; 
     } 

     public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
     { 
      throw new NotImplementedException(); 
     } 

     #endregion 
    } 
+1

¡Duh! Por supuesto. Muchas gracias. –

+3

Esto es un poco más esfuerzo de lo necesario solo puede usar un disparador – rjarmstrong

1

No sé si esta es la manera más fácil, pero siempre puede crear una propiedad que devuelva el CanExecute() y luego enlazar la visibilidad de su elemento a esta propiedad, usando un IValueConverter para convertir el booleano a Visibilidad.

+0

Esta respuesta no ayuda mucho, pero le doy +1 para nivelar esos puntos negativos que no entiendo completamente por qué alguien ha dado. Si bien esta respuesta no es demasiado útil, TODAS las cosas que se mencionan en ella son VÁLIDAS y, además, todas las demás respuestas positivas MARCAN las cosas mencionadas. ¡El valor de punto mínimo que esta respuesta merece es cero, no negativos! – quetzalcoatl

+0

Este fue mi primer pensamiento, pero ¿cómo se accede a los parámetros (objeto param) desde dentro de esta nueva propiedad, y pasarlo a CanExecute()? – Matt

43

Gracias por la solución. Para aquellos que quieran XAML explícita que esto podría ayudar:

<Window.Resources> 
     <BooleanToVisibilityConverter x:Key="booleanToVisibilityConverter" /> 
</Window.Resources> 

<ContextMenu x:Key="innerResultsContextMenu"> 
    <MenuItem Header="Open" 
       Command="{x:Static local:Commands.AccountOpened}" 
       CommandParameter="{Binding Path=PlacementTarget.DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}}" 
       CommandTarget="{Binding Path=PlacementTarget, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}}" 
       Visibility="{Binding Path=IsEnabled, RelativeSource={RelativeSource Self}, Mode=OneWay, Converter={StaticResource booleanToVisibilityConverter}}" 
       /> 
</ContextMenu> 

En mi caso, el menú contextual es un recurso, por lo que la unión de la visibilidad debe utilizar la configuración de unión RelativeSource Ser.

Como un lado, para la CommandParameter, éstos también debería pasar el DataContext del tema los cuales se ha hecho clic para abrir el menú contextual. Y para enrutar los enlaces de comando a la ventana principal, deberá configurar CommandTarget en consecuencia también.

+0

Gran respuesta exactamente lo que necesitaba – Gilad

40
<Style.Triggers> 
    <Trigger Property="IsEnabled" Value="False"> 
     <Setter Property="Visibility" Value="Collapsed"/> 
    </Trigger> 
</Style.Triggers> 

CanExecute conmuta la propiedad IsEnabled tan simplemente ver esto y mantener todo en la interfaz de usuario. Crea un estilo separado si quieres reutilizar esto.

+0

Esto es perfecto - funcionó como un amuleto (aunque usé un enlace directo con un bool para convertidor de visibilidad en lugar de un disparador, la idea es la misma) –

+1

+1 ¡Esta es la mejor solución! Y debe tener la marca de verificación verde – GETah

+7

La visibilidad debe establecerse en 'Contraída' ya que, de lo contrario, el elemento del menú oculto aún ocupará espacio. –

Cuestiones relacionadas