Condividi tramite


Procedura: definire un comando di menu in un diagramma di modellazione

In Visual Studio Ultimate è possibile definire voci di menu aggiuntive che vengono visualizzate quando l'utente fa clic con il pulsante destro del mouse su un diagramma UML. È possibile controllare se il comando di menu viene visualizzato e abilitato quando l'utente fa clic con il pulsante destro del mouse su qualsiasi elemento del diagramma ed è possibile scrivere codice che venga eseguito quando l'utente seleziona la voce di menu. È possibile comprimere queste estensioni in un pacchetto Visual Studio Integration Extension, abbreviato in VSIX (la pagina potrebbe essere in inglese), e distribuirlo ad altri utenti di Visual Studio Ultimate.

Requisiti

Definizione del comando di menu

Per creare un comando di menu per una finestra di progettazione UML, è necessario creare una classe che definisce il comportamento del comando e incorporarla in un progetto VSIX (Visual Studio Integration Extension). Il progetto VSIX funge da contenitore per l'installazione del comando. Esistono due metodi alternativi per definire un comando di menu:

  • Creazione di un comando di menu in un progetto VSIX distinto mediante un modello di progetto. Si tratta del metodo più rapido. Utilizzarlo se non si desidera combinare i comandi di menu con altri tipi di estensione quali estensioni della convalida, elementi della casella degli strumenti personalizzati o gestori movimenti.

  • Creazione di progetti di comando di menu e progetti VSIX distinti. Utilizzare questo metodo se si desidera combinare più tipi di estensione nello stesso progetto VSIX. Ad esempio, se per il comando di menu è previsto che il modello osservi vincoli specifici, è possibile incorporarlo nello stesso progetto VSIX come un metodo di convalida.

Per creare un comando di menu in un progetto VSIX distinto

  1. Nella finestra di dialogo Nuovo progetto, sotto Progetti di modello fare clic su Estensione di comando.

  2. Aprire il file con estensione .cs nel nuovo progetto e modificare la classe CommandExtension per implementare il comando.

    Per ulteriori informazioni, vedere Implementazione del comando di menu.

  3. È possibile aggiungere ulteriori comandi al progetto definendo nuove classi.

  4. Testare il comando di menu premendo F5. Per ulteriori informazioni, vedere Esecuzione del comando di menu.

  5. Installare il comando di menu in un altro computer copiando il file bin\*\*.vsix compilato dal progetto. Per ulteriori informazioni, vedere Installazione del comando di menu.

Per creare un comando di menu distinto in un progetto Libreria di classi (DLL)

  1. Creare un progetto Libreria di classi, in una nuova soluzione Visual Studio o in una soluzione esistente.

    1. Scegliere Nuovo dal menu File, quindi fare clic su Progetto.

    2. In Modelli installati fare clic su Visual C# o su Visual Basic. Nella colonna centrale fare clic su Libreria di classi.

    3. Impostare Soluzione per indicare se si desidera creare una nuova soluzione o aggiungere un componente a una soluzione VSIX già aperta.

    4. Impostare nome e percorso per il progetto, quindi fare clic su OK.

  2. Aggiungere i riferimenti seguenti al progetto.

    Riferimenti

    Operazioni consentite

    System.ComponentModel.Composition

    Definire i componenti utilizzando il framework di estensibilità gestita (MEF, Managed Extensibility Framework) (la pagina potrebbe essere in inglese).

    Microsoft.VisualStudio.Uml.Interfaces

    Leggere e modificare le proprietà degli elementi del modello.

    Microsoft.VisualStudio.ArchitectureTools.Extensibility

    Creare elementi del modello, modificare forme nei diagrammi.

    Microsoft.VisualStudio.Modeling.Sdk.10.0

    Definire i gestori eventi del modello.

    Incapsulare serie di modifiche nel modello. Per ulteriori informazioni, vedere Procedura: collegare aggiornamenti di modelli tramite transazioni.

    Microsoft.VisualStudio.Modeling.Sdk.Diagrams.10.0

    (non sempre necessario)

    Accedere a elementi del diagramma aggiuntivi per i gestori movimenti.

    Microsoft.VisualStudio.ArchitectureTools.Extensibility.Layer

    Richiesto solo per i comandi nei diagrammi livello. Per ulteriori informazioni, vedere Creazione di estensioni per diagrammi livelli.

    Definire comandi in un diagramma livello.

  3. Aggiungere un file di classe al progetto e impostarne il contenuto sul codice seguente.

    Nota

    Cambiare lo spazio dei nomi, il nome della classe e il valore restituito da Text in base alle proprie preferenze.

    using System.ComponentModel.Composition;   
    using System.Linq;
    using Microsoft.VisualStudio.ArchitectureTools.Extensibility.Presentation;
    using Microsoft.VisualStudio.ArchitectureTools.Extensibility.Uml;
    using Microsoft.VisualStudio.Modeling.ExtensionEnablement;
    using Microsoft.VisualStudio.Uml.AuxiliaryConstructs;
    using Microsoft.VisualStudio.Uml.Classes; 
        // ADD other UML namespaces if required
    
    namespace UMLmenu1 // CHANGE
    {
      // DELETE any of these attributes if the command
      // should not appear in some types of diagram.
      [ClassDesignerExtension]
      [ActivityDesignerExtension]
      [ComponentDesignerExtension]
      [SequenceDesignerExtension]
      [UseCaseDesignerExtension]
      // [LayerDesignerExtension] // if you have installed Feature Pack 1
    
      // All menu commands must export ICommandExtension:
      [Export (typeof(ICommandExtension))]
      // CHANGE class name
      public class Menu1 : ICommandExtension
      {
        [Import]
        public IDiagramContext DiagramContext { get; set; }
    
        public void QueryStatus(IMenuCommand command)
        { // Set command.Visible or command.Enabled to false
          // to disable the menu command.
          command.Visible = command.Enabled = true;
        }
    
        public string Text
        {
          get { return "MENU COMMAND LABEL"; }
        }
    
        public void Execute(IMenuCommand command)
        {
          // A selection of starting points:
          IDiagram diagram = this.DiagramContext.CurrentDiagram;
          foreach (IShape<IElement> shape in diagram.GetSelectedShapes<IElement>())
          { IElement element = shape.Element; }
          IModelStore modelStore = diagram.ModelStore;
          IModel model = modelStore.Root;
          foreach (IElement element in modelStore.AllInstances<IClass>()) 
          { }
        }
      }
    }
    

    Per ulteriori informazioni su cosa inserire nei metodi, vedere Implementazione del comando di menu.

È necessario aggiungere il comando di menu a un progetto VSIX, che fungerà da contenitore per l'installazione del comando. Se si desidera, è possibile includere altri componenti nello stesso progetto VSIX.

Per aggiungere un comando di menu distinto a un progetto VSIX

  1. Questa routine non è necessaria se si è creato il comando di menu con un progetto VSIX distinto.

  2. Creare un progetto VSIX, a meno che la soluzione non ne includa già uno.

    1. In Esplora soluzioni fare clic con il pulsante destro del mouse sulla soluzione, scegliere Aggiungi, quindi Nuovo progetto.

    2. In Modelli installati espandere Visual Basic o Visual C#, quindi fare clic su Extensibility. Nella colonna centrale fare clic su Progetto VSIX.

  3. Impostare il progetto VSIX come progetto di avvio della soluzione.

    In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto VSIX e scegliere Imposta come progetto di avvio.

  4. In source.extension.vsixmanifest, sotto Contenuto, aggiungere il progetto Libreria di classi come componente MEF.

    1. Aprire source.extension.vsixmanifest

    2. Fare clic su Aggiungi contenuto.

    3. In Seleziona un tipo di contenuto selezionare Componente MEF.

    4. In Selezionare un'origine fare clic su Progetto e selezionare il nome del progetto Libreria di classi.

  5. Fare clic su Seleziona versioni e selezionare le edizioni di Visual Studio in cui si desidera eseguire l'estensione.

  6. Impostare il nome e i campi descrittivi del progetto VSIX. Salvare il file.

Implementazione del comando di menu

La classe del comando di menu implementa i metodi necessari per ICommandExtension.

string Text { get; }

Restituisce l'etichetta della voce di menu.

void QueryStatus(IMenuCommand command);

Chiamato quando l'utente fa clic con il pulsante destro del mouse nel diagramma.

Questo metodo non deve modificare il modello.

Utilizzare DiagramContext.CurrentDiagram.SelectedShapes per determinare se si desidera che il comando venga visualizzato e abilitato.

Impostare:

  • command.Visible su true se il comando deve essere visualizzato nel menu quando l'utente fa clic con il pulsante destro del mouse nel diagramma

  • command.Enabled su true se l'utente può fare clic sul comando nel menu

  • command.Text per impostare l'etichetta del menu in modo dinamico

void Execute (IMenuCommand command);

Chiamato quando l'utente fa clic sulla voce di menu, se visibile e abilitato.

 

Accesso al modello nel codice

Includendo la dichiarazione seguente nella classe del comando di menu:

[Import] public IDiagramContext DiagramContext { get; set; }

...

La dichiarazione di IDiagramContext consente di scrivere codice nei metodi che sia in grado di accedere al diagramma, alla selezione corrente e al modello:

IDiagram diagram = this.DiagramContext.CurrentDiagram;
foreach (IShape<IElement> shape in diagram.GetSelectedShapes<IElement>())
{ IElement element = shape.Element; ... }
IModelStore modelStore = diagram.ModelStore;
IModel model = modelStore.Root;
foreach (IElement element in modelStore.AllInstances<IUseCase>()) {...}

Spostamento e aggiornamento del modello

Gli elementi del modello UML sono tutti disponibili tramite l'API. Dalla selezione corrente o dalla radice del modello, è possibile accedere a tutti gli altri elementi. Per ulteriori informazioni, vedere Procedura: esplorare il modello UML e Programmazione con l'API UML.

Se si utilizza un diagramma di sequenza, vedere anche Procedura: modificare i diagrammi di sequenza tramite l'API UML.

L'API consente inoltre di modificare le proprietà di elementi, eliminare elementi e relazioni e creare nuovi elementi e relazioni.

Per impostazione predefinita, ogni modifica apportata nel metodo Execute verrà eseguita in una transazione separata. L'utente potrà annullare ogni modifica separatamente. Se si desidera raggruppare le modifiche in una sola transazione, utilizzare un oggetto ILinkedUndoTransaction come descritto in Procedura: collegare aggiornamenti di modelli tramite transazioni.

Utilizzare il thread dell'interfaccia utente per gli aggiornamenti

Talvolta può essere utile apportare aggiornamenti al modello da un thread in background. Se, ad esempio, tramite il comando vengono caricati dati da una risorsa lenta, è possibile eseguire il caricamento in un thread in background, in modo che l'utente possa visualizzare le modifiche mentre sono in corso e annullare l'operazione, se necessario.

È tuttavia necessario tenere presente che l'archivio del modello non è thread-safe. È necessario utilizzare sempre il thread dell'interfaccia utente per eseguire aggiornamenti e, se possibile, impedire all'utente di apportare modifiche mentre è in corso l'operazione in background. Per un esempio, vedere Procedura: aggiornare un modello UML da un thread in background.

Esecuzione del comando di menu

A scopo di test, eseguire il comando in modalità di debug.

Per testare il comando di menu

  1. Premere F5 oppure scegliere Avvia debug dal menu Debug.

    Verrà avviata un'istanza sperimentale di Visual Studio.

    Risoluzione dei problemi. Se non viene avviata una nuova istanza di Visual Studio:

    • Se si dispone di più progetti, verificare che il progetto VSIX sia impostato come progetto di avvio della soluzione.

    • In Esplora soluzioni fare clic con il pulsante destro del mouse sul nome del progetto di avvio o del solo progetto disponibile, quindi scegliere Proprietà. Fare clic sulla scheda Debug nell'editor delle proprietà del progetto. Assicurarsi che la stringa nel campo Avvia programma esterno sia il percorso completo di Visual Studio, in genere:

      C:\Programmi\Microsoft Visual Studio 10.0\Common7\IDE\devenv.exe

  2. Nell'istanza sperimentale di Visual Studio aprire o creare un progetto di modello e un diagramma di modellazione. Utilizzare un diagramma appartenente a uno dei tipi elencati negli attributi della classe del comando di menu.

  3. Fare clic con il pulsante destro del mouse in un punto qualsiasi del diagramma. Il comando dovrebbe venire visualizzato nel menu.

    Risoluzione dei problemi: se il comando non viene visualizzato nel menu, verificare quanto indicato di seguito:

    • Il progetto di comando di menu è elencato come componente MEF nell'elenco Contenuto in source.extensions.manifest nel progetto VSIX.

    • I parametri degli attributi Import ed Export sono validi.

    • Tramite il metodo QueryStatus i campi command.Enabled e Visible non vengono impostati su false.

    • Il tipo di diagramma di modello utilizzato (classi UML, sequenza e così via) viene elencato come uno degli attributi della classe del comando di menu [ClassDesignerExtension], [SequenceDesignerExtension] e così via.

Installazione e disinstallazione di un'estensione

È possibile installare un'estensione di Visual Studio sia nel computer in uso che in altri computer.

Per installare un'estensione

  1. Nel computer trovare il file .vsix compilato dal progetto VSIX.

    1. In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto VSIX, quindi scegliere Apri cartella in Esplora risorse.

    2. Individuare il file bin\*\Progetto.vsix

  2. Copiare il file .vsix nel computer di destinazione in cui si desidera installare l'estensione. Si può trattare del computer in uso o di un altro computer.

    Nel computer di destinazione deve essere presente una delle versioni di Visual Studio specificata in source.extension.vsixmanifest.

  3. Nel computer di destinazione fare doppio clic sul file .vsix.

    Verrà visualizzato Visual Studio Extension Installer e verrà installata l'estensione.

  4. Avviare o riavviare Visual Studio.

Per disinstallare un'estensione

  1. Scegliere Gestione estensioni dal menu Strumenti.

  2. Espandere Estensioni installate.

  3. Selezionare l'estensione, quindi fare clic su Disinstalla.

Raramente, può verificarsi che un'estensione errata non venga caricata creando un rapporto nella finestra di errore. Tale estensione non viene però visualizzata in Gestione estensioni. In tal caso, è possibile rimuovere l'estensione eliminando il file da:

%LocalAppData%\Local\Microsoft\VisualStudio\10.0\Extensions

Esempio

Nell'esempio seguente viene illustrato il codice per un comando di menu che interscambierà i nomi di due elementi in un diagramma classi. Questo codice deve essere incorporato in un progetto Visual Studio Extension e installato come descritto nelle sezioni precedenti.

using System.Collections.Generic; // for IEnumerable
using System.ComponentModel.Composition;
  // for [Import], [Export]
using System.Linq; // for IEnumerable extensions
using Microsoft.VisualStudio.ArchitectureTools.Extensibility.Presentation;
  // for IDiagramContext
using Microsoft.VisualStudio.ArchitectureTools.Extensibility.Uml;
  // for designer extension attributes
using Microsoft.VisualStudio.Modeling.Diagrams;
  // for ShapeElement
using Microsoft.VisualStudio.Modeling.ExtensionEnablement;
  // for IGestureExtension, ICommandExtension, ILinkedUndoContext
using Microsoft.VisualStudio.Uml.Classes;
  // for class diagrams, packages

/// <summary>
/// Extension to swap names of classes in a class diagram.
/// </summary>
namespace SwapClassNames
{
  // Declare the class as an MEF component:
  [Export(typeof(ICommandExtension))]
  [ClassDesignerExtension]
  // Add more ExportMetadata attributes to make
  // the command appear on diagrams of other types.
  public class NameSwapper : ICommandExtension
  {
  // MEF required interfaces:
  [Import]
  public IDiagramContext Context { get; set; }
  [Import]
  public ILinkedUndoContext LinkedUndoContext { get; set; }

  /// <summary>
  /// Swap the names of the currently selected elements.
  /// </summary>
  /// <param name="command"></param>
  public void Execute(IMenuCommand command)
  {
    // Get selected shapes that are IClassifiers -
    // IClasses, IInterfaces, IEnumerators.
    var selectedShapes = Context.CurrentDiagram
     .GetSelectedShapes<IClassifier>();
    if (selectedShapes.Count() < 2) return;

    // Get model elements displayed by shapes.
    IClassifier firstElement = selectedShapes.First().Element;
    IClassifier lastElement = selectedShapes.Last().Element;

    // Do the swap in a transaction so that user
    // cannot undo one change without the other.
    using (ILinkedUndoTransaction transaction =
    LinkedUndoContext.BeginTransaction("Swap names"))
    {
    string firstName = firstElement.Name;
    firstElement.Name = lastElement.Name;
    lastElement.Name = firstName;
    transaction.Commit();
    }
  }

  /// <summary>
  /// Called by Visual Studio to determine whether
  /// menu item should be visible and enabled.
  /// </summary>
  public void QueryStatus(IMenuCommand command)
  { 
    int selectedClassifiers = Context.CurrentDiagram
     .GetSelectedShapes<IClassifier>().Count();
    command.Visible = selectedClassifiers > 0;
    command.Enabled = selectedClassifiers == 2;
  }

  /// <summary>
  /// Name of the menu command.
  /// </summary>
  public string Text
  {
    get { return "Swap Names"; }
  }
  }

}

Vedere anche

Concetti

Estensione di modelli e diagrammi UML

Procedura: definire vincoli di convalida per i modelli UML

Programmazione con l'API UML

Altre risorse

Procedura: definire e installare un'estensione di modellazione

Procedura: definire un gestore di trascinamento della selezione e doppio clic in un diagramma di modellazione

Procedura: definire un elemento personalizzato della Casella degli strumenti di modellazione

Procedura: modificare i diagrammi di sequenza tramite l'API UML

Esempio di comando per allineare le forme in un diagramma UML