2010-09-21 5 views
42

Standardmäßig werden Menüelemente deaktiviert, wenn der Befehl nicht ausgeführt werden kann (CanExecute = false). Was ist der einfachste Weg, den Menüeintrag basierend auf der CanExecute-Methode sichtbar/reduziert zu machen?WPF - wie Menüeintrag zu verbergen, wenn Befehl CanExecute falsch ist?

Dank

für Ihre Bequemlichkeit ist hier die Lösung: mit „Boolean Sichtbarkeit“ Konverter die Sichtbarkeit Eigenschaft auf die IsEnabled Eigenschaft binden.

+1

Ohhhh - so einfach! Ausgezeichneter Trick! – sergtk

Antwort

40

Sie können Visibility einfach an IsEnabled binden (in CanExecute == false auf false setzen). Sie benötigen immer noch einen IValueConverter, um das Bool in sichtbar/reduziert zu konvertieren.

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! Na sicher. Danke vielmals. –

+3

Dies ist ein bisschen mehr Aufwand als notwendig Sie können einfach einen Auslöser verwenden – rjarmstrong

1

Ich weiß nicht, ob dies der einfachste Weg ist, aber man kann immer eine Eigenschaft erstellen, die die CanExecute() zurückkehrt und dann binden Sie die Sichtbarkeit Ihres Elements diese Eigenschaft ein IValueConverter mit dem boolean Sichtbarkeit zu konvertieren.

+0

Diese Antwort hilft nicht viel, aber ich gebe es +1, um diese negativen Punkte zu leveln, die ich völlig nicht verstanden habe, warum jemand gegeben hat. Während diese Antwort nicht zu hilfreich ist, sind alle darin erwähnten Dinge gültig und außerdem verwenden alle anderen positiv markierten Antworten die erwähnten Dinge. Der kleinste Punktwert, den diese Antwort verdient, ist null, keine negativen! – quetzalcoatl

+0

Das war mein erster Gedanke, aber wie würden Sie Zugriff auf den Parameter (object param) innerhalb dieser neuen Eigenschaft erhalten und ihn an CanExecute() übergeben? – Matt

43

Danke für die Lösung. Für diejenigen, expliziten XAML könnte dies helfen:

<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> 

In meinem Fall das Kontextmenü ist eine Ressource, so dass für die Sichtbarkeit der Bindung muss den Relativeselbstbindungsaufbau verwenden.

Als Side für CommandParameter übergeben Sie möglicherweise auch den DataContext des Elements, auf das geklickt wurde, um das Kontextmenü zu öffnen. Um die Befehlsbindungen an das übergeordnete Fenster weiterzuleiten, müssen Sie auch das CommandTarget entsprechend einstellen.

+0

Große Antwort genau das, was ich brauchte – Gilad

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

CanExecute schaltet die IsEnabled Eigenschaft so dass diese nur beobachten und alles in der Benutzeroberfläche zu halten. Erstellen Sie einen separaten Stil, wenn Sie diesen wiederverwenden möchten.

+0

Das ist perfekt - arbeitete wie ein Charme (obwohl ich eine direkte Bindung mit einem Bool zu Sichtbarkeit Konverter anstelle eines Auslösers verwendet, die Idee ist das gleiche) –

+1

+1 Dies ist die beste Lösung! Und sollte das grüne Häkchen haben – GETah

+7

Die Sichtbarkeit sollte auf 'Collapsed' gesetzt werden, da sonst der versteckte Menüpunkt noch Platz einnimmt. –