向层关系图添加自定义属性

当您在 Visual Studio 旗舰版 中为图表层编写扩展代码关系图时,可以图表层上的任何元素存储值。 在图表保存并重新打开时,值仍保持一致。 您还可以让这些属性显示在**“属性”**窗口中,以便用户可查看和编辑它们。 例如,您可以让用户为每一层指定正则表达式,并编写验证验证代码来确认每层中的类名称符合用户指定的模式。

不向用户显示的属性

如果仅是希望使您的代码为图表层的任何元素附加值,您不必定义 MEF 组件。 在 ILayerElement 有一个名为的 Properties 字典。 简单添加 marshalable 值到任何层元素字典。 它们将作为图表层部件被保存。 有关详细信息,请参阅在程序代码中导航和更新层模型

用户可以编辑的属性

初始准备

重要

为了让属性显示,您必须为每台要显示层属性的计算机做出以下更改。

  1. 以管理员身份运行运行"记事本"打开 %ProgramFiles%\Microsoft Visual Studio 12.0\Common7\IDE\Extensions\Microsoft\Architecture Tools\ExtensibilityRuntime\extension.vsixmanifest

  2. 在 Content 元素中,添加:

    <MefComponent>Microsoft.VisualStudio.ArchitectureTools.Extensibility.Layer.Provider.dll</MefComponent>
  3. 在 windows "开始"菜单,在 Microsoft Visual Studio 2012Visual Studio 工具 下,打开 开发人员命令提示

    Enter(输入):

    devenv /rootSuffix /updateConfiguration

    devenv /rootSuffix Exp /updateConfiguration

  4. 重新启动 Visual Studio。

确保您的代码在 VSIX 项目中

如果您的属性是命令、笔势或验证项目的一部分,无需添加任何内容。 自定义属性代码应该定义在 Visual Studio 扩展项目中,并作为 MEF 组件. 有关更多信息,请参见向层关系图添加命令和特定动作向层关系图添加自定义体系结构验证

定义自定义属性

若要创建自定义属性,请定义如下类:

[Export(typeof(IPropertyExtension))]
public class MyProperty 
      : PropertyExtension<ILayerElement>
{
  // Implement the interface.
}

可以在 ILayerElement 或任何派生类中,包括:

  • ILayerModel - 模型

  • ILayer - 每层

  • ILayerDependencyLink - 层之间的链接

  • ILayerComment

  • ILayerCommentLink

查看您的自定义属性

重要

只有当体系结构资源管理器在加载建模项目前是打开的情况下自定义属性才会显示。您可能必须打开体系结构资源管理器然后停止并重新启动 Visual Studio 才能看到自定义属性。在“体系结构”菜单上,选择“窗口”、“体系结构资源管理器”。

若要测试您的自定义特性,请按 F5 启动 Visual Studio 的实验实例。 创建相应的层元素的示例,并将其选中。 您将看到您的"属性"窗口中的自定义特性。

示例

以下代码是典型的自定义属性描述符。 它在层模型 (ILayerModel) 上定义了一个布尔值属性,该属性允许用户为自定义验证方法提供值。

using System;
using System.ComponentModel.Composition;
using Microsoft.VisualStudio.ArchitectureTools.Extensibility.Layer;

namespace MyNamespace
{
  /// <summary>
  /// Custom properties are added to the Layer Designer via a custom
  /// Property Descriptor. We have to export this Property Descriptor
  /// using MEF to make it available in the Layer Designer.
  /// </summary>
  [Export(typeof(IPropertyExtension))]
  public class AllTypesMustBeReferencedProperty 
      : PropertyExtension<ILayerModel>
  {
    /// <summary>
    /// Each custom property must have a unique name. 
    /// Usually we use the full name of this class.
    /// </summary>
    public static readonly string FullName =
      typeof(AllTypesMustBeReferencedProperty).FullName;

    /// <summary>
    /// Construct the property. Notice the use of FullName.
    /// </summary>
    public AllTypesMustBeReferencedProperty()
            : base(FullName)
    {  }

    /// <summary>
    /// The display name is shown in the Properties window.
    /// We therefore use a localizable resource.
    /// </summary>
    public override string DisplayName
    {
      get { return Strings.AllTypesMustBeReferencedDisplayName; }
    }

    /// <summary>
    /// Description shown at the bottom of the Properties window.
    /// We use a resource string for easier localization.
    /// </summary>
    public override string Description
    {
      get { return Strings.AllTypesMustBeReferencedDescription; }
    }

    /// <summary>
    /// This is called to set a new value for this property. We must
    /// throw an exception if the value is invalid.
    /// </summary>
    /// <param name="component">The target ILayerElement</param>
    /// <param name="value">The new value</param>
    public override void SetValue(object component, object value)
    {
      ValidateValue(value);
      base.SetValue(component, value);
    }
    /// <summary>
    /// Helper to validate the value.
    /// </summary>
    /// <param name="value">The value to validate</param>
    private static void ValidateValue(object value)
    {  }

    public override Type PropertyType
    { get { return typeof(bool); } }

    /// <summary>
    /// The segment label of the properties window.
    /// </summary>
    public override string Category
    { 
      get
      {
        return Strings.AllTypesMustBeReferencedCategory;
      }
    }
  }
}

请参见

概念

扩展层关系图