在C#或VB.NET中,在Windows窗体的.NET Framework 4.x下,我希望编写一个通用函数,以便在运行时为指定的控件属性类型调用默认的UI编辑器。
示例(不完整代码):
public T EditValue<T>(Component component, string propertyName, T value) {
PropertyDescriptor propDescriptor =
TypeDescriptor.GetProperties(component)[propertyName];
UITypeEditor editor =
(UITypeEditor)propDescriptor.GetEditor(typeof(UITypeEditor));
IWindowsFormsEditorService serviceProvider = ??????;
object result = editor.EditValue(serviceProvider, serviceProvider, value);
return (T)result;
}
(当然,函数定义也可以指定ExtensionAttribute以简化函数调用。)
示例用法如下:编辑Control.Font属性:
TextBox ctrl = this.TextBox1;
Font value = EditValue(ctrl, nameof(ctrl.Font), ctrl.Font);
ctrl.Font = value;
或者编辑ListBox中的项目:
ListBox ctrl = this.ListBox1;
ListBox.ObjectCollection value = EditValue(ctrl, nameof(ctrl.Items), ctrl.Items);
我需要帮助来确定这是否是实现这种功能的正确方法(也许所有这些都可以通过反射或其他方式更容易地完成?),还需要帮助来获得默认的IServiceProvider/IWindowsFormsEditorService示例,以便能够编辑我传递给上述代码的函数的控件。
我研究并发现了这个答案,它演示了如何定义一个实现IServiceProvider/IWindowsFormsEditorService接口的新类:
https://stackoverflow.com/a/3816585/1248295
因此,在上面的代码中,我可以替换以下代码行:
IWindowsFormsEditorService serviceProvider = ??????;
为此:
RuntimeServiceProvider serviceProvider = new RuntimeServiceProvider();
它的工作原理是:
但我想问的是,窗体、组件或控件类型中是否已经定义了一个类,它已经实现了IServiceProvider/IWindowsFormsEditorService用于此目的,这样我就可以示例化它或通过Reflection检索它来示例化它,从而简化我的代码,以避免仅为定义RuntimeServiceProvider类而编写更多代码。
我想知道,是否可以在不需要定义RuntimeServiceProvider之类的自定义类来实现IWindowsFormsEditorService的情况下简化操作。
1条答案
按热度按时间tzxcd3kk1#
由于无法找到其他更简单的方法,我不得不定义一个类来实现ITypeDescriptorContext、IServiceProvider和IWindowsFormsEditorService。在本例中,我定义了三个类,只是因为我更喜欢单独的实现,这些实现在将来单独使用时可能更有用,但所有这些实现都可以在一个类中定义,如@Reza的C#示例。
这不是一个可以接受的答案,但它是一个有效的解决方案,因为缺少更简单的东西。
我们开始吧:
服务提供程序.vb
Windows窗体编辑器服务.vb
类型描述符上下文.vb
最后是Component类和派生类(如Control、UserControl或Form)的方法扩展模块:
组件扩展.vb
导入此名称空间后:
它的使用非常简单:
或者这样: