Frage

Wie kann ich Caliburn.Micro bekommen eine Schlüssel Geste zu einer Aktionsmethode auf meinem Ansichtsmodell abzubilden?

Zum Beispiel möchte ich eine Tabbed-Schnittstelle implementieren, und ich möchte, dass meine ShellViewModel eine newtab Methode haben, die der Benutzer sollte durch Drücken von Strg + T auf der Tastatur aufrufen können.

Ich weiß, dass der volle Caliburn Rahmen Unterstützung für Gesten, aber wie kann ich das mit Caliburn.Micro tun? Gibt es vielleicht eine Möglichkeit, um eine Aktion zu einem RoutedCommand zu binden (seit RoutedCommands bereits Eingabegesten unterstützen)? Oder eine andere Art und Weise Geste Unterstützung zu bekommen?

War es hilfreich?

Lösung

Sie können es tun, indem sie von System.Windows.Interactivity.TriggerBase abzuleiten. Hier ist ein Beispiel .

Andere Tipps

I geändert Beispiel Unterstützung für globalen Key-Bindings zu ermöglichen. Sie müssen nur den folowing Code zu Ihrer Ansicht hinzuzufügen:

<i:Interaction.Triggers>
        <common:InputBindingTrigger>
            <common:InputBindingTrigger.InputBinding>
                <KeyBinding Modifiers="Control" Key="D"/>
            </common:InputBindingTrigger.InputBinding>
            <cl:ActionMessage MethodName="DoTheMagic"/>
        </common:InputBindingTrigger>
    </i:Interaction.Triggers>

Und wenn Strg + D ist die Methode gedrückt DoTheMagic exexuted wird. Hier ist der modifizierte InputBindingTrigger Code:

public class InputBindingTrigger : TriggerBase<FrameworkElement>, ICommand
  {
    public static readonly DependencyProperty InputBindingProperty =
      DependencyProperty.Register("InputBinding", typeof (InputBinding)
        , typeof (InputBindingTrigger)
        , new UIPropertyMetadata(null));

    public InputBinding InputBinding
    {
      get { return (InputBinding) GetValue(InputBindingProperty); }
      set { SetValue(InputBindingProperty, value); }
    }

    public event EventHandler CanExecuteChanged = delegate { };

    public bool CanExecute(object parameter)
    {
      // action is anyway blocked by Caliburn at the invoke level
      return true;
    }

    public void Execute(object parameter)
    {
      InvokeActions(parameter);
    }

    protected override void OnAttached()
    {
      if (InputBinding != null)
      {
        InputBinding.Command = this;        
        AssociatedObject.Loaded += delegate {
          var window = GetWindow(AssociatedObject);
          window.InputBindings.Add(InputBinding);
        };
      }
      base.OnAttached();
    }

    private Window GetWindow(FrameworkElement frameworkElement)
    {
      if (frameworkElement is Window)
        return frameworkElement as Window;

      var parent = frameworkElement.Parent as FrameworkElement;      
      Debug.Assert(parent != null);

      return GetWindow(parent);
    }
  }

Caliburn.Micro Aktionen Mechanismus ist oben auf System.Windows.Interactivity gebaut. So können Sie einen benutzerdefinierten Trigger basierend auf TriggerBase erstellen zu tun, was Sie wollen, einschließlich dem globalen Tastaturgesten. Dann schließen Sie einfach die ActionMessage in den Trigger und Viola!

, vererben Caliburn ActionMessage des (der eine Triggeraction) zur Befestigung des abgeleiteten Auslösers zum KeyDown- Ereignisse in XAML und stellen die ActionMessage.MethodName Eigenschaft. Fügen Sie eine Eigenschaft der abgeleiteten Auslöser, welche Tastenkombination, die Sie suchen und überschreiben Sie die Invoke-Methode zum Filter durch diese Tastenkombination, ruft base.Invoke (...), wenn die Schlüssel nicht übereinstimmen.

Wenn Sie Marshal ein Befehl durch den Blick auf die Ansicht Modell Sie die CanExecute aus dem View-Modell steuern können. Ich habe diese Methode in mehreren Caliburn Projekten im Einsatz. Vielleicht nicht so „glatt“ sein, wie mit Interaktivität, aber CanExecute funktioniert.

<UserControl x:Class="MyView"
      ...
      Name="View"
>

  <UserControl.InputBindings>
    <KeyBinding Key="F5" 
                Command="{Binding RefreshCommand, ElementName=View, Mode=OneWay}" />
  </UserControl.InputBindings>

  <Button Command="{Binding Path=RefreshCommand, ElementName=View, Mode=OneWay}"/>

In Ihrer View-Klasse, können Sie den Befehl zum Abspielen Modell Draht, der in der MyView.DataContext Eigenschaft verwiesen wird.

Class MyView

    Public Property RefreshCommand As _
    New RelayCommand(AddressOf Refresh,
                     Function()
                         If ViewModel Is Nothing Then
                             Return False
                         Else
                             Return ViewModel.CanRefresh
                         End If
                     End Function)

    Private Sub Refresh()
        ViewModel.Refresh()
    End Sub

    Private ReadOnly Property ViewModel As MyViewModel
        Get
            Return DirectCast(DataContext, MyViewModel)
        End Get
    End Property

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