Procedura: rispondere alle modifiche in un modello UML
È possibile scrivere codice che viene eseguito ogni qualvolta viene apportata una modifica in un modello UML in Visual Studio. Il codice consentirà di rispondere ugualmente a modifiche apportate direttamente dall'utente e da altre estensioni di Visual Studio.
Attenzione |
---|
La caratteristica non viene supportata direttamente dall'API dell'estensione ULM. Pertanto, è necessario utilizzare tecniche meno convenzionali. In questo argomento viene fornito il codice necessario. Tuttavia, in alcuni casi è possibile che si verifichino effetti imprevisti. È inoltre possibile che modifiche successive nell'implementazione Visual Studio di UML invalidino le tecniche descritte in questo argomento. |
Per utilizzare le tecniche descritte in questo argomento, è opportuno avere familiarità con l'SKD di visualizzazione e modellazione (VMSDK) tramite il quale vengono implementati gli strumenti UML. Per ulteriori informazioni, vedere SDK di visualizzazione e modellazione (linguaggi specifici di dominio).
In questo argomento:
Creazione di un progetto di estensione UML
Eventi e regole
Definizione di eventi
Esempio: Cassi di colorazione dagli stereotipi tramite gli eventi
Definizione di regole
Esempio: Classi di colorazione dagli stereotipi tramite le regole
Esempio: Associazioni bidirezionali per impostazione predefinita
Modelli principali e di visualizzazione
Creazione di un progetto di estensione UML
In molti casi, si aggiungerà un gestore dell'evento a un'estensione che implementa già un comando o un gestore movimenti. In questo caso, sarà possibile aggiungere allo stesso progetto di Visual Studio il codice descritto in questo argomento. Per ulteriori informazioni, vedere Procedura: definire un comando di menu in un diagramma di modellazione e Procedura: definire un gestore di trascinamento della selezione e doppio clic in un diagramma di modellazione.
Se si desidera creare il gestore dell'evento in un'estensione di Visual Studio distinta, iniziare creando un nuovo progetto di convalida UML. Nella finestra di dialogo Nuovo progetto fare clic su Progetti di modello e quindi selezionare Estensione di convalida del modello. In alternativa, è possibile seguire la procedura Definizione di un'estensione della convalida in Procedura: definire vincoli di convalida per i modelli UML.
È necessario aggiungere al progetto i riferimenti riportati di seguito.
\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\PrivateAssemblies\Microsoft.VisualStudio.Uml.dll
Microsoft.VisualStudio.ArchitectureTools.Extensibility.dll
Microsoft.VisualStudio.Modeling.Sdk.10.0dll
Microsoft.VisualStudio.Modeling.Sdk.Diagrams.10.0.dll
Microsoft.VisualStudio.Uml.Interfaces.dll
Eventi e regole
VMSDK fornisce due metodi principali per il rilevamento delle modifiche nell'archivio:
Un gestore dell'evento risponde a una modifica al termine della transazione nella quale si è verificata la modifica. I gestori degli eventi vengono in genere utilizzati per propagare le modifiche al fuori del modello, a interfacce utente, file o database. È anche possibile scrivere un gestore dell'evento che apporta una modifica aggiuntiva al modello in una nuova transazione.
Una regola risponde a una modifica all'interno della transazione nella quale si è verificata la modifica. In genere, le regole vengono utilizzate per propagare le modifiche all'interno del modello, ad esempio per mantenere la coerenza tra due parti del modello. È anche possibile scrivere una regola che impedisca di apportare una modifica non valida tramite l'annullamento della transazione.
Per ulteriori informazioni sulle transazioni, vedere Procedura: collegare aggiornamenti di modelli tramite transazioni.
Definizione di gestori degli eventi
Per fare in modo che il gestore dell'evento venga richiamato quando si verifica una modifica, è necessario registrarlo. È necessario registrare il gestore per ogni classe di elemento che si desidera monitorare, ad esempio UseCase o Activity. Non è necessario registrarlo per ogni istanza.
L'esempio che segue consente di impostare il colore di una classe UML in base allo stereotipo che l'utente applica. I gestori degli eventi vengono registrati per essere attivati ogni qualvolta viene creata o eliminata un'istanza dello stereotipo. Poiché in questo esempio vengono utilizzati i gestori degli eventi, e non le regole, i gestori vengono chiamati dopo il completamento della transazione nella quale viene modificato lo stereotipo. Poiché il colore rappresenta anche una modifica all'interno dell'archivio VMSDK, deve essere eseguito in una seconda transazione.
È anche possibile utilizzare i gestori degli eventi per apportare modifiche al di fuori dell'archivio.
È possibile adattare il codice dell'esempio seguente per rispondere a eventi in base alle esigenze. Nel codice è importante notare gli aspetti seguenti:
La convalida API viene utilizzata per registrare i gestori degli eventi. Il framework di convalida fornisce un modo pratico per eseguire il codice quando viene aperto il modello. Tuttavia, il codice non esegue effettivamente la convalida e l'utente non deve richiamare la convalida per effettuare gli aggiornamenti.
I gestori degli eventi sono metodi aggiunti a Store.EventManagerDirectory. Si tratta dell'elemento Store dell'implementazione VMSDK (DSL) sottostante, non dell'elemento ModelStore UML. EventManagerDirectory dispone di un set fisso di dizionari per diversi tipi di eventi, quali ElementAdded e ElementDeleted.
Per registrare un evento, è necessario conoscere il nome della classe di implementazione o la relazione che si desidera monitorare. Queste classi vengono definite in Microsoft.VisualStudio.Modeling.Uml.dll ed è possibile visualizzare i nomi delle classi quando si controllano proprietà nel debugger. È possibile eseguire il cast di questi membri della classe ai tipi di interfaccia appropriati, quali IClass, IStereotype. Per un elenco dei tipi di interfaccia, vedere Tipi di elemento del modello.
I nomi delle classi di implementazione potrebbero essere diversi in versioni future.
I gestori degli eventi vengono chiamati quando l'utente richiama i comandi Annulla e Ripristina. Ad esempio, dopo un evento Aggiungi, Annulla genererà un evento Elimina. Se il gestore dell'evento sta propagando modifiche al di fuori dell'archivio, dovrà rispondere a questi eventi. Tuttavia, non dovrà apportare modifiche nell'archivio in risposta ai comandi Annulla o Ripeti e non dovrà apportare modifiche quando il modello viene letto dal file. È possibile utilizzare if (!store.InUndoRedoOrRollback && !store.InSerializationTransaction)....
Nell'esempio vengono mostrati i gestori degli eventi per l'aggiunta e l'eliminazione di oggetti nel modello. È anche possibile creare gestori degli eventi per le modifiche nei valori delle proprietà. Per ulteriori informazioni, vedere I gestori eventi propagano le modifiche al di fuori del modello.
Per informazioni dettagliate sugli eventi, vedere I gestori eventi propagano le modifiche al di fuori del modello.
Esempio: Classi di colorazione per stereotipo tramite gli eventi
Per questo esempio è necessario anche aggiungere un riferimento al progetto a System.Drawing.dll.
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Drawing;
using System.Linq;
using Microsoft.VisualStudio.ArchitectureTools.Extensibility.Presentation;
using Microsoft.VisualStudio.ArchitectureTools.Extensibility.Uml;
using Microsoft.VisualStudio.Modeling;
using Microsoft.VisualStudio.Modeling.Diagrams;
using Microsoft.VisualStudio.Modeling.Validation;
using Microsoft.VisualStudio.Uml.AuxiliaryConstructs;
using Microsoft.VisualStudio.Uml.Classes;
using Microsoft.VisualStudio.Uml.Profiles;
using Microsoft.VisualStudio.Uml.UseCases;
using Microsoft.VisualStudio.Uml.ModelStore; // in private assembly. Used for Get|IsElementDefinition()
namespace UmlEvents // <<<< EDIT
{
/// <summary>
/// Wraps a UML model to add stereotype coloring.
/// </summary>
public partial class ColoringModelAdapter
{
// This is the underlying DSL store, not the wrapping UML ModelStore:
private Store store;
/// <summary>
/// This isn't actually validation. It's to couple this adapter to the model before we start.
/// The validation package creates an instance of this class and then calls this method.
/// See "Validation": https://msdn.microsoft.com/library/bb126413.aspx
/// </summary>
/// <param name="vcontext"></param>
/// <param name="model"></param>
[Export(typeof(System.Action<ValidationContext, object>))]
[ValidationMethod(ValidationCategories.Open)]
public void ConnectAdapterToModel(ValidationContext vcontext, IModel model)
{
// This is the underlying DSL store, not the wrapping UML ModelStore:
store = (model as ModelElement).Store;
// Add an event that triggers on creating a stereotype instance.
// See "Event handlers": https://msdn.microsoft.com/library/bb126250.aspx
DomainClassInfo siClass = store.DomainDataDirectory.FindDomainClass
("Microsoft.VisualStudio.Uml.Classes.StereotypeInstance");
store.EventManagerDirectory.ElementAdded.Add(siClass,
new EventHandler<ElementAddedEventArgs>(StereotypeInstanceAdded));
// For the deletion, we need to trigger from the deleted link
// between the stereotype instance and the model element -
// because after deletion we can't find the element from the stereotype instance.
DomainRelationshipInfo linkToStereotypeClass = store.DomainDataDirectory.FindDomainRelationship
("Microsoft.VisualStudio.Uml.Classes.ElementHasAppliedStereotypeInstances");
store.EventManagerDirectory.ElementDeleted.Add(linkToStereotypeClass,
new EventHandler<ElementDeletedEventArgs>(StereotypeInstanceDeleted));
// Add here handlers for other events.
}
/// <summary>
/// Event handler called whenever a stereotype instance is linked to a uml model element.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void StereotypeInstanceAdded(object sender, ElementAddedEventArgs e)
{
// Don't handle changes in undo or load from file:
if (store.InUndoRedoOrRollback || store.InSerializationTransaction) return;
IStereotypeInstance si = e.ModelElement as IStereotypeInstance;
IElement umlElement = si.Element;
// Work only with the core model, not the views:
if (!umlElement.IsElementDefinition()) return;
// I'm only interested in coloring classes and interfaces:
if (!(umlElement is IType)) return;
Color? color = ColorForStereotype(si.Name);
if (color.HasValue)
{
SetColorOfShapes(si.Element, color.Value);
}
}
/// <summary>
/// Called whenever a stereotype instance is deleted - well, actually,
/// when the link between the stereotype instance and the uml model element is deleted.
/// Triggering on the link deletion allows us to get both ends.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void StereotypeInstanceDeleted(object sender, ElementDeletedEventArgs e)
{
// Don't handle changes in undo or load from file:
if (store.InUndoRedoOrRollback || store.InSerializationTransaction) return;
// Use the generic link type to avoid unearthing the UML implementation DLL:
ElementLink elementToStereotypeLink = e.ModelElement as ElementLink;
IElement umlElement = elementToStereotypeLink.LinkedElements[0] as IElement;
IStereotypeInstance si = elementToStereotypeLink.LinkedElements[1] as IStereotypeInstance;
// Work only with the core model, not the views:
if (!umlElement.IsElementDefinition()) return;
// We're here either because a stereotype is being un-applied,
// or because the uml element is being deleted.
// Don't bother if the element is being deleted:
if ((umlElement as ModelElement).IsDeleting) return;
// We're only interested in classes and interfaces:
if (!(umlElement is IType)) return;
// Because more than one stereotype can be applied to an element,
// we should check to see if there are any remaining:
Color newColor = Color.WhiteSmoke; // Default if there aren't.
foreach (IStereotypeInstance remainingSi in umlElement.AppliedStereotypes)
{
Color? color = ColorForStereotype(remainingSi.Name);
if (color.HasValue)
{
newColor = color.Value;
break;
}
}
SetColorOfShapes(umlElement, newColor);
}
private void SetColorOfShapes(IElement element, Color color)
{
foreach (IShape shape in element.Shapes())
{
shape.Color = color;
}
}
/// <summary>
/// This example deals only with a subset of the standard stereotypes.
/// </summary>
private Color? ColorForStereotype(string name)
{
switch (name)
{
case "focus": return Color.AliceBlue;
case "auxiliary": return Color.Bisque;
case "specification": return Color.OliveDrab;
case "realization": return Color.LightSeaGreen;
case "implementationClass": return Color.PaleGoldenrod;
}
return null;
}
}}
Definizione di regole
È possibile definire una regola per propagare una modifica all'interno dell'archivio VMSDK. Sia la modifica di attivazione che la regola vengono eseguite all'interno della stessa transazione. Se l'utente richiama il comando Annulla, entrambe le modifiche verranno annullate.
Un inconveniente dell'esempio precedente è che vengono utilizzati gestori degli eventi per modificare il colore delle forme. Il colore è associato anche a un campo dell'archivio VMSDK e deve pertanto essere eseguito in una transazione. Di conseguenza, se l'utente richiama il comando Annulla dopo avere applicato un stereotipo, la modifica del colore verrà annullata, ma lo stereotipo rimarrà applicato. Per annullare l'applicazione dello stereotipo, sarà necessario richiamare il comando Annulla una seconda volta. In alcuni casi, questo potrebbe essere l'effetto desiderato. In caso contrario, è possibile propagare tutte le modifiche all'interno di una transazione definendo delle regole.
Le regole sono meno utili per la propagazione delle modifiche al di fuori dell'archivio, poiché non vengono richiamate quando l'utente esegue un comando Annulla o Ripristina.
Una regola rappresenta una classe registrata tramite la gestione regole. In genere, quando si scrive del codice VMSDK, si registra una regola allegando un attributo alla classe e includendo la classe in un elenco che viene letto quando il codice di estensione viene caricato. Tuttavia, poiché l'implementazione UML è già compilata, è necessario aggiungere la regola alla gestione regole in modo dinamico. Il codice fornito nell'esempio è fortemente dipendente dalla gestione di implementazione delle regole attuale, che potrebbe subire modifiche nelle versioni future.
Per aggiungere una regola, è necessario conoscere i nomi della classe di implementazione. Questi potrebbero subire modifiche nelle versioni future. Per quanto possibile, è necessario eseguire il cast di elementi ai tipi di API UML quali IClass, IProfile.
Nell'esempio vengono mostrate regole che consentono di gestire l'aggiunta e l'eliminazione di oggetti nel modello UML. È anche possibile creare regole che rispondono alle modifiche nelle proprietà di oggetti. Per ulteriori informazioni, vedere Le regole propagano le modifiche all'interno del modello.
Esempio: Classi di colorazione per stereotipo tramite le regole
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Drawing;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.ArchitectureTools.Extensibility.Presentation;
using Microsoft.VisualStudio.ArchitectureTools.Extensibility.Uml;
using Microsoft.VisualStudio.Modeling;
using Microsoft.VisualStudio.Modeling.Diagrams;
using Microsoft.VisualStudio.Modeling.Validation;
using Microsoft.VisualStudio.Uml.AuxiliaryConstructs;
using Microsoft.VisualStudio.Uml.Classes;
using Microsoft.VisualStudio.Uml.UseCases;
using Microsoft.VisualStudio.Uml.ModelStore; // in private assembly. Used for Get|IsElementDefinition()
namespace UmlRules
{
class ColorByStereotype
{
/// <summary>
/// Singleton wrappers: one per model.
/// </summary>
private static Dictionary<IPackage, ColorByStereotype > modelAdapters =
new Dictionary<IPackage, ColorByStereotype >();
private class Wrapper
{
/// <summary>
/// This isn't actually validation.
/// It sets up some store rules.
/// The validation package creates an instance of this class and then calls this method.
/// See "Validation": https://msdn.microsoft.com/library/bb126413.aspx
/// </summary>
/// <param name="vcontext"></param>
/// <param name="model"></param>
[Export(typeof(System.Action<ValidationContext, object>))]
[ValidationMethod(ValidationCategories.Open)]
private void ConnectAdapterToModel(ValidationContext vcontext, IModel model)
{
modelAdapters.Add(model, new ColorByStereotype (model));
}
}
private IModel model;
private Store store;
private ColorByStereotype (IModel model)
{
this.model = model;
// This is the underlying DSL store, not the wrapping UML ModelStore:
store = (model as ModelElement).Store;
SetRule<StereotypeInstanceAddedRule>(
store.DomainDataDirectory.FindDomainClass(
"Microsoft.VisualStudio.Uml.Classes.StereotypeInstance"));
// For the deletion, we need to trigger from the deleted link
// between the stereotype instance and the model element -
// because after deletion we can't find the element from the stereotype instance.
SetRule<StereotypeInstanceDeletedRule>(
store.DomainDataDirectory.FindDomainRelationship(
"Microsoft.VisualStudio.Uml.Classes.ElementHasAppliedStereotypeInstances"));
}
/// <summary>
/// Register a rule.
/// Normally, you set a rule by prefixing the rule class with
/// [RuleOn(typeof(TargetClass))]
/// but we are setting up the rule at runtime, so must add
/// the rules to the relevant dictionaries.
/// </summary>
/// <typeparam name="T">Rule class</typeparam>
/// <param name="classInfo">Class or relationship to which to attach the rule.</param>
private void SetRule<T>(DomainClassInfo classInfo) where T : Rule, new()
{
T rule = new T();
rule.FireTime = TimeToFire.TopLevelCommit;
System.Type tt = typeof(T);
string ruleSet = (typeof(AddRule).IsAssignableFrom(tt)) ? "AddRules" :
(typeof(ChangeRule).IsAssignableFrom(tt)) ? "ChangeRules" :
(typeof(DeleteRule).IsAssignableFrom(tt)) ? "DeleteRules" :
(typeof(DeletingRule).IsAssignableFrom(tt)) ? "DeletingRules" : "";
// The rest of this method uses reflection to achieve the following:
// store.RuleManager.RegisterRule(rule);
// classInfo.AddRules.Add(rule);
System.Reflection.BindingFlags privateBinding =
System.Reflection.BindingFlags.Instance
| System.Reflection.BindingFlags.NonPublic;
System.Reflection.MethodInfo mi =
typeof(RuleManager).GetMethod("RegisterRule", privateBinding);
mi.Invoke(store.RuleManager, new object[] { rule });
store.RuleManager.EnableRule(typeof(T));
System.Reflection.PropertyInfo pi =
typeof(DomainClassInfo).GetProperty(ruleSet, privateBinding);
dynamic rules = pi.GetValue(classInfo, null);
System.Type ruleListType = rules.GetType();
System.Reflection.FieldInfo listpi =
ruleListType.GetField("list", privateBinding);
dynamic list = listpi.GetValue(rules);
System.Type listType = list.GetType();
System.Reflection.MethodInfo addmi = listType.GetMethod("Add");
addmi.Invoke(list, new object[] { rule });
System.Reflection.MethodInfo resetRulesCache =
typeof(DomainClassInfo).GetMethod("ResetRulesCache", privateBinding);
resetRulesCache.Invoke(classInfo, null);
}
#region Rules.
private class StereotypeInstanceAddedRule : AddRule
{
public override void ElementAdded(ElementAddedEventArgs e)
{
base.ElementAdded(e);
Store store = e.ModelElement.Store;
// Don't handle load from file:
if (store.InSerializationTransaction)
return;
IStereotypeInstance si = e.ModelElement as IStereotypeInstance;
IElement umlElement = si.Element;
// Work only with the core model, not the views:
if (!umlElement.IsElementDefinition()) return;
// I'm only interested in coloring classes and interfaces:
if (!(umlElement is IType)) return;
Color? color = ColorForStereotype(si.Name);
if (color.HasValue)
{
SetColorOfShapes(si.Element, color.Value);
}
}
}
private class StereotypeInstanceDeletedRule : DeleteRule
{
public override void ElementDeleted(ElementDeletedEventArgs e)
{
base.ElementDeleted(e);
Store store = e.ModelElement.Store;
// Use the generic link type to avoid using the UML implementation DLL:
ElementLink elementToStereotypeLink = e.ModelElement as ElementLink;
IElement umlElement = elementToStereotypeLink.LinkedElements[0] as IElement;
// Work only with the core model, not the views:
if (!umlElement.IsElementDefinition()) return;
// We're here either because a stereotype is being un-applied,
// or because the uml element is being deleted.
// Don't bother if the element is being deleted:
if ((umlElement as ModelElement).IsDeleting) return;
// We're only interested in classes and interfaces:
if (!(umlElement is IType)) return;
// Because more than one stereotype can be applied to an element,
// we should check to see if there are any remaining:
Color newColor = Color.WhiteSmoke; // Default if there aren't.
foreach (IStereotypeInstance remainingSi in umlElement.AppliedStereotypes)
{
Color? color = ColorForStereotype(remainingSi.Name);
if (color.HasValue)
{
newColor = color.Value;
break;
}
}
SetColorOfShapes(umlElement, newColor);
}
}
/// <summary>
/// Set the color of the shapes that display an element.
/// </summary>
/// <param name="element"></param>
/// <param name="color"></param>
private static void SetColorOfShapes(IElement element, Color color)
{
foreach (IShape shape in element.Shapes())
{
shape.Color = color;
}
}
/// <summary>
/// For this sample, we just deal with some of the standard stereotypes.
/// </summary>
/// <param name="name">Stereotype name</param>
/// <returns></returns>
private static Color? ColorForStereotype(string name)
{
switch (name)
{
case "focus": return Color.AliceBlue;
case "auxiliary": return Color.Bisque;
case "specification": return Color.OliveDrab;
case "realization": return Color.LightSeaGreen;
case "implementationClass": return Color.PaleGoldenrod;
}
return null;
}
#endregion
}
}
Esempio: Associazioni bidirezionali per impostazione predefinita
Per impostazione predefinita, quando si disegna un'associazione in un diagramma classi, la nuova associazione è esplorabile solo in una direzione. Nell'associazione è presente una freccia a un'estremità. Per alcuni scopi, risulta più conveniente disegnare associazioni bidirezionali, senza frecce. È possibile creare associazioni bidirezionali per impostazione predefinita aggiungendo la regola seguente.
/// <summary>
/// Rule invoked when an Association is created.
/// This rule sets both ends navigable, which is convenient for representing requirements.
/// </summary>
private class AssociationAddRule : AddRule
{
public override void ElementAdded(ElementAddedEventArgs e)
{
Store store = e.ModelElement.Store;
IAssociation association = e.ModelElement as IAssociation;
// Do not apply the rule if we are reading from file or undoing a deletion:
if (association.MemberEnds.Count() == 0
|| store.InSerializationTransaction || store.InUndoRedoOrRollback) return;
// Do not apply the rule unless a containing package or model has imported
// a profile that defines the stereotype "Default Binary Associations" for associations:
// if (!association.ApplicableStereotypes.Any
// (s => s.DisplayName == "Default Binary Associations")) return;
// Don’t apply the rule to use cases:
if (!(association.SourceElement is IUseCase && association.TargetElement is IUseCase))
{
association.OwnedEnds.First().SetNavigable(true);
association.OwnedEnds.Last().SetNavigable(true);
}
}
}
Per registrare la regola, è necessario utilizzare il metodo SetRule descritto in Definizione di regole:
SetRule<AssociationAddRule>(store.DomainDataDirectory.
FindDomainRelationship("Microsoft.VisualStudio.Uml.Classes.Association"));
Se si desidera poter abilitare o disabilitare la regola, è possibile definire un profilo nel quale viene definito uno stereotipo specifico. È possibile aggiungere codice alla regola per verificare che il profilo sia stato abilitato in un modello o un pacchetto contenitore. Per ulteriori informazioni, vedere Procedura: definire un profilo per estendere UML.
Modelli principali e di visualizzazione
Il modello UML è costituito da più di un modello VMSDK (DSL):
Il modello principale contiene rappresentazioni di tutti gli elementi nel modello UML. L'utente può visualizzare questi elementi nella finestra Esplora modelli UML e accedere ad essi tramite l'API UML ModelStore. Il modello principale occupa una partizione dell'archivio VMSDK.
È presente un modello di visualizzazione per ogni diagramma UML nel progetto UML. Gli oggetti in ogni modello di visualizzazione rappresentano dei proxy per gli oggetti nel modello principale. È presente un oggetto modello di visualizzazione per ogni elemento visualizzato nel diagramma UML. Ogni modello di visualizzazione occupa una partizione dell'archivio VMSDK.
È presente un oggetto forma VMSDK per ogni elemento visualizzato in un diagramma. Tra gli elementi del modello di visualizzazione e le forme è presente una relazione 1:1.
Quando si definiscono regole o gestori degli eventi, questi vengono chiamati quando vengono apportate modifiche sia agli oggetti principali che agli oggetti di visualizzazione. È necessario gestire solo le modifiche apportare agli oggetti principali. I gestori inclusi nell'esempio utilizzano element.IsElementDefinition() per determinare se stanno gestendo l'oggetto principale.
Per utilizzare questo metodo, è necessario aggiungere un riferimento al progetto a:
%ProgramFiles%\Microsoft Visual Studio 10.0\Common7\IDE\PrivateAssemblies\Microsoft.VisualStudio.Uml.dll
Attenzione |
---|
IsElementDefinition e altri metodi definiti nell'assembly privato potrebbero essere modificati nelle versioni successive. |
using Microsoft.VisualStudio.Uml.ModelStore;
// in private assembly. Used for GetElementDefinition()
...
// Determine whether an element is view or core:
if (anElement.IsElementDefinition())
{ /* core */ }
else
{ /* view */ }
...
// If shapeElement is a shape on a diagram -
// The VMSDK element connected to the shape is in the view:
IElement viewModelElement = shapeElement.ModelElement as IElement;
// Get the core element for which the view is a proxy:
IElement coreModelElement = viewModelElement.GetElementDefinition();
...
Vedere anche
Attività
I gestori eventi propagano le modifiche al di fuori del modello
Concetti
Procedura: esplorare il modello UML
Altre risorse
Esempio: colorazione per stereotipo
Cronologia delle modifiche
Data |
Cronologia |
Motivo |
---|---|---|
Marzo 2011 |
Creato argomento. |
Commenti e suggerimenti dei clienti. |