Porady: definiowanie procedury obsługi gestów na diagramie modelowania
W Visual Studio Ultimate można zdefiniować polecenia, które są wykonywane, gdy użytkownik kliknie dwukrotnie lub przeciąganie elementy na diagram UML.Można spakować te rozszerzenia w Rozszerzeniu Integracji programu Visual Studio (VSIX) i rozdystrybuować je innym użytkownikom programu Visual Studio Ultimate.
Jeśli istnieje już wbudowane zachowanie dla typu diagramu i typu elementu, który chcesz przeciągnąć, możesz nie być w stanie dodać lub zmienić tego zachowania.
Wymagania
Visual Studio SDK, który można otrzymać od Galerii Visual Studio.
Wizualizacja i Modelowanie zestawu SKD Visual Studio, który można uzyskać z Wizualizacja i Modelowanie zestawu SKD programu Visual Studio w Galerii Kodów.
Tworzenie procedury obsługi gestu
Aby zdefiniować program obsługi gestu dla projektanta UML, należy utworzyć klasę, która definiuje zachowanie obsługi gestu i osadzić tę klasę w Visual Studio Integration rozszerzenie (VSIX)VSIX działa jako kontener, który może zainstalować obsługę.Istnieją dwie alternatywne metody definiowania obsługi gestu:
Utwórz procedurę obsługi gestu w jego własnym VSIX przy użyciu szablonu projektu. To jest szybsza metoda.Użyj go, jeśli nie chcesz połączyć programu obsługi z innymi rodzajami rozszerzeń takich jak rozszerzenie sprawdzania poprawności, elementy do przybornika niestandardowego lub polecenia menu.
Utwórz osobną procedurę obsługi gestu i projektów VSIX. Metoda ta jest używana, jeśli chcesz połączyć kilka rodzajów rozszerzeń w samym VSIX.Na przykład, jeśli procedura obsługi gestu oczekuje modelu do przestrzegania szczególnych ograniczeń, można ją osadzić w samym VSIX jako metodę sprawdzania poprawności.
Aby utworzyć obsługę gestu w jego własnym VSIX
W oknie dialogowym Nowy projekt w polu Projekty modelowania, wybierz opcję Rozszerzenie gestu.
Otwórz .cs plik w nowym projekcie i modyfikuj GestureExtension klasę, aby wdrożyć swój plik obsługi gestów.
Aby uzyskać więcej informacji, zobacz Implementacja procedury obsługi gestów.
Przetestuj obsługę gestu naciskając klawisz F5.Aby uzyskać więcej informacji, zobacz Uruchamianie procedury obsługi gestów.
Zainstaluj program obsługi gestu na innym komputerze przez skopiowanie pliku bin\*\*.vsix utworzonego w projekcie.Aby uzyskać więcej informacji, zobacz Procedura obsługi gestów.
W tym miejscu jest alternatywna procedura:
Aby utworzyć projekt osobnej klasy biblioteki (DLL) dla obsługi gestu
Utwórz projekt biblioteki klas w nowym rozwiązaniu Visual Studio lub w istniejącym rozwiązaniu.
W pasku menu wybierz Plik, Nowy, Projekt.
Pod zainstalowane szablony, rozwiń program Visual C# lub język Visual Basic, a następnie w środkowej kolumnie Wybierz Biblioteka klas.
Dodaj następujące odwołania do własnego projektu.
Microsoft.VisualStudio.Modeling.Sdk.12.0
Microsoft.VisualStudio.Modeling.Sdk.Diagrams.12.0
Microsoft.VisualStudio.ArchitectureTools.Extensibility
Microsoft.VisualStudio.Uml.Interfaces
System.ComponentModel.Composition
System.Windows.Forms
Microsoft.VisualStudio.ArchitectureTools.Extensibility.Layer — jest to tylko potrzebne w przypadku rozszerzenia diagramów warstwy.Aby uzyskać więcej informacji, zobacz Rozszerzanie diagramów warstw.
Dodaj plik klasy do projektu i ustawi jego zawartość do następującego kodu.
[!UWAGA]
Zmień przestrzeń nazw i nazwę klasy zgodnie z preferencjami.
using System.ComponentModel.Composition; using System.Linq; using System.Collections.Generic; using Microsoft.VisualStudio.Modeling.Diagrams; using Microsoft.VisualStudio.Modeling.Diagrams.ExtensionEnablement; using Microsoft.VisualStudio.Modeling.ExtensionEnablement; using Microsoft.VisualStudio.ArchitectureTools.Extensibility.Uml; using Microsoft.VisualStudio.ArchitectureTools.Extensibility.Presentation; using Microsoft.VisualStudio.Uml.AuxiliaryConstructs; using Microsoft.VisualStudio.Modeling; using Microsoft.VisualStudio.Uml.Classes; // ADD other UML namespaces if required namespace MyGestureHandler // CHANGE { // DELETE any of these attributes if the handler // should not work with some types of diagram. [ClassDesignerExtension] [ActivityDesignerExtension] [ComponentDesignerExtension] [SequenceDesignerExtension] [UseCaseDesignerExtension] // [LayerDesignerExtension] // Gesture handlers must export IGestureExtension: [Export(typeof(IGestureExtension))] // CHANGE class name public class MyGesture1 : IGestureExtension { [Import] public IDiagramContext DiagramContext { get; set; } /// <summary> /// Called when the user double-clicks on the diagram /// </summary> /// <param name="targetElement"></param> /// <param name="diagramPointEventArgs"></param> public void OnDoubleClick(ShapeElement targetElement, DiagramPointEventArgs diagramPointEventArgs) { // CHANGE THIS CODE FOR YOUR APPLICATION. // Get the target shape, if any. Null if the target is the diagram. IShape targetIShape = targetElement.CreateIShape(); // Do something... } /// <summary> /// Called repeatedly when the user drags from anywhere on the screen. /// Return value should indicate whether a drop here is allowed. /// </summary> /// <param name="targetMergeElement">References the element to be dropped on.</param> /// <param name="diagramDragEventArgs">References the element to be dropped.</param> /// <returns></returns> public bool CanDragDrop(ShapeElement targetMergeElement, DiagramDragEventArgs diagramDragEventArgs) { // CHANGE THIS CODE FOR YOUR APPLICATION. // Get the target element, if any. Null if the target is the diagram. IShape targetIShape = targetMergeElement.CreateIShape(); // This example allows drag of any UML elements. return GetModelElementsFromDragEvent(diagramDragEventArgs).Count() > 0; } /// <summary> /// Execute the action to be performed on the drop. /// </summary> /// <param name="targetDropElement"></param> /// <param name="diagramDragEventArgs"></param> public void OnDragDrop(ShapeElement targetDropElement, DiagramDragEventArgs diagramDragEventArgs) { // CHANGE THIS CODE FOR YOUR APPLICATION. } /// <summary> /// Retrieves UML IElements from drag arguments. /// Works for drags from UML diagrams. /// </summary> private IEnumerable<IElement> GetModelElementsFromDragEvent (DiagramDragEventArgs dragEvent) { //ElementGroupPrototype is the container for //dragged and copied elements and toolbox items. ElementGroupPrototype prototype = dragEvent.Data. GetData(typeof(ElementGroupPrototype)) as ElementGroupPrototype; // Locate the originals in the implementation store. IElementDirectory implementationDirectory = dragEvent.DiagramClientView.Diagram.Store.ElementDirectory; return prototype.ProtoElements.Select( prototypeElement => { ModelElement element = implementationDirectory .FindElement(prototypeElement.ElementId); ShapeElement shapeElement = element as ShapeElement; if (shapeElement != null) { // Dragged from a diagram. return shapeElement.ModelElement as IElement; } else { // Dragged from UML Model Explorer. return element as IElement; } }); } } }
Aby uzyskać więcej informacji o tym, co umieścić w metodach, zobacz Implementowanie obsługi gest.
Musisz dodać swoje polecenie menu do projektu VSIX, który działa jako kontener dla polecenia instalowania.Jeśli chcesz, możesz dodać inne składniki w tym samym VSIX.
Aby dodać obsługę oddzielnych gestów do projektu VSIX
Nie potrzebujesz tej procedury po utworzeniu elementu obsługi gestu z własnej VSIX.
Utwórz projekt VSIX, chyba, że rozwiązanie zawiera już jeden.
W Eksploratorze rozwiązań w menu skrótów rozwiązania wybierz Dodaj, Nowy projekt.
Pod zainstalowane szablony, rozwiń program Visual C# lub program Visual Basic, następnie wybierz rozszerzalności.W środkowej kolumnie wybierz Projekt VSIX.
Ustaw projekt VSIX jako projekt startowy rozwiązania.
- W Eksploratorze rozwiązań, w menu skrótów projektu VSIX, wybierz Ustaw jako projekt startowy.
W source.extension.vsixmanifest dodaj projekt biblioteki klas obsługi gest jako składnik MEF:
W zakładce Metadane ustaw nazwę VSIX.
W zakładce Instaluj obiekty docelowe ustaw program Visual Studio Ultimate i Premium jako obiekty docelowe.
W zakładce Aktywa wybierz polecenie Nowy i w oknie dialogowym ustaw:
Typ = składnik MEF
Źródło = projektu w bieżącym rozwiązaniu
Projekt = Your class library project
Wykonywanie obsługi gestu
Do celów testowych wykonaj procedurę obsługi gestu w trybie debugowania.
Testowanie obsługi gestu
Naciśnij klawisz F5 lub w menu Debugowanie kliknij Rozpocznij debugowanie.
Eksperymentalne wystąpienie Visual Studio rozpoczyna się.
Rozwiązywanie problemów z: Jeśli nowego Visual Studio nie można uruchomić:
Jeśli masz więcej niż jeden projekt, upewnij się, że projekt VSIX jest ustawiony jako projekt startowy rozwiązania.
W Eksploratorze rozwiązań, w menu skrótów uruchamiania lub tylko projektu, wybierz Właściwości.W edytorze właściwości projektu wybierz kartę Debugowanie.Upewnij się, że ciąg w polu Uruchomienie zewnętrznego programu jest pełną nazwą ścieżki Visual Studio, zazwyczaj:
C:\Program Files\Microsoft Visual Studio 12.0\Common7\IDE\devenv.exe
W eksperymentalnym Visual Studio, otwórz lub stwórz projektu modelowania i otworzyć lub utworzyć diagram modelowania.Użyj diagramu, który należy do jednego z typów wymienionych w atrybucie klasy programu obsługi gestu.
Kliknij dwukrotnie dowolne miejsce na diagramie.Program obsługi dwukrotnego kliknięcia powinien zostać wywołany.
Przeciągnij element z Eksploratora UML na diagram.Program obsługi przeciągnięcia powinien zostać wywołany.
Rozwiązywanie problemów z: Jeśli program obsługi gestu nie działa, upewnij się, że:
Projekt obsługi gestu jest wymieniony jako składnik listy MEF zakładki Aktywa w source.extensions.manifest w projekcie VSIX.
Parametry wszystkich Import i Export atrybuty są prawidłowe.
Metoda CanDragDrop nie zwraca false.
Typ diagramu modelu, którego używasz (klasa UML, sekwencja i tak dalej) jest wymieniony jako jeden z atrybutów elementu obsługi gestu klasy polecenia [ClassDesignerExtension], [SequenceDesignerExtension] i tak dalej.
Nie ma żadnych funkcji wbudowanych już zdefiniowanych dla tego typu docelowego i elementu porzuconego.
Wdrażanie obsługi gestu
Metody obsługi gestu
Implementuje klasy obsługi gestu i eksportuje IGestureExtension.metody, które musisz zdefiniować, są następujące:
bool CanDragDrop (ShapeElement target, DiagramDragEventArgs dragEvent) |
Wróć true , aby zezwolić elementowi źródła wymienionemu w dragEvent na przerwanie w tym celu. Ta metoda nie powinna dokonywać zmian w modelu.powinna działać szybko, ponieważ jest używana do określania stanu strzałki gdy użytkownik przesuwa mysz. |
void OnDragDrop (ShapeElement target, DiagramDragEventArgs dragEvent) |
Zaktualizuj model oparty na obiekcie źródłowym, do którego odwołuje się dragEvent, i docelowy. Wywołane, gdy użytkownik zwolni przycisk myszy po przeciągnięciu. |
void OnDoubleClick (ShapeElement target, DiagramPointEventArgs pointEvent) |
target jest kształtem, który zostanie kliknięty dwukrotnie. |
Można napisać procedury obsługi, które mogą również akceptować UML, nie tylko cały szereg innych elementów, takich jak pliki, węzły w widoku klasy .NET, węzły w Eksploratorze architektury i tak dalej.Użytkownik można przeciągnąć te elementy na diagramie UML pod warunkiem, że zapiszesz OnDragDrop metody, która mogą dekodować serializowane postaci elementów.Metody dekodowania rozróżniają jeden rodzaj artykułu od innego.
Parametry tych metod są:
ShapeElement target.Kształt lub diagram, na którym użytkownik przenosi coś.
ShapeElement jest klasą we wdrażaniu, która jest podporządkowana narzędziu do modelowania UML.Aby zmniejszyć ryzyko wprowadzenia modelu UML i diagramów w niespójnym stanie, firma Microsoft zaleca, aby używać metody tej klasy bezpośrednio.Zamiast tego, owiń element w IShape, a następnie użyj metod opisanych w Porady: wyświetlanie modelu na diagramach.
Aby uzyskać IShape:
IShape targetIShape = target.CreateIShape(target);
Aby uzyskać element modelu, który jest określony przez przeciąganie lub operację dwukrotnego kliknięcia:
IElement target = targetIShape.Element;
Można rzutować to do bardziej określonego typu elementu.
Aby uzyskać magazyn modeli UML, który zawiera model UML:
IModelStore modelStore = targetIShape.Element.GetModelStore();
Aby uzyskać dostęp do hosta i usługodawcy:
target.Store.GetService(typeof(EnvDTE.DTE)) as EnvDTE.DTE
DiagramDragEventArgs eventArgs.Ten parametr niesie ze sobą serializowany formularz z obiektem źródłowym operacji przeciągania:
System.Windows.Forms.IDataObject data = eventArgs.Data;
Można przeciągnąć elementy różnego rodzaju na diagramie z różnych części Visual Studio, lub z pulpitu systemu Windows.Różne rodzaje elementu są zakodowane w różny sposób w IDataObject.Aby wyodrębnić elementy z niego, zajrzyj do dokumentacji dla odpowiedniego typu obiektu.
Jeśli obiekt źródłowy jest elementem UML przeciągniętym z Eksploratora modelu UML lub innego diagramu UML, patrz Porady: pozyskiwanie elementów modelu UML z IDataObject.
Pisanie kodu metody
Aby uzyskać więcej informacji na temat pisania kodu do odczytu i aktualizacji modelu, zobacz Programowanie za pomocą API UML.
Aby uzyskać informacje dotyczące uzyskania dostępu do informacji o modelu w operacji przeciągania, zobacz Porady: pozyskiwanie elementów modelu UML z IDataObject.
Jeśli masz do czynienia z diagramem sekwencji, zobacz też Porady: edytowanie diagramów sekwencyjnych przy użyciu API UML.
Oprócz parametrów metody, można również zadeklarować importowane właściwości w swojej klasie, która zapewnia dostęp do bieżącego diagramu i modelu.
[Import] public IDiagramContext DiagramContext { get; set; }
Deklaracja IDiagramContext umożliwia pisanie kodu w Twoich metodach, które uzyskują dostęp do diagramu, bieżącego zaznaczenie i modelu:
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 (IDiagram diagram in modelStore.Diagrams) {...}
foreach (IElement element in modelStore.AllInstances<IUseCase>) {...}
Aby uzyskać więcej informacji, zobacz Porady: nawigowanie po modelu UML.
Instalowanie i odinstalowywanie rozszerzenia
Można zainstalować Visual Studio rozszerzenie zarówno na swoim komputerze jak i na innych komputerach.
Aby zainstalować rozszerzenie
Na komputerze, należy odnaleźć plik .vsix, który został zbudowany przez projekt VSIX.
W Eksploratorze rozwiązań, w menu skrótów projektu VSIX wybierz Otwórz folder w Eksploratorze Windows.
Zlokalizuj plik bin\*\YourProject.vsix
Kopiuj plik .vsix do komputera miejsca docelowego, na którym chcesz zainstalować rozszerzenie.Może to być twój własny komputer, albo inny.
Komputer docelowy musi mieć jedną z wersji systemu Visual Studio określonej w source.extension.vsixmanifest.
Na komputerze docelowym otwórz .vsix pliku.
Instalator rozszerzenia programu Visual Studio otwiera i instaluje rozszerzenia.
Uruchom lub ponownie uruchom Visual Studio.
Aby odinstalować rozszerzenie
W menu Narzędzia wybierz Menedżer rozszerzeń.
Rozwiń Zainstalowane rozszerzenia.
Zaznacz rozszerzenie, a następnie wybierz Odinstaluj.
Rzadko wadliwe rozszerzenie nie ładuje się i tworzy raport w oknie błędów, ale nie pojawia się w Menedżerze rozszerzeń.W takim przypadku należy usunąć rozszerzenie przez usunięcie pliku z:
%LocalAppData%\Local\Microsoft\VisualStudio\12.0\Extensions
Przykład
Poniższy przykład pokazuje sposób tworzenia linii życia w diagramie sekwencji na podstawie części i portów składnika przeciągniętych z diagramu składników.
Aby przetestować go, naciśnij klawisz F5.Otwiera doświadczalne wystąpienie programu Visual Studio.W tym wypadku otwórz model UML i utwórz składnik na diagramie składników.Dodaj do tego składnika niektóre interfejsy i wewnętrzne części zamienne.Wybierz interfejsy i części.Następnie przeciągnij interfejsy i części na diagramie sekwencji. (Przeciągnij z diagramu składników w górę do karty diagramu sekwencji, a następnie w dół do diagramu sekwencji.) Linia życia pojawi się dla poszczególnych interfejsów i części.
Aby uzyskać więcej informacji o wiązaniu interakcji do diagramów sekwencji, zobacz Porady: edytowanie diagramów sekwencyjnych przy użyciu API UML.
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using Microsoft.VisualStudio.Modeling;
using Microsoft.VisualStudio.Modeling.Diagrams;
using Microsoft.VisualStudio.Modeling.Diagrams.ExtensionEnablement;
using Microsoft.VisualStudio.Modeling.ExtensionEnablement;
using Microsoft.VisualStudio.ArchitectureTools.Extensibility.Uml;
using Microsoft.VisualStudio.ArchitectureTools.Extensibility.Presentation;
using Microsoft.VisualStudio.Uml.AuxiliaryConstructs;
using Microsoft.VisualStudio.Uml.Classes;
using Microsoft.VisualStudio.Uml.Interactions;
using Microsoft.VisualStudio.Uml.CompositeStructures;
using Microsoft.VisualStudio.Uml.Components;
/// <summary>
/// Creates lifelines from component ports and parts.
/// </summary>
[Export(typeof(IGestureExtension))]
[SequenceDesignerExtension]
public class CreateLifelinesFromComponentParts : IGestureExtension
{
[Import]
public IDiagramContext Context { get; set; }
/// <summary>
/// Called by the modeling framework when
/// the user drops something on a target.
/// </summary>
/// <param name="target">The target shape or diagram </param>
/// <param name="dragEvent">The item being dragged</param>
public void OnDragDrop(ShapeElement target,
DiagramDragEventArgs dragEvent)
{
ISequenceDiagram diagram = Context.CurrentDiagram
as ISequenceDiagram;
IInteraction interaction = diagram.Interaction;
if (interaction == null)
{
// Sequence diagram is empty: create an interaction.
interaction = diagram.ModelStore.Root.CreateInteraction();
interaction.Name = Context.CurrentDiagram.Name;
diagram.Bind(interaction);
}
foreach (IConnectableElement connectable in
GetConnectablesFromDrag(dragEvent))
{
ILifeline lifeline = interaction.CreateLifeline();
lifeline.Represents = connectable;
lifeline.Name = connectable.Name;
}
}
/// <summary>
/// Called by the modeling framework to determine whether
/// the user can drop something on a target.
/// Must not change anything.
/// </summary>
/// <param name="target">The target shape or diagram</param>
/// <param name="dragEvent">The item being dragged</param>
/// <returns>true if this item can be dropped on this target</returns>
public bool CanDragDrop(ShapeElement target,
DiagramDragEventArgs dragEvent)
{
IEnumerable<IConnectableElement> connectables = GetConnectablesFromDrag(dragEvent);
return connectables.Count() > 0;
}
///<summary>
/// Get dragged parts and ports of an IComponent.
///</summary>
private IEnumerable<IConnectableElement>
GetConnectablesFromDrag(DiagramDragEventArgs dragEvent)
{
foreach (IElement element in
GetModelElementsFromDragEvent(dragEvent))
{
IConnectableElement part = element as IConnectableElement;
if (part != null)
{
yield return part;
}
}
}
/// <summary>
/// Retrieves UML IElements from drag arguments.
/// Works for drags from UML diagrams.
/// </summary>
private IEnumerable<IElement> GetModelElementsFromDragEvent
(DiagramDragEventArgs dragEvent)
{
//ElementGroupPrototype is the container for
//dragged and copied elements and toolbox items.
ElementGroupPrototype prototype =
dragEvent.Data.
GetData(typeof(ElementGroupPrototype))
as ElementGroupPrototype;
// Locate the originals in the implementation store.
IElementDirectory implementationDirectory =
dragEvent.DiagramClientView.Diagram.Store.ElementDirectory;
return prototype.ProtoElements.Select(
prototypeElement =>
{
ModelElement element = implementationDirectory
.FindElement(prototypeElement.ElementId);
ShapeElement shapeElement = element as ShapeElement;
if (shapeElement != null)
{
// Dragged from a diagram.
return shapeElement.ModelElement as IElement;
}
else
{
// Dragged from UML Model Explorer.
return element as IElement;
}
});
}
public void OnDoubleClick(ShapeElement targetElement, DiagramPointEventArgs diagramPointEventArgs)
{
}
}
Kod GetModelElementsFromDragEvent() jest opisany w Porady: pozyskiwanie elementów modelu UML z IDataObject.
Zobacz też
Koncepcje
Porady: definiowanie i instalowanie rozszerzenia modelowania
Rozszerzanie diagramów i modeli UML
Porady: definiowanie polecenia menu na diagramie modelowania