Udostępnij za pośrednictwem


Dodawanie polecenia do menu skrótów

Polecenia menu można dodawać do języka specyficznego dla domeny (DSL), aby użytkownicy mogli wykonywać zadania specyficzne dla dsl. Polecenia są wyświetlane w menu kontekstowym (skrót) po kliknięciu diagramu prawym przyciskiem myszy. Polecenie można zdefiniować tak, aby było wyświetlane tylko w menu w określonych okolicznościach. Można na przykład ustawić, że polecenie będzie widoczne tylko wtedy, gdy użytkownik kliknie określone typy elementów lub elementów w określonych stanach.

Podsumowując, kroki są wykonywane w projekcie DslPackage w następujący sposób:

  1. Deklarowanie polecenia w pliku Commands.vsct

  2. Zaktualizuj numer wersji pakietu w Package.tt. Należy to zrobić za każdym razem, gdy zmienisz plik Commands.vsct

  3. Pisanie metod w klasie CommandSet w celu uwidocznić polecenie i zdefiniować, co ma robić polecenie.

Uwaga

Można również zmodyfikować zachowanie niektórych istniejących poleceń, takich jak Cut, Paste, Select All i Print, przesłonięcia metod w pliku CommandSet.cs. Aby uzyskać więcej informacji, zobacz How to: Modify a Standard Menu Command (Instrukcje: modyfikowanie standardowego polecenia menu).

Definiowanie polecenia przy użyciu mef

Program Managed Extension Framework (MEF) udostępnia alternatywną metodę definiowania poleceń menu w menu diagramu. Jego głównym celem jest umożliwienie rozszerzenia praw podmiotu danych przez Ciebie lub przez inne strony. Użytkownicy mogą zainstalować tylko rozszerzenie DSL lub zainstalować zarówno rozszerzenie DSL, jak i rozszerzenia. Jednak mef zmniejsza również pracę definiowania poleceń menu skrótów, po początkowej pracy w celu włączenia mef na DSL.

Użyj metody w tym temacie, jeśli:

  1. Chcesz zdefiniować polecenia menu w menu innych niż menu skrótów kliknij prawym przyciskiem myszy.

  2. Chcesz zdefiniować określone grupowania poleceń w menu.

  3. Nie chcesz umożliwiać innym osobom rozszerzania rozszerzenia DSL przy użyciu własnych poleceń.

  4. Chcesz zdefiniować tylko jedno polecenie.

    W przeciwnym razie rozważ użycie metody MEF do zdefiniowania poleceń. Aby uzyskać więcej informacji, zobacz Rozszerzanie dsL przy użyciu mef.

Deklarowanie polecenia w pliku Commands.Vsct

Polecenia menu są deklarowane w pliku DslPackage\Commands.vsct. Te definicje określają etykiety elementów menu i miejsca ich wyświetlania w menu.

Edytowany plik Commands.vsct importuje definicje z kilku plików h znajdujących się w katalogu Ścieżka instalacji zestawu SDK programu Visual Studio\VisualStudioIntegration\Common\Inc. Zawiera również wartość GeneratedVsct.vsct, która jest generowana na podstawie definicji DSL.

Aby uzyskać więcej informacji na temat plików vsct, zobacz Tabela poleceń programu Visual Studio (. Pliki vsct).

Aby dodać polecenie

  1. W Eksplorator rozwiązań w projekcie DslPackage otwórz plik Commands.vsct.

  2. W elemecie zdefiniuj Commands jeden lub więcej przycisków i grupę. Przycisk to element w menu. Grupa jest sekcją w menu. Aby zdefiniować te elementy, dodaj następujące elementy:

    <!-- Define a group - a section in the menu -->
    <Groups>
      <Group guid="guidCustomMenuCmdSet" id="grpidMyMenuGroup" priority="0x0100">
        <!-- These symbols are defined in GeneratedVSCT.vsct -->
        <Parent guid="guidCmdSet" id="menuidContext" />
      </Group>
    </Groups>
    <!-- Define a button - a menu item - inside the Group -->
    <Buttons>
      <Button guid="guidCustomMenuCmdSet" id="cmdidMyContextMenuCommand"
        priority="0x0100" type="Button">
        <Parent guid="guidCustomMenuCmdSet" id="grpidMyMenuGroup"/>
        <!-- If you do not want to place the command in your own Group,
             use Parent guid="guidCmdSet" id="grpidContextMain".
             These symbols are defined in GeneratedVSCT.vsct -->
        <CommandFlag>DynamicVisibility</CommandFlag>
        <Strings>
          <ButtonText>My Context Menu Command</ButtonText>
        </Strings>
      </Button>
    </Buttons>
    

    Uwaga

    Każdy przycisk lub grupa jest identyfikowany przez identyfikator GUID i liczbę całkowitą. Można utworzyć kilka grup i przycisków przy użyciu tego samego identyfikatora GUID. Muszą jednak mieć różne identyfikatory. Nazwy identyfikatorów GUID i nazwy identyfikatorów są tłumaczone na rzeczywiste identyfikatory GUID i identyfikatory liczbowe w węźle <Symbols> .

  3. Dodaj ograniczenie widoczności dla polecenia, aby było ładowane tylko w kontekście języka specyficznego dla domeny. Aby uzyskać więcej informacji, zobacz VisibilityConstraints, element.

    W tym celu dodaj następujące elementy w elemecie CommandTable po elemecie Commands .

    <VisibilityConstraints>
      <!-- Ensures the command is only loaded for this DSL -->
      <VisibilityItem guid="guidCustomMenuCmdSet" id="cmdidMyContextMenuCommand"
        context="guidEditor"/>
    </VisibilityConstraints>
    
  4. Zdefiniuj nazwy używane dla identyfikatorów GUID i identyfikatorów. W tym celu dodaj Symbols element w elemecie CommandTable po elemecie Commands .

    <Symbols>
      <!-- Substitute a unique GUID for the placeholder: -->
      <GuidSymbol name="guidCustomMenuCmdSet"
        value="{00000000-0000-0000-0000-000000000000}" >
        <IDSymbol name="grpidMyMenuGroup" value="0x01001"/>
        <IDSymbol name="cmdidMyContextMenuCommand" value="0x00001"/>
      </GuidSymbol>
    </Symbols>
    
  5. Zastąp element {000...000} identyfikatorem GUID, który identyfikuje grupy i elementy menu. Aby uzyskać nowy identyfikator GUID, użyj narzędzia Create GUID (Tworzenie identyfikatora GUID ) w menu Narzędzia .

    Uwaga

    Jeśli dodasz więcej grup lub elementów menu, możesz użyć tego samego identyfikatora GUID. Należy jednak użyć nowych wartości dla elementu IDSymbols.

  6. W kodzie skopiowany z tej procedury zastąp każde wystąpienie następujących ciągów własnymi ciągami:

    • grpidMyMenuGroup

    • cmdidMyContextMenuCommand

    • guidCustomMenuCmdSet

    • My Context Menu Command

Aktualizowanie wersji pakietu w Package.tt

Za każdym razem, gdy dodasz lub zmienisz polecenie, zaktualizuj version parametr ProvideMenuResourceAttribute , który jest stosowany do klasy pakietu przed wydaniem nowej wersji języka specyficznego dla domeny.

Ponieważ klasa pakietu jest zdefiniowana w wygenerowanym pliku, zaktualizuj atrybut w pliku szablonu tekstowego, który generuje plik Package.cs.

Aby zaktualizować plik Package.tt

  1. W Eksplorator rozwiązań w projekcie DslPackage w folderze GeneratedCode otwórz plik Package.tt.

  2. ProvideMenuResource Znajdź atrybut .

  3. Zwiększa version parametr atrybutu, który jest drugim parametrem. Jeśli chcesz, możesz jawnie napisać nazwę parametru, aby przypomnieć o jego celu. Na przykład:

    [VSShell::ProvideMenuResource("1000.ctmenu", version: 2 )]

Definiowanie zachowania polecenia

Rozszerzenie DSL ma już pewne polecenia zaimplementowane w klasie częściowej zadeklarowanej w pliku DslPackage\GeneratedCode\CommandSet.cs. Aby dodać nowe polecenia, należy rozszerzyć tę klasę, tworząc nowy plik zawierający częściową deklarację tej samej klasy. Nazwa klasy to zwykle YourDslName>CommandSet.< Warto zacząć od zweryfikowania nazwy klasy i sprawdzenia jej zawartości.

Klasa zestawu poleceń pochodzi z klasy CommandSet.

Rozszerzanie klasy CommandSet

  1. W Eksplorator rozwiązań w projekcie DslPackage otwórz folder GeneratedCode, a następnie wyszukaj CommandSet.tt i otwórz wygenerowany plik CommandSet.cs. Zanotuj przestrzeń nazw i nazwę pierwszej klasy, która jest tam zdefiniowana. Możesz na przykład zobaczyć następujące elementy:

    namespace Company.Language1

    { ... internal partial class Language1CommandSet : ...

  2. W folderze DslPackage utwórz folder o nazwie Kod niestandardowy. W tym folderze utwórz nowy plik klasy o nazwie CommandSet.cs.

  3. W nowym pliku napisz deklarację częściową, która ma taką samą przestrzeń nazw i nazwę jak wygenerowana klasa częściowa. Na przykład:

    namespace Company.Language1 /* Make sure this is correct */

    { internal partial class Language1CommandSet { ...

    Uwaga

    Jeśli użyto szablonu klasy do utworzenia nowego pliku, musisz poprawić zarówno przestrzeń nazw, jak i nazwę klasy.

Kod zestawu poleceń zazwyczaj wymaga zaimportowania następujących przestrzeni nazw:

using System;
using System.Collections.Generic;
using System.ComponentModel.Design;
using System.Linq;
using Microsoft.VisualStudio.Modeling;
using Microsoft.VisualStudio.Modeling.Diagrams;
using Microsoft.VisualStudio.Modeling.Shell;

Dostosuj przestrzeń nazw i nazwę klasy, aby pasowały do tych w wygenerowanych plikach CommandSet.cs:

namespace Company.Language1 /* Make sure this is correct */
{
  // Same class as the generated class.
  internal partial class Language1CommandSet
  {

Należy zdefiniować dwie metody, jedną, aby określić, kiedy polecenie będzie widoczne w menu prawym przyciskiem myszy (kontekst), a drugie do wykonania polecenia. Te metody nie są zastępowane; Zamiast tego należy je zarejestrować na liście poleceń.

Zdefiniuj, kiedy polecenie będzie widoczne

Dla każdego polecenia zdefiniuj metodęOnStatus..., która określa, czy polecenie będzie wyświetlane w menu, i czy będzie ono włączone, czy wyszarzone. Visible Ustaw właściwości MenuCommandi Enabled elementu , jak pokazano w poniższym przykładzie. Ta metoda jest wywoływana w celu utworzenia menu skrótów za każdym razem, gdy użytkownik kliknie diagram prawym przyciskiem myszy, więc musi działać szybko.

W tym przykładzie polecenie jest widoczne tylko wtedy, gdy użytkownik wybrał określony typ kształtu i jest włączony tylko wtedy, gdy co najmniej jeden z wybranych elementów jest w określonym stanie. Przykład jest oparty na szablonie DSL diagramu klas, a KlasyShape i ModelClass są typami zdefiniowanymi w języku DSL:

private void OnStatusMyContextMenuCommand(object sender, EventArgs e)
{
  MenuCommand command = sender as MenuCommand;
  command.Visible = command.Enabled = false;
  foreach (object selectedObject in this.CurrentSelection)
  {
    ClassShape shape = selectedObject as ClassShape;
    if (shape != null)
    {
      // Visibility depends on what is selected.
      command.Visible = true;
      ModelClass element = shape.ModelElement as ModelClass;
      // Enabled depends on state of selection.
      if (element != null && element.Comments.Count == 0)
      {
        command.Enabled = true;
        return; // seen enough
} } } }

Następujące fragmenty są często przydatne w metodach OnStatus:

  • this.CurrentSelection. Kształt, który użytkownik kliknął prawym przyciskiem myszy, jest zawsze zawarty na tej liście. Jeśli użytkownik kliknie pustą część diagramu, diagram jest jedynym członkiem listy.

  • this.IsDiagramSelected() - true jeśli użytkownik kliknął pustą część diagramu.

  • this.IsCurrentDiagramEmpty()

  • this.IsSingleSelection() — użytkownik nie wybrał wielu obiektów

  • this.SingleSelection — kształt lub diagram, który użytkownik kliknął prawym przyciskiem myszy

  • shape.ModelElement as MyLanguageElement - element modelu reprezentowany przez kształt.

W ramach ogólnych wskazówek ustaw Visible właściwość na zależności od wybranej wartości, a właściwość Enabled zależy od stanu wybranych elementów.

Metoda OnStatus nie powinna zmieniać stanu Sklepu.

Zdefiniuj, co robi polecenie

Dla każdego polecenia zdefiniuj metodę, która wykonuje wymaganą OnMenu... akcję, gdy użytkownik kliknie polecenie menu.

Jeśli wprowadzisz zmiany w elementach modelu, musisz to zrobić wewnątrz transakcji. Aby uzyskać więcej informacji, zobacz How to: Modify a Standard Menu Command (Instrukcje: modyfikowanie standardowego polecenia menu).

W tym przykładzie wartości ClassShape, ModelClassi Comment są typami zdefiniowanymi w języku DSL, które pochodzą z szablonu DSL diagramu klas.

private void OnMenuMyContextMenuCommand(object sender, EventArgs e)
{
  MenuCommand command = sender as MenuCommand;
  Store store = this.CurrentDocData.Store;
  // Changes to elements and shapes must be performed in a Transaction.
  using (Transaction transaction =
       store.TransactionManager.BeginTransaction("My command"))
  {
    foreach (object selectedObject in this.CurrentSelection)
    {
      // ClassShape is defined in my DSL.
      ClassShape shape = selectedObject as ClassShape;
      if (shape != null)
      {
        // ModelClass is defined in my DSL.
        ModelClass element = shape.ModelElement as ModelClass;
        if (element != null)
        {
          // Do required action here - for example:

          // Create a new element. Comment is defined in my DSL.
          Comment newComment = new Comment(element.Partition);
          // Every element must be the target of an embedding link.
          element.ModelRoot.Comments.Add(newComment);
          // Set properties of new element.
          newComment.Text = "This is a comment";
          // Create a reference link to existing object.
          element.Comments.Add(newComment);
        }
      }
    }
    transaction.Commit(); // Don't forget this!
  }
}

Aby uzyskać więcej informacji na temat przechodzenia z obiektu do obiektu w modelu oraz o sposobie tworzenia obiektów i linków, zobacz How to: Modify a Standard Menu Command (Instrukcje: modyfikowanie standardowego polecenia menu).

Rejestrowanie polecenia

Powtórz w języku C# deklaracje wartości identyfikatora GUID i identyfikatora wprowadzone w sekcji Symbole w pliku CommandSet.vsct:

private Guid guidCustomMenuCmdSet =
    new Guid("00000000-0000-0000-0000-000000000000");
private const int grpidMyMenuGroup = 0x01001;
private const int cmdidMyContextMenuCommand = 1;

Użyj tej samej wartości identyfikatora GUID, która została wstawiona w pliku Commands.vsct.

Uwaga

Jeśli zmienisz sekcję Symbole pliku VSCT, musisz również zmienić te deklaracje tak, aby były zgodne. Należy również zwiększać numer wersji w Package.tt

Zarejestruj polecenia menu w ramach tego zestawu poleceń. GetMenuCommands() jest wywoływany raz po zainicjowaniu diagramu:

protected override IList<MenuCommand> GetMenuCommands()
{
  // Get the list of generated commands.
  IList<MenuCommand> commands = base.GetMenuCommands();
  // Add a custom command:
  DynamicStatusMenuCommand myContextMenuCommand =
    new DynamicStatusMenuCommand(
      new EventHandler(OnStatusMyContextMenuCommand),
      new EventHandler(OnMenuMyContextMenuCommand),
      new CommandID(guidCustomMenuCmdSet, cmdidMyContextMenuCommand));
  commands.Add(myContextMenuCommand);
  // Add more commands here.
  return commands;
}

Testowanie polecenia

Skompiluj i uruchom rozszerzenie DSL w eksperymentalnym wystąpieniu programu Visual Studio. Polecenie powinno pojawić się w menu skrótów w określonych sytuacjach.

Aby wykonać polecenie

  1. Na pasku narzędzi Eksplorator rozwiązań kliknij pozycję Przekształć wszystkie szablony.

  2. Naciśnij klawisz F5 , aby ponownie skompilować rozwiązanie i rozpocząć debugowanie języka specyficznego dla domeny w kompilacji eksperymentalnej.

  3. W kompilacji eksperymentalnej otwórz przykładowy diagram.

  4. Kliknij prawym przyciskiem myszy różne elementy na diagramie, aby sprawdzić, czy polecenie jest poprawnie włączone lub wyłączone, i odpowiednio wyświetlane lub ukryte, w zależności od wybranego elementu.

Rozwiązywanie problemów

Polecenie nie jest wyświetlane w menu:

  • Polecenie będzie wyświetlane tylko w wystąpieniach debugowania programu Visual Studio, dopóki nie zainstalujesz pakietu DSL. Aby uzyskać więcej informacji, zobacz Wdrażanie rozwiązań językowych specyficznych dla domeny.

  • Upewnij się, że w próbce eksperymentalnej jest używane poprawne rozszerzenie nazwy pliku dla tego rozszerzenia DSL. Aby sprawdzić rozszerzenie nazwy pliku, otwórz plik DslDefinition.dsl w głównym wystąpieniu programu Visual Studio. Następnie w Eksploratorze DSL kliknij prawym przyciskiem myszy węzeł Edytor, a następnie kliknij polecenie Właściwości. W okno Właściwości sprawdź właściwość FileExtension.

  • Czy zwiększono numer wersji pakietu?

  • Ustaw punkt przerwania na początku metody OnStatus. Powinien zostać przerwany po kliknięciu prawym przyciskiem myszy dowolnej części diagramu.

Metoda OnStatus nie jest wywoływana:

  • Upewnij się, że identyfikatory GUID i identyfikatory w kodzie CommandSet są zgodne z identyfikatorami w sekcji Symbole w pliku Commands.vsct.

  • W pliku Commands.vsct upewnij się, że identyfikator GUID i identyfikator w każdym węźle nadrzędnym identyfikują prawidłową grupę nadrzędną.

  • W wierszu polecenia programu Visual Studio wpisz devenv /rootsuffix exp /setup. Następnie uruchom ponownie wystąpienie debugowania programu Visual Studio.

  • Wykonaj kroki metody OnStatus, aby sprawdzić to polecenie. Widoczne i polecenie. Włączone są ustawione na wartość true.

Zostanie wyświetlony nieprawidłowy tekst menu lub polecenie pojawi się w niewłaściwym miejscu:

  • Upewnij się, że kombinacja identyfikatora GUID i identyfikatora jest unikatowa dla tego polecenia.

  • Upewnij się, że zostały odinstalowane wcześniejsze wersje pakietu.

Uwaga

Składnik Przekształcanie szablonu tekstu jest automatycznie instalowany w ramach obciążenia programistycznego rozszerzenia programu Visual Studio. Można go również zainstalować na karcie Poszczególne składniki Instalator programu Visual Studio w kategorii Zestawy SDK, biblioteki i struktury. Zainstaluj składnik Zestawu SDK modelowania na karcie Poszczególne składniki.