Compartir a través de


Cómo: Responder a cambios en un modelo UML

Puede escribir código para que se ejecute cuando se produzca un cambio en un modelo UML de Visual Studio. Este código responderá igualmente a los cambios que realice directamente el usuario o que realicen otras extensiones de Visual Studio.

Nota de precauciónPrecaución

Esta característica no se admite directamente en la API de extensión UML. Por tanto, tendrá que usar unas técnicas que no son demasiado convencionales. En este tema se proporciona el código necesario. Sin embargo, es posible que, en ciertos casos, se produzcan efectos inesperados. También es posible que los cambios que en un futuro pudieran realizarse en la implementación de UML de Visual Studio invaliden las técnicas descritas en este tema.

Para usar las técnicas descritas en este tema, le conviene conocer el SDK de visualización y modelado (VMSDK), con el que se implementan las herramientas UML. Para obtener más información, vea SDK de modelado y virtualización - Lenguajes específicos de dominio.

En este tema:

  • Crear un proyecto de extensión UML

  • Eventos y reglas

  • Definir eventos

  • Ejemplo: Establecer colores en las clases en función de estereotipos usando eventos

  • Definir reglas

  • Ejemplo: Establecer colores en las clases en función de estereotipos usando reglas

  • Ejemplo: Asociaciones que son bidireccionales de manera predeterminada

  • Modelo de núcleo y modelo de vista

Crear un proyecto de extensión UML

En muchos casos, el controlador de eventos que agregue a una extensión implementará ya un controlador de comandos o gestos. En ese caso, puede agregar el código que se describe aquí en el mismo proyecto de Visual Studio. Para obtener más información, vea Cómo: Definir un comando de menú en un diagrama de modelado y Cómo: Definir un controlador de colocación y doble clic en un diagrama de modelado.

Si desea crear su controlador de eventos en una Extensión de Visual Studio independiente, empiece creando un nuevo proyecto de validación de UML. En el cuadro de diálogo Nuevo proyecto, haga clic en Proyectos de modelado y, a continuación, seleccione Extensión de validación del modelo. Si lo desea, puede seguir el procedimiento que se describe en Definir extensiones de validación en Cómo: Definir restricciones de validación para modelos UML.

Debe agregar las referencias siguientes al proyecto:

  • \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

Eventos y reglas

VMSDK proporciona dos métodos principales para detectar cambios en el almacén:

  • Un controlador de eventos, que responde a un cambio una vez que finaliza la transacción en la que se ha producido el cambio. Normalmente, los controladores de eventos se usan para propagar cambios fuera del modelo, a las interfaces de usuario, a los archivos o a las bases de datos. También puede escribir un controlador de eventos que realice un cambio adicional en el modelo a través de una nueva transacción.

    Una regla, que responde a un cambio dentro de la transacción en la que se produce el cambio. Normalmente, las reglas se utilizan para propagar los cambios dentro del modelo para mantener la coherencia entre dos partes del modelo. También puede escribir una regla que evite un cambio no válido y cancele la transacción.

Para obtener más información sobre transacciones, consulte Cómo: Vincular actualizaciones del modelo mediante transacciones.

Definir controladores de eventos

Para que el controlador de eventos se invoque cuando se produce un cambio, debe registrarlo. Debe registrar el controlador de cada clase de elemento que desee supervisar, como UseCase o Activity. No tiene que registrarlo para cada instancia.

En el ejemplo que se muestra a continuación se establece el color de una clase de UML en función del estereotipo que el usuario aplica. Los controladores de eventos se registran para activarse siempre que se crea o elimina una instancia del estereotipo. Como en este ejemplo se usan controladores de eventos y no reglas, se llama a los controladores una vez que finaliza la transacción en la que se modifica el estereotipo. Como el color también representa un cambio en el almacén de VMSDK, debe realizarse en una segunda transacción.

También puede usar los controladores de eventos para realizar cambios fuera del almacén.

Puede adaptar el código del ejemplo siguiente para responder a eventos que usted mismo seleccione. Los puntos importantes que deben tenerse en cuenta sobre este código son los siguientes:

  • La API de validación se usa para registrar los controladores de eventos. El marco de validación proporciona un mecanismo apropiado para ejecutar código cuando se abre el modelo. Sin embargo, el código no realiza realmente la validación y el usuario no tiene que invocar la validación para poder realizar las actualizaciones.

  • Los controladores de eventos son métodos que se agregan a Store.EventManagerDirectory. Este es el objeto Store de la implementación de VMSDK (DSL) subyacente, no el objeto ModelStore de UML. EventManagerDirectory tiene un conjunto fijo de diccionarios para distintos tipos de eventos, como ElementAdded y ElementDeleted.

  • Para registrar un evento, debe conocer el nombre de la clase de implementación o la relación que desea supervisar. Estas clases se definen en Microsoft.VisualStudio.Modeling.Uml.dll y podrá ver los nombres de clase cuando consulte las propiedades en el depurador. Puede convertir estos miembros de clase en los tipos de interfaz adecuados, como IClass o IStereotype. Para obtener una lista de tipos de interfaz, vea Tipos de elementos del modelo.

    Los nombres de clase de implementación podrían diferir en las futuras versiones.

  • Se llama a los controladores de eventos cuando el usuario invoca los comandos Undo y Redo. Por ejemplo, después de un evento Add, el evento Undo generará un evento Delete. El controlador de eventos debería responder a estos eventos si está propagando cambios fuera del almacén. Sin embargo, no debería efectuar cambios dentro del almacén en respuesta a los eventos Undo y Redo y no debería realizar cambios cuando el modelo se está leyendo desde un archivo. Puede usar if (!store.InUndoRedoOrRollback && !store.InSerializationTransaction)....

  • En el ejemplo se muestran controladores de eventos para agregar y eliminar objetos del modelo. También puede crear controladores de eventos para realizar cambios en los valores de propiedad. Para obtener más información, vea Los controladores de eventos propagan cambios fuera del modelo.

  • Para obtener información detallada sobre estos eventos, vea Los controladores de eventos propagan cambios fuera del modelo.

Ejemplo: Establecer colores en las clases en función de estereotipos usando eventos

Para este ejemplo, debe agregar también una referencia de proyecto 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;
  } 
}}

Definir reglas

Puede definir una regla para propagar un cambio dentro del almacén de VMSDK. El cambio que provoca la activación y la regla tienen lugar en la misma transacción. Cuando el usuario invoca Undo, los dos cambios se deshacen a la vez.

Una desventaja del ejemplo anterior es que se usan controladores de eventos para cambiar el color de las formas. El color también está asociado a un campo del almacén de VMSDK y, por tanto, debe realizarse en una transacción. Por consiguiente, si el usuario invoca el comando Undo después de aplicar un estereotipo, el cambio de color se deshace, pero el estereotipo sigue aplicándose. Se requiere otro evento Undo para revertir la aplicación del estereotipo. En algunos casos, esto podría tener el efecto que se pretende, pero, si no fuera así, se pueden propagar todos los cambios en una única transacción definiendo reglas.

Las reglas resultan menos útiles para propagar los cambios fuera del almacén, porque no se invocan cuando el usuario ejecuta un comando Undo o Redo.

Una regla es una clase registrada con el administrador de reglas. Normalmente, cuando escribe código VMSDK, registra una regla asociando un atributo a la clase e incluyendo la clase en una lista que se lee cuando se carga el código de la extensión. Sin embargo, dado que la implementación de UML ya está compilada, debe agregar la regla al administrador de reglas dinámicamente. El código que se muestra en el ejemplo depende plenamente de la administración de la regla de implementación actual, que podría cambiar en futuras versiones.

Para agregar una regla, tiene que conocer los nombres de las clases de implementación. Estos nombres podrían cambiar en futuras versiones. En la medida de lo posible, debería convertir estos elemento en tipos de API de UML, como IClass o IProfile.

En el ejemplo se muestran reglas que administran la incorporación y eliminación de objetos en el modelo UML. También puede crear reglas que respondan a los cambios de las propiedades de objetos. Para obtener más información, vea Las reglas propagan los cambios dentro del modelo.

Ejemplo: Establecer colores en las clases en función de estereotipos usando reglas

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
  }
}

Ejemplo: Asociaciones que son bidireccionales de manera predeterminada

De forma predeterminada, al dibujar una asociación en un diagrama de clases, la nueva asociación solo es navegable en una dirección. Tiene una punta de flecha en un extremo. En algunos casos, es más conveniente dibujar asociaciones bidireccionales, sin puntas de flecha. Puede convertir las asociaciones bidireccionales en el valor predeterminado agregando la siguiente regla.

/// <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);
    }
  }
}

Para registrar la regla, debe usar el método SetRule que se describe en Definir reglas:

SetRule<AssociationAddRule>(store.DomainDataDirectory.
      FindDomainRelationship("Microsoft.VisualStudio.Uml.Classes.Association"));

Si desea poder habilitar o deshabilitar esta regla, puede hacerlo estableciendo un perfil en el que se define un estereotipo determinado. Puede agregar código a la regla para comprobar que el perfil se ha habilitado en un paquete o modelo contenedor. Para obtener más información, vea Cómo: Definir un perfil para ampliar UML.

Modelo de núcleo y modelo de vista

El modelo UML se compone de varios modelos VMSDK (DSL):

  • El modelo de núcleo contiene representaciones de todos los elementos del modelo UML. El usuario puede ver estos elementos en la ventana Explorador de modelos UML y puede acceder a ellos a través de la API ModelStore de UML. El modelo de núcleo ocupa una partición del almacén de VMSDK.

  • Hay un modelo de vista por cada diagrama UML del proyecto UML. Los objetos de cada modelo de la vista representan los objetos del modelo de núcleo. Hay un objeto de modelo de vista por cada elemento que se muestra en el diagrama UML. Cada modelo de vista ocupa una partición del almacén de VMSDK.

  • Hay un objeto de forma VMSDK por cada uno de los elementos que se muestran en un diagrama. La relación entre las formas y elementos del modelo de vista es 1:1.

Cuando se definen reglas o controladores de eventos, estos se invocan si los objetos de vista o núcleo cambian. Solo debe administrar los cambios de los objetos de núcleo. Los controladores de los ejemplos usan element.IsElementDefinition() para determinar si están tratando con el objeto de núcleo.

Para usar este método debe agregar una referencia de proyecto a:

%ProgramFiles%\Microsoft Visual Studio 10.0\Common7\IDE\PrivateAssemblies\Microsoft.VisualStudio.Uml.dll

Nota de precauciónPrecaución

IsElementDefinition y otros métodos definidos en el ensamblado privado podrían cambiar en las futuras versiones.

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();
...

Vea también

Tareas

Los controladores de eventos propagan cambios fuera del modelo

Otros recursos

Cómo: Navegar por el modelo UML

Sample: Color by Stereotype

Historial de cambios

Fecha

Historial

Motivo

Marzo de 2011

Se ha creado el tema.

Comentarios de los clientes.