WinForms PropertyGrid 如何在外部库中找到自定义类型转换器?

How WinForms PropertyGrid finds custom type converters in external libraries?

我们有一个自定义控件。此控件的某些属性使用自定义类型转换器和 UI 类型编辑器,它们在单独的设计时 DLL 中实现。这些类型转换器是使用 TypeConverter and Editor 属性的字符串语法定义的,例如:

[TypeConverter("<full class name>, <library name>, Version=<version>")]
public CustomType Property1
{
    // property implementation
}

当我们在已编译应用程序中的 WinForms 包中的标准 PropertyGrid 控件中显示自定义控件的属性时,仅当我们将此 DLL 放在包含应用程序 exe 的文件夹中。由于某些原因,我们不想在此文件夹中复制设计时 DLL。有没有其他方法可以告诉 PropertyGrid 控件在哪里可以找到以这种方式引用的设计时 DLL?

您可以使用以下任一选项:

  • 在 GAC 中安装程序集并像这样修饰 属性(使用您的程序集完全限定名称)。正如汉斯在评论中已经提到的那样,我也认为这是最体面的方式:

    [TypeConverter("MyAssembly.MyClassTypeConverter, MyAssembly, Version=1.0.0.0," +
        " Culture=neutral, PublicKeyToken=8ac69aab03bb290e")]
    public MyClass MyClass { get; set; }
    
  • 将程序集复制到您的应用程序文件夹并像这样装饰 属性。

    [TypeConverter("MyAssembly.MyClassTypeConverter, MyAssembly")]
    public MyClass MyClass { get; set; }
    
  • 如果程序集的位置已知,您可以处理 AppDomain.AssemblyResolve 事件并加载程序集。例如,假设您的应用程序文件夹下有一个包含程序集的 assemblies 文件夹,您可以在 Application.Run 之前的 main 方法中添加以下代码:

    AppDomain.CurrentDomain.AssemblyResolve += (s, e) =>
        Assembly.LoadFrom(Path.Combine(Application.StartupPath,
            "assemblies", $"{e.Name}.dll"));
    

    我假设你有 属性 声明:

    [TypeConverter("MyAssembly.MyClassTypeConverter, MyAssembly")]
    public MyClass MyClass { get; set; }
    
  • 正如 TnTinMn 的评论中已经提到的,如果程序集的位置已知,您也可以在不编写代码的情况下加载程序集,方法是在 app.config 中注册已知文件夹使用 probing tag or codebase 标签。例如,假设您的应用程序文件夹下有一个 assemblies 文件夹,其中包含程序集:

    <runtime>
      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
        <probing privatePath="assemblies"/>
      </assemblyBinding>
    </runtime>
    

    我假设你有 属性 声明:

    [TypeConverter("MyAssembly.MyClassTypeConverter, MyAssembly")]
    public MyClass MyClass { get; set; }
    

Note: None of the above options need adding a reference to the assembly which contains the type converter.