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.
我们有一个自定义控件。此控件的某些属性使用自定义类型转换器和 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 orcodebase
标签。例如,假设您的应用程序文件夹下有一个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.