2009-03-02 11 views
41

Ich habe eine Anwendung, die Menü und Untermenüs enthält. Ich habe Applocation-Befehle an einige der Untermenü-Optionen wie Ausschneiden, Kopieren und Einfügen angehängt.
Ich habe auch einige andere Menüpunkte, die keine Anwendungsbefehle haben.
Wie kann ich eine benutzerdefinierte Befehlsbindung zu diesen Untermenüpunkten hinzufügen?
Ich bin durch this Artikel gegangen, aber ich konnte kein Ereignis an meine Untermenüpunkte anhängen.Wie füge ich einen benutzerdefinierten weitergeleiteten Befehl in WPF hinzu?

+0

Dieser Youtube-Link gefunden. http://www.youtube.com/watch?v=mG4l0AaYBTM –

Antwort

86

Ich benutze eine statische Klasse, die ich nach der Window1 Klasse platzieren (oder was auch immer die Fensterklasse genannt werden passiert), wo ich Instanzen der RoutedUICommand Klasse erstellen:

public static class Command { 

    public static readonly RoutedUICommand DoSomething = new RoutedUICommand("Do something", "DoSomething", typeof(Window1)); 
    public static readonly RoutedUICommand SomeOtherAction = new RoutedUICommand("Some other action", "SomeOtherAction", typeof(Window1)); 
    public static readonly RoutedUICommand MoreDeeds = new RoutedUICommand("More deeds", "MoreDeeeds", typeof(Window1)); 

} 

einen Namespace in dem Fenster Markup hinzufügen den Namensraum, mit, dass die Window1 Klasse ist in:

xmlns:w="clr-namespace:NameSpaceOfTheApplication" 

Jetzt habe ich Bindungen für die Befehle genauso wie für die Anwendungsbefehle erstellen:

<Window.CommandBindings> 
    <CommandBinding Command="ApplicationCommands.Open" Executed="CommandBinding_Open" /> 
    <CommandBinding Command="ApplicationCommands.Paste" Executed="CommandBinding_Paste" /> 
    <CommandBinding Command="w:Command.DoSomething" Executed="CommandBinding_DoSomething" /> 
    <CommandBinding Command="w:Command.SomeOtherAction" Executed="CommandBinding_SomeOtherAction" /> 
    <CommandBinding Command="w:Command.MoreDeeds" Executed="CommandBinding_MoreDeeds" /> 
</Window.CommandBindings> 

Und die Bindungen in einem Menü verwenden, zB:

<MenuItem Name="Menu_DoSomething" Header="Do Something" Command="w:Command.DoSomething" /> 
+5

Es war der Schlüssel für mich, die _static_ Klasse zu haben, um die RoutedUICommands zu halten. (Wenn sie in meiner Klasse Window1 waren, konnte der XAML sie nicht finden.) Danke! – ewall

+9

Die Wichtigkeit der statischen Klasse kann nicht unterschätzt werden. Frustrierend ignoriert WPF Befehle stillschweigend, wenn sie in einer nicht statischen Klasse definiert sind. –

+3

Warum der Downvote? Wenn Sie nicht erklären, was Sie falsch finden, kann es die Antwort nicht verbessern. – Guffa

61

Statt sich in einer statischen Klasse zu definieren, können Sie auch die Befehle direkt in XAML deklarieren. Beispiel (angepasst von Guffas schönen Beispiel):

<Window.Resources> 
    <RoutedUICommand x:Key="DoSomethingCommand" Text="Do Something" /> 
    <RoutedUICommand x:Key="DoSomethingElseCommand" Text="Do Something Else" /> 
</Window.Resources> 
<Window.CommandBindings> 
    <CommandBinding Command="{StaticResource DoSomethingCommand}" Executed="CommandBinding_DoSomething" /> 
    <CommandBinding Command="{StaticResource DoSomethingElseCommand}" Executed="CommandBinding_DoSomethingElse" /> 
</Window.CommandBindings> 
... 
<MenuItem Name="Menu_DoSomething" Header="Do Something" Command="{StaticResource DoSomethingCommand}" /> 
+1

Verbindet sich irgendetwas davon mit tatsächlichem C# -Code? Wenn das so ist, wie? Welchen Zweck erfüllen die RoutedUICommands? Welche Funktionalität fügen sie hinzu? –

+1

@ EdJ.Plunkett: 1. Ja. 2. Durch die CommandBindings: 'CommandBinding_DoSomething' und' CommandBinding_DoSomethingElse' sind C# -Code. 3./4. Eine allgemeine Diskussion über die Vorteile von RoutedCommands im Vergleich zu regulären Button_Click-Bindungen finden Sie z. B. unter http://joshsmithsonwpf.wordpress.com/2008/03/18/understanding-routed-commands/ (Abschnitt "Who Cares?"). – Heinzi

+0

Danke. Ich habe mich gefragt, was die RoutedUIC-Befehle relativ zu Guffas Beispiel hinzufügen, nicht relativ zur altmodischen onclick-Handhabung (wenn ich Sie verstehe - was ich unbedingt tun würde, würde ich das alles nicht verlangen!), Aber ich werde es tun Suche danach in dem Artikel von Josh Smith. –

15

Ich weiß, dass meine Antwort zu spät ist, aber ich hoffe, dass es für die Zukunft helfen.

Ich mag Guffa und Heinzi Antworten, aber Sie können nur einen Befehl verwenden, um das vorherige Ergebnis zu erzielen. ich in der Regel den Befehl Hilfe verwenden

<Window.CommandBindings> 
     <CommandBinding Command="{StaticResource Help}" Executed="HelpExecuted" /> 
    </Window.CommandBindings> 

und ich verwende CommandParametr bei jedem Aufruf zB

<Window.InputBindings> 
    <KeyBinding Command="{StaticResource Help}" Key="A" Modifiers="Ctrl" CommandParameter="Case1"/> 
    <KeyBinding Command="{StaticResource Help}" Key="B" Modifiers="Ctrl" CommandParameter="Case2"/> 
    <KeyBinding Command="{StaticResource Help}" Key="C" Modifiers="Ctrl" CommandParameter="Case3"/> 
    <KeyBinding Command="{StaticResource Help}" Key="D" Modifiers="Ctrl" CommandParameter="Case4"/> 
    <MouseBinding Command="{StaticResource Help}" MouseAction="LeftDoubleClick" CommandParameter="Case5" /> 
</Window.InputBindings> 

oder

<Button Command="Help" CommandParameter="Case6" Content="Button"> 
    <Button.InputBindings> 
     <KeyBinding Command="{StaticResource Help}" Gesture="Ctrl+D" CommandParameter="Case7"/> 
    </Button.InputBindings> 
</Button> 

und in der cs-Datei

private void HelpExecuted(object sender, ExecutedRoutedEventArgs e) 
{ 
    string str = e.Parameter as string; 
    switch (str) 
    { 
     case null://F1 Pressed default Help 
       //Code 
      break; 
     case "Case1": 
       //Code 
      break; 
     case "Case2": 
       //Code 
      break; 
     case "Case3": 
       //Code 
      break; 
     case "Case4": 
      break; 
     case "Case5": 
       //Code 
      break; 
     case "Case6": 
       //Code 
      break; 
     case "Case7": 
       //Code 
      break; 
    } 
    e.Handled = true; 
} 

und ob Verwenden Sie das MVVM-Muster

private void HelpExecuted(object sender, ExecutedRoutedEventArgs e) 
{ 
    string str = e.Parameter as string; 
    Mvvm_Variable.Action(Input: str); 
    e.Handled = true; 
} 

und verschieben Sie den Schalter zur ViewModule-Site. und Aktion ist eine Methode in derselben ViewModule-Klasse.

+1

Nur das Ticket! Die Verwendung des Eigenschaftenwerts eines Befehls hat mir so viele neue Möglichkeiten eröffnet :-) Ich habe nur ApplicationCommands.NotACommand mit den Eigenschaften MinimizeWindow, MaximizeWindow und RestoreDownWindow verwendet. – Heliac

+0

Ich mag das (alles um die Kesselplatte zu reduzieren!), Aber es ist bemerkenswert es hat eine Einschränkung - Text, der zum Beispiel in Menüeinträge enthalten wäre, wird pro Befehl definiert. Wenn Sie also Menüs benötigen (oder später hinzufügen), ist diese Methode möglicherweise nicht die beste (ich breche häufig Schaltflächenbeschriftungen an) der Befehlstext auch). –

+0

@Bob, Es ist eine einfache switch-Anweisung, die Beschränkung ist per Formular, die Sie alle Tastenkombination verwenden, die die Zeichenfolge des Befehlsparameters widerspiegelt. In diesem Fall hilft Ihnen auch der geroutete Befehl nicht. –

Verwandte Themen