如何使用 UITypeEditor 创建简单的 Visual Studio Automation Extender

2023-12-01

在 Visual Studio 中,当您在解决方案资源管理器中选择项目或项目项时,有时您可能希望将自定义属性添加到属性窗口(按 F4 时弹出的窗口)。此外,为了填写这些属性的值,我需要添加一个按钮来弹出表单,以便我可以在设计时从用户那里收集信息。

我可以开始使用的最简单的实现是什么? 我将如何创建一个用户界面来使用 UITypeEditAttribute 收集值?


这是我能想到的最简单的实现。

由于这是一个高级主题,因此意味着您可以在开始实现之前轻松完成所有步骤(这些都是常见的编程任务)。

如果有任何不够清楚的地方,请发表评论,我会尽力简化。请注意,这配置为在 Visual Studio 中为 Visual C# 文件创建自定义属性。当您运行或调试 Visual Studio 包并单击任何 .cs 文件时,自定义属性应显示在属性窗口中。提供的评论是必需的说明。

enter image description here

  1. 创建 Visual Studio 包。
  2. 创建一个接口来实现您想要添加到属性页的自定义属性。
  3. 创建一个实现自定义属性接口的类,并使用属性来装饰自定义属性。
  4. 创建实现的类扩展提供者接口和覆盖获取扩展器 and 可以扩展方法。
  5. 创建一个新类,继承自UI类型编辑器并覆盖获取编辑样式 and 编辑值方法。

让我们开始吧。

1. 在 Visual Studio 中创建包。

包.cs

// ... 
public sealed class ThePackage : Package
{
    private DTE2 Host;
    private ObjectExtenders _extensionManager;
    private MyExtenderProvider _extenderProvider;
    protected override void Initialize()
    {

    Host = (DTE2)Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(SDTE));
    _extenderProvider = new MyExtenderProvider();

    _extenderProviderCookie = Host.ObjectExtenders.RegisterExtenderProvider(VSConstants.CATID.CSharpFileProperties_string,
        "MyExtenderProvider", _extenderProvider);
    }
    protected override void Dispose(bool disposing)
    {
        Host.ObjectExtenders.UnregisterExtenderProvider(_extenderProviderCookie);
        _extenderProvider = null;
        base.Dispose(disposing);
    }
}

2. 创建实现您所需的自定义属性的类。

[ComVisible(true)] // Important!
public interface IMyDynamicExtender
{
    String NewProperty { get; set; }
}

3. 创建一个实现自定义属性接口的类。

[ComVisible(true)] // Important!
public class NewPropertyExtender : IMyDynamicExtender, IDisposable
{
    // These attibutes supply the property with some information
    // on how to display and which UITypeEditor to use.
    [DisplayName("New Property")]
    [Category("New")]
    [Description("Specifies the new property")]
    [Editor(typeof(CustomUiTypeEditor), typeof(UITypeEditor))]
    public String NewProperty { get; set; }
    private readonly IExtenderSite _extenderSite;
    private readonly int _cookie;
    private bool _disposed;

    public NewPropertyExtender(IExtenderSite extenderSite, int cookie)
    {
        _extenderSite = extenderSite;
        _cookie = cookie;
    }

    public void Dispose()
    {
        Dispose(true);
        // take the instance off of the finalization queue.
        GC.SuppressFinalize(this);
    }

    private void Dispose(bool disposing)
    {
        if (_disposed) return;
        if (disposing && _cookie != 0)
        {
            _extenderSite.NotifyDelete(_cookie);
        }
        _disposed = true;
    }
}

4. 创建实现 [IExtenderProvider] 接口的类并重写 [GetExtender] 和 [CanExtend] 方法。

public class MyExtenderProvider : IExtenderProvider
{
    private IMyDynamicExtender _extender;
    public object GetExtender(string extenderCatid, string extenderName,           
         object extendeeObject, IExtenderSite extenderSite,
        int cookie)
    {
        return _extender = CanExtend(extenderCatid, extenderName, extendeeObject) ?  
            new NewPropertyExtender(extenderSite, cookie) : null;
    }

    public bool CanExtend(string extenderCatid, string extenderName, object extendeeObject)
    {
        // Some implementation will be here in the real world. 
        return true;
    }
} 

5. 创建一个继承[UITypeEditor]的新类并重写[GetEditStyle]和[EditValue]方法。

public class CustomUiTypeEditor : UITypeEditor
{
    public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
    {
        return UITypeEditorEditStyle.Modal;
    }

    public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
    {
        // Use the result of a dialog or something else here.
        return "HELLO WORLD";
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 UITypeEditor 创建简单的 Visual Studio Automation Extender 的相关文章

随机推荐

  • 如何在 Android Studio 中创建使用 Google Maps Api v2 的 Android 应用程序?

    我在 Android Studio 尝试使用 GoogleMap 创建应用程序时遇到了很多麻烦 我之前按照以下指南使用 Eclipse 作为 IDE 几乎 没有出现任何问题 https developers google com maps
  • JavaScript 异步生成器

    是否可以编写如下所示的异步生成器 function gen return async function yield await yield await yield await 所以人们可以像这样使用它 例如 for let val of a
  • BCryptHelper.CheckPassword 始终返回 false

    我正在使用 BCrypt 实现密码哈希 这应该非常简单易用 但是 当使用哈希密码检查密码时 BCryptHelper CheckPassword Password hashedDBPassword 这总是返回 false 这是我的哈希类 p
  • docker postgres pgadmin 本地连​​接

    我用 nginx php 和 postgres 创建了一个 ubuntu 镜像 我想连接当前图像中的 postgres 数据库pgadmin位于我的本地计算机上 我尝试使用 docker Inspector 尝试使用图像 ip 与本地 pg
  • 是否可以使用 Java 在 Intellij 运行时清除控制台选项卡?

    我试图在 Java 运行时清除 Intellij 中的控制台选项卡 有任何想法吗 这是我尝试过的 System out print 033 143 public static void clrscr Clears Screen in jav
  • 矢量迭代器与 const vector& 不兼容

    我正在编写图表程序 在这个程序中 我有一个方法 它必须返回源自顶点的弱组件内的顶点 我收到 错误 向量迭代器不兼容 struct graph std vector
  • 如何将流转换为生成器而不泄漏承诺的解析

    我有一个流 我需要将其转换为生成器 以便上传者可以使用通用生成器 这意味着转动 stream on data chunk gt to generator streamGenerator stream chunk await generato
  • 带两个提交按钮的 Laravel 表单

    我的更新表单需要两个提交按钮 当前设置 目前 当我点击提交时 它会保存我的数据并将我重定向到另一个页面 我可以在其中编辑多个图像 所以我的表单就像两步函数 我想添加什么 我想添加另一个按钮以便保存我的数据并将我返回到索引页面 跳过第二步 最
  • 我可以将自定义字体上传到大卡特尔吗

    我在名片上使用了某种字体 为了保持一致性 我想在我的网站上使用它们 我找不到上传字体的方法 并且在自定义菜单中找不到它 帮助将不胜感激 是的 您可以使用 CSS 中的 fontface 功能上传自定义字体 但您需要有权访问服务器来存储和上传
  • Unity - 检查播放器是否接地不起作用

    我希望玩家在落地时跳跃 private void OnTriggerStay Collider other if other gameObject layer 8 isGrounded true else isGrounded false
  • 如何将单元格值设置为日期并应用默认的 Excel 日期格式?

    一段时间以来 我一直在使用 Apache POI 以编程方式读取现有的 Excel 2003 文件 现在我有一个新要求 在内存中创建整个 xls 文件 仍然使用 Apache POI 然后将它们写入最后的文件中 阻碍我的唯一问题是处理带有日
  • 在VB.NET中捕获功能键F1..F12 [关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 I cannot capture the functi
  • 未找到续集关联者

    我有一个项目正在尝试使用sequelize 它可以很好地创建数据库和表 但它永远找不到关联类方法 因此它永远不会调用关联方法 此代码可以很好地创建表 使用导入方法 但 Object keys db 会迭代每个模型 但它永远找不到关联方法 f
  • FFmpeg 无需解码视频即可获取运动向量

    我想访问 h264 视频流的运动向量而不解码视频 我知道这显示了视频和运动矢量 ffplay i myvideo avi flags2 export mvs vf codecview mv pf bf bb 如何避免解码整个视频以节省 CP
  • 如何通过传递特定日期来确定星期几?

    例如 我的日期是 23 2 2010 2010 年 2 月 23 日 我想将它传递给一个函数 该函数将返回星期几 我怎样才能做到这一点 在此示例中 该函数应返回String Tue 此外 如果只需要日期序号 如何检索 是的 根据您的具体情况
  • 如何使用迭代器在向量中导航? (C++)

    目标是访问字符串向量的 第 n 个元素 而不是 运算符或 at 方法 据我了解 迭代器可用于在容器中导航 但我以前从未使用过迭代器 而且我正在阅读的内容令人困惑 如果有人能给我一些关于如何实现这一目标的信息 我将不胜感激 谢谢 您需要利用b
  • 如何计算多线程进程的总计算时间

    我有一组任务 我们称之为T 其中每个任务T i 需要一定的时间t T i 待处理 这些任务正在并行处理X线程 这并不是说多个线程共同处理单个任务 而是多个线程正在处理多个任务 每个线程执行一个任务 然后执行下一个任务 依此类推 现在我想计算
  • geom_hexbin 将 bincount 映射到 alpha

    我希望将 geom hex bincount 设置为 alpha 就像完成的那样here 不知怎的 它对我不起作用 可能出了什么问题 ggplot2 的开发版本 library ggplot2 library reshape2 dm lt
  • 在随机字符串内使用正则表达式匹配日期

    我正在尝试这样做Java 我收到这种字符串 12 07 2004dddsss12 10 2010 rr r r10 01 2000ksdifjsdifffffdd04 04 1998 然后我必须在该字符串中找到一个或多个日期 日期格式 dd
  • 如何使用 UITypeEditor 创建简单的 Visual Studio Automation Extender

    在 Visual Studio 中 当您在解决方案资源管理器中选择项目或项目项时 有时您可能希望将自定义属性添加到属性窗口 按 F4 时弹出的窗口 此外 为了填写这些属性的值 我需要添加一个按钮来弹出表单 以便我可以在设计时从用户那里收集信