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

时间:2019-05-17 15:10:15

标签: .net winforms propertygrid design-time uitypeeditor

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

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

当我们在已编译应用程序的WinForms包中的标准PropertyGrid控件中显示自定义控件的属性时,只有将我们的DLL放置在程序库中时,才能找到设计时DLL中的相应类型转换器和UI类型编辑器。包含应用程序exe的文件夹。由于某些原因,我们不想在此文件夹中复制设计时DLL。还有其他方法可以告诉PropertyGrid控件在哪里可以找到以这种方式引用的设计时DLL吗?

1 个答案:

答案 0 :(得分:1)

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

  • 在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之前的主方法中添加以下代码:

    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的注释中已经提到的那样,如果具有程序集的已知位置,则还可以通过使用probing在app.config中注册已知的文件夹来加载程序集而无需编写代码。标签或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; }
    
  

注意:以上所有选项均不需要为包含类型转换器的程序集添加引用。