Wie binden Sie ein ComboBoxItem die IsEnabled-Eigenschaft, um das Ergebnis eines Befehls ist die CanExecute-Methode

StackOverflow https://stackoverflow.com/questions/2320553

Frage

Ich habe eine benutzerdefinierte SplitButton-Umsetzung in denen enthält eine ComboBox mit mehreren ComboBoxItems gebunden zu Befehlen.Ich kann binden, um die Namen und Text Eigenschaften des Befehls Prima, aber haben keine Möglichkeit, die Bindung des ComboBoxItem s IsEnabled - Eigenschaft, um das Ergebnis der ein-Befehl CanExecute Methode weil es ist eine Methode.Gibt es eine syntax, die ich bewusst bin, der für die Bindung von Methoden oder gibt es einige Tricks, die mir helfen wird, mich zu binden, CanExecute.

Übrigens, ich habe darüber nachgedacht, eine benutzerdefinierte ValueConverter außer, dass ich erkannte, dass ich würde wahrscheinlich nicht erhalten keine updates, wenn CanExecute wird neu bewertet, da es nicht eine Eigenschaft und da meine Befehle sind nicht mit business-Objekten.Sie blickt zu mir, dass ich möglicherweise erstellen Sie ein ViewModel für einen Befehl an dieser Stelle die Verwendung nur in meiner benutzerdefinierten SplitButton-Steuerelement, aber das scheint ein wenig über Bord zu mir.

War es hilfreich?

Lösung 2

Eine andere Lösung, die von ViewModel.Unten ist, wie ich ein ViewModel um mein problem zu lösen.Und bitte beachten Sie, dass die nette NotifyPropertyChanged-Methode gehört zu meinen Basis-ViewModel-Klasse.

public class RoutedUICommandViewModel : ViewModel
{
    private RoutedUICommand _command;
    private IInputElement _target;

    public string Name { get { return _command.Name; } }

    public string Text { get { return _command.Text; } }

    public bool CanExecute
    {
        get
        {
            return _command.CanExecute(null, _target);
        }
    }

    public RoutedUICommand Command { get { return _command; } }

    public RoutedUICommandViewModel(ReportCommand command, IInputElement target)
    {
        _command = command;
        _target = target;
        _command.CanExecuteChanged += _command_CanExecuteChanged;
    }

    private void _command_CanExecuteChanged(object sender, EventArgs e)
    {
        base.NotifyPropertyChanged(() => this.CanExecute);
    }
}

Andere Tipps

Sie können eine Taste(wenn Sie nicht haben eine in der controltemplate gebunden an die ICommand) innerhalb ItemContainerStyle(ComboBoxItem Stil) und Binden den Befehl Und fügen Sie einen Trigger, um überprüfen Sie die-Taste.IsEnabled, und dann den Wert für das ComboBoxItem.Also hier haben wir-Button CommandSource nur, um die IsEnabled-Eigenschaft der Wert von CanExeute.Sie können die Schaltfläche Höhe und Breite auf null

 <ControlTemplate....>
   <Grid ...
       <Button x:Name="dummyButton" Command="{Binding YourCommand}" ....
           ......
   </Grid>

   <ControlTemplate.Triggers>
      <Trigger SourceName="dummyButton" Property="IsEnabled" Value="False">
        <Setter Property="IsEnabled" Value="False"/>
      </Trigger>
   </ControlTemplate.Triggers>

Ich fand diese Diskussion auf der MSDN-Foren, in denen Dr.WPF hatte empfohlen, die Verwendung von eine befestigt Verhalten lösen genau dieses problem.Er gab das Beispiel, wie es verwendet werden würde.

<Grid behaviors:CommandBehaviors.EnablingCommand="{x:Static commands:testcommand.test}">  
  . . .  
</Grid> 

Obwohl diese Lösung scheint ziemlich nett, ich habe nicht in der Lage zu widmen, die Zeit zu verstehen, wie genau diese Art von Verhalten umgesetzt würde und was beteiligt ist.Wenn jemand möchte, aufwendige, bitte tun, sonst werde ich ändern, das Antwort mit mehr details, wenn ich die chance bekommen, um zu erkunden dieser option.

Die Art, wie ich dieses problem in meinem code war, um einen Ereignishandler hinzufügen, der auf die ComboBox für das PreviewMouseDown-Ereignis.Hier ist der handler:

private void comboBox_PreviewMouseDown(object sender, MouseButtonEventArgs e)
        {
            ViewModel vm = this.DataContext as ViewModel;

            if (vm != null)
            {
                if (!vm.CanChangeSelection())
                {
                    e.Handled = true;
                    vm.RespondToFailedAttemptChangeUnits();
                }
            }
        }

Dies funktioniert gut für mich in dem Fall, dass ich nur das tun müssen, an einem Ort.Es könnte ein wenig tedius, wenn ich hatte viele Seiten wie diese.

Auch, wenn ich Folgen Sie dem MVVM-Muster, ich bin kein purist - halte ich für eine gute praktische Lösung, folgt der Geist von MVVM, wenn nicht der Brief.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top