Hinzufügen eines Kontextmenüs in einem Toolfenster

In dieser exemplarischen Vorgehensweise wird ein Kontextmenü in ein Toolfenster eingefügt. Ein Kontextmenü ist ein Menü, das angezeigt wird, wenn ein Benutzer mit der rechten Maustaste auf eine Schaltfläche, ein Textfeld oder einen Fensterhintergrund klickt. Befehle in einem Kontextmenü verhalten sich genauso wie Befehle in anderen Menüs oder Symbolleisten. Um ein Kontextmenü zu unterstützen, geben Sie es in der VSCT-Datei an, und zeigen Sie es als Reaktion auf den rechtsklick der Maus an.

Ein Toolfenster besteht aus einem WPF-Benutzersteuerelement in einer benutzerdefinierten Toolfensterklasse, die von ToolWindowPane.

In dieser exemplarischen Vorgehensweise wird gezeigt, wie Sie ein Kontextmenü als Visual Studio-Menü erstellen, indem Sie Menüelemente in der VSCT-Datei deklarieren und dann das Verwaltete Paketframework verwenden, um sie in der Klasse zu implementieren, die das Toolfenster definiert. Dieser Ansatz erleichtert den Zugriff auf Visual Studio-Befehle, UI-Elemente und das Automatisierungsobjektmodell.

Alternativ können Sie die Eigenschaft eines XAML-Elements im Benutzersteuerelement verwenden, wenn das Kontextmenü nicht auf die ContextMenu Visual Studio-Funktionalität zugreift. Weitere Informationen finden Sie unter ContextMenu.

Erstellen des Kontextmenüpakets für das Toolfenster

  1. Erstellen Sie ein VSIX-Projekt mit dem Namen TWShortcutMenu und fügen Sie ihr eine Toolfenstervorlage namens ShortcutMenu hinzu. Weitere Informationen zum Erstellen eines Toolfensters finden Sie unter Erstellen einer Erweiterung mit einem Toolfenster.

Angeben des Kontextmenüs

Ein Kontextmenü, z. B. das in dieser exemplarischen Vorgehensweise gezeigte, ermöglicht es dem Benutzer, aus einer Liste der Farben auszuwählen, die zum Ausfüllen des Hintergrunds des Toolfensters verwendet werden.

  1. Suchen Sie in ShortcutMenuPackage.vsct im GuidSymbol-Element mit dem Namen "guidShortcutMenuPackageCmdSet", und deklarieren Sie das Kontextmenü, die Kontextmenügruppe und die Menüoptionen. Das GuidSymbol-Element sollte nun wie folgt aussehen:

    <GuidSymbol name="guidShortcutMenuPackageCmdSet" value="{00000000-0000-0000-0000-0000}"> // your GUID here
        <IDSymbol name="ShortcutMenuCommandId" value="0x0100" />
        <IDSymbol name="ColorMenu" value="0x1000"/>
        <IDSymbol name="ColorGroup" value="0x1100"/>
        <IDSymbol name="cmdidRed" value="0x102"/>
        <IDSymbol name="cmdidYellow" value="0x103"/>
        <IDSymbol name="cmdidBlue" value="0x104"/>
    </GuidSymbol>
    
  2. Erstellen Sie direkt vor dem Buttons-Element ein Menüelement, und definieren Sie dann das Kontextmenü darin.

    <Menus>
      <Menu guid="guidShortcutMenuPackageCmdSet" id="ColorMenu" type="Context">
        <Strings>
          <ButtonText>Color change</ButtonText>
          <CommandName>ColorChange</CommandName>
        </Strings>
      </Menu>
    </Menus>
    

    Ein Kontextmenü verfügt nicht über ein übergeordnetes Element, da es nicht Teil eines Menüs oder einer Symbolleiste ist.

  3. Erstellen Sie ein Groups-Element mit einem Group-Element, das die Kontextmenüelemente enthält, und ordnen Sie die Gruppe dem Kontextmenü zu.

    <Groups>
        <Group guid="guidShortcutMenuPackageCmdSet" id="ColorGroup">
            <Parent guid="guidShortcutMenuPackageCmdSet" id="ColorMenu"/>
        </Group>
    </Groups>
    
  4. Definieren Sie im Buttons-Element die einzelnen Befehle, die im Kontextmenü angezeigt werden. Das Buttons-Element sollte wie folgt aussehen:

    <Buttons>
        <Button guid="guidShortcutMenuPackageCmdSet" id="ShortcutMenuCommandId" priority="0x0100" type="Button">
            <Parent guid="guidSHLMainMenu" id="IDG_VS_WNDO_OTRWNDWS1"/>
            <Icon guid="guidImages" id="bmpPic1" />
            <Strings>
                <ButtonText>ShortcutMenu</ButtonText>
            </Strings>
        </Button>
    
        <Button guid="guidShortcutMenuPackageCmdSet" id="cmdidRed" priority="1" type="Button">
            <Parent guid="guidShortcutMenuPackageCmdSet" id="ColorGroup" />
            <Strings>
                <ButtonText>Red</ButtonText>
            </Strings>
        </Button>
    
        <Button guid="guidShortcutMenuPackageCmdSet" id="cmdidYellow" priority="3" type="Button">
            <Parent guid="guidShortcutMenuPackageCmdSet" id="ColorGroup" />
            <Strings>
                <ButtonText>Yellow</ButtonText>
            </Strings>
        </Button>
    
        <Button guid="guidShortcutMenuPackageCmdSet" id="cmdidBlue" priority="5" type="Button">
            <Parent guid="guidShortcutMenuPackageCmdSet" id="ColorGroup" />
            <Strings>
                <ButtonText>Blue</ButtonText>
            </Strings>
        </Button>
    </Buttons>
    
  5. Fügen Sie in ShortcutMenuCommand.cs die Definitionen für die Befehlssatz-GUID, das Kontextmenü und die Menüelemente hinzu.

    public const string guidShortcutMenuPackageCmdSet = "00000000-0000-0000-0000-00000000"; // your GUID will differ
    public const int ColorMenu = 0x1000;
    public const int cmdidRed = 0x102;
    public const int cmdidYellow = 0x103;
    public const int cmdidBlue = 0x104;
    

    Dies sind die gleichen Befehls-IDs, die im Abschnitt "Symbole" der Datei "ShortcutMenuPackage.vsct " definiert sind. Die Kontextgruppe ist hier nicht enthalten, da sie nur in der VSCT-Datei erforderlich ist.

Implementieren des Kontextmenüs

In diesem Abschnitt werden das Kontextmenü und die zugehörigen Befehle implementiert.

  1. In ShortcutMenu.cs kann das Toolfenster den Menübefehlsdienst abrufen, aber das darin enthaltene Steuerelement kann nicht verwendet werden. Die folgenden Schritte zeigen, wie Sie den Menübefehlsdienst für das Benutzersteuerelement verfügbar machen.

  2. Fügen Sie in ShortcutMenu.cs die folgenden using-Direktiven hinzu:

    using Microsoft.VisualStudio.Shell;
    using System.ComponentModel.Design;
    
  3. Überschreiben Sie die Initialize()-Methode des Toolfensters, um den Menübefehlsdienst abzurufen und das Steuerelement hinzuzufügen, und übergeben Sie den Menübefehlsdienst an den Konstruktor:

    protected override void Initialize()
    {
        var commandService = (OleMenuCommandService)GetService(typeof(IMenuCommandService));
        Content = new ShortcutMenuControl(commandService);
    }
    
  4. Entfernen Sie im Fensterkonstruktor des ShortcutMenu-Tools die Linie, die das Steuerelement hinzufügt. Der Konstruktor sollte nun wie folgt aussehen:

    public ShortcutMenu() : base(null)
    {
        this.Caption = "ShortcutMenu";
        this.BitmapResourceID = 301;
        this.BitmapIndex = 1;
    }
    
  5. Fügen Sie in ShortcutMenuControl.xaml.cs ein privates Feld für den Menübefehlsdienst hinzu, und ändern Sie den Steuerelementkonstruktor, um den Menübefehlsdienst zu übernehmen. Verwenden Sie dann den Menübefehlsdienst, um die Kontextmenübefehle hinzuzufügen. Der ShortcutMenuControl-Konstruktor sollte nun wie der folgende Code aussehen. Der Befehlshandler wird später definiert.

    public ShortcutMenuControl(OleMenuCommandService service)
    {
        this.InitializeComponent();
        commandService = service;
    
        if (null !=commandService)
        {
            // Create an alias for the command set guid.
            Guid guid = new Guid(ShortcutMenuCommand.guidShortcutMenuPackageCmdSet);
    
            // Create the command IDs.
            var red = new CommandID(guid, ShortcutMenuCommand.cmdidRed);
            var yellow = new CommandID(guid, ShortcutMenuCommand.cmdidYellow);
            var blue = new CommandID(guid, ShortcutMenuCommand.cmdidBlue);
    
            // Add a command for each command ID.
            commandService.AddCommand(new MenuCommand(ChangeColor, red));
            commandService.AddCommand(new MenuCommand(ChangeColor, yellow));
            commandService.AddCommand(new MenuCommand(ChangeColor, blue));
        }
    }
    
  6. Fügen Sie in ShortcutMenuControl.xaml dem Element der obersten Ebene UserControl ein MouseRightButtonDown Ereignis hinzu. Die XAML-Datei sollte nun wie folgt aussehen:

    <UserControl x:Class="TWShortcutMenu.ShortcutMenuControl"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            Background="{DynamicResource VsBrush.Window}"
            Foreground="{DynamicResource VsBrush.WindowText}"
            mc:Ignorable="d"
            d:DesignHeight="300" d:DesignWidth="300"
            Name="MyToolWindow"
            MouseRightButtonDown="MyToolWindow_MouseRightButtonDown">
        <Grid>
            <StackPanel Orientation="Vertical">
                <TextBlock Margin="10" HorizontalAlignment="Center">ShortcutMenu</TextBlock>
            </StackPanel>
        </Grid>
    </UserControl>
    
  7. Fügen Sie in ShortcutMenuControl.xaml.cs einen Stub für den Ereignishandler hinzu.

    private void MyToolWindow_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
    {
    . . .
    }
    
  8. Fügen Sie der gleichen Datei die folgenden Using-Direktiven hinzu:

    using Microsoft.VisualStudio.Shell;
    using System.ComponentModel.Design;
    using System;
    using System.Windows.Input;
    using System.Windows.Media;
    
  9. Implementieren Sie das MyToolWindowMouseRightButtonDown Ereignis wie folgt.

    private void MyToolWindow_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
    {
        if (null != commandService)
        {
            CommandID menuID = new CommandID(
                new Guid(ShortcutMenuCommand.guidShortcutMenuPackageCmdSet),
                ShortcutMenuCommand.ColorMenu);
            Point p = this.PointToScreen(e.GetPosition(this));
            commandService.ShowContextMenu(menuID, (int)p.X, (int)p.Y);
        }
    }
    

    Dadurch wird ein CommandID Objekt für das Kontextmenü erstellt, die Position des Mausklicks identifiziert und das Kontextmenü an dieser Position mithilfe der ShowContextMenu Methode geöffnet.

  10. Implementieren Sie den Befehlshandler.

    private void ChangeColor(object sender, EventArgs e)
    {
        var mc = sender as MenuCommand;
    
        switch (mc.CommandID.ID)
        {
            case ShortcutMenuCommand.cmdidRed:
                MyToolWindow.Background = Brushes.Red;
                break;
            case ShortcutMenuCommand.cmdidYellow:
                MyToolWindow.Background = Brushes.Yellow;
                break;
            case ShortcutMenuCommand.cmdidBlue:
                MyToolWindow.Background = Brushes.Blue;
                break;
        }
    }
    

    In diesem Fall behandelt nur eine Methode Ereignisse für alle Menüelemente, indem die CommandID Hintergrundfarbe identifiziert und entsprechend festgelegt wird. Wenn die Menüelemente nicht verwandte Befehle enthielten, hätten Sie für jeden Befehl einen separaten Ereignishandler erstellt.

Testen der Toolfensterfeatures

  1. Erstellen Sie das Projekt, und starten Sie das Debugging. Die experimentelle Instanz wird geöffnet.

  2. Klicken Sie in der experimentellen Instanz auf "Ansicht/ Andere Fenster", und klicken Sie dann auf "ShortcutMenu". Auf diese Weise sollte Das Toolfenster angezeigt werden.

  3. Klicken Sie mit der rechten Maustaste im Textkörper des Toolfensters. Ein Kontextmenü mit einer Liste von Farben sollte angezeigt werden.

  4. Klicken Sie im Kontextmenü auf eine Farbe. Die Hintergrundfarbe des Toolfensters sollte in die ausgewählte Farbe geändert werden.