如何注入一个封闭源类型的所有属性的自定义UITypeEditor的?
-
21-08-2019 - |
题
我想避免放置EditorAttribute某种类型,我已经写了一个自定义的UITypeEditor的每一个实例。
我不能放置在型的EditorAttribute因为我不能修改源。
我必须将要使用的唯一的PropertyGrid实例的引用。
我可以告诉PropertyGrid的实例(或所有实例)使用自定义的UITypeEditor的每当遇到特定类型的?
这里是一个MSDN文章提供开始点上如何做到这一点的.NET 2.0或更高版本。
解决方案
可以在运行时编辑等经由TypeDescriptor.AddAttributes
通常相关联。例如(在Bar
财产应显示“...”,显示‘编辑!’):
using System;
using System.ComponentModel;
using System.Drawing.Design;
using System.Windows.Forms;
class Foo
{
public Foo() { Bar = new Bar(); }
public Bar Bar { get; set; }
}
class Bar
{
public string Value { get; set; }
}
class BarEditor : UITypeEditor
{
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
{
return UITypeEditorEditStyle.Modal;
}
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
{
MessageBox.Show("Editing!");
return base.EditValue(context, provider, value);
}
}
static class Program
{
[STAThread]
static void Main()
{
TypeDescriptor.AddAttributes(typeof(Bar),
new EditorAttribute(typeof(BarEditor), typeof(UITypeEditor)));
Application.EnableVisualStyles();
Application.Run(new Form { Controls = { new PropertyGrid { SelectedObject = new Foo() } } });
}
}
其他提示
Marc的溶液直截了当地施加EditorAttribute到酒吧全局类型。如果你有一个微妙的性格,你可能宁愿注释特定实例的属性。可惜的是,这是不可能用TypeDescriptor.AddAttributes
我的解决办法是写一个包装ViewModel<T>
,其在T拷贝属性,注释一些额外的属性。假设我们有报告类型的变量datum
,我们会使用这样
var pretty = ViewModel<Report>.DressUp(datum);
pretty.PropertyAttributeReplacements[typeof(Smiley)] = new List<Attribute>() { new EditorAttribute(typeof(SmileyEditor),typeof(UITypeEditor))};
propertyGrid1.SelectedObject = pretty;
其中ViewModel<T>
被定义:
public class ViewModel<T> : CustomTypeDescriptor
{
private T _instance;
private ICustomTypeDescriptor _originalDescriptor;
public ViewModel(T instance, ICustomTypeDescriptor originalDescriptor) : base(originalDescriptor)
{
_instance = instance;
_originalDescriptor = originalDescriptor;
PropertyAttributeReplacements = new Dictionary<Type,IList<Attribute>>();
}
public static ViewModel<T> DressUp(T instance)
{
return new ViewModel<T>(instance, TypeDescriptor.GetProvider(instance).GetTypeDescriptor(instance));
}
/// <summary>
/// Most useful for changing EditorAttribute and TypeConvertorAttribute
/// </summary>
public IDictionary<Type,IList<Attribute>> PropertyAttributeReplacements {get; set; }
public override PropertyDescriptorCollection GetProperties (Attribute[] attributes)
{
var properties = base.GetProperties(attributes).Cast<PropertyDescriptor>();
var bettered = properties.Select(pd =>
{
if (PropertyAttributeReplacements.ContainsKey(pd.PropertyType))
{
return TypeDescriptor.CreateProperty(typeof(T), pd, PropertyAttributeReplacements[pd.PropertyType].ToArray());
}
else
{
return pd;
}
});
return new PropertyDescriptorCollection(bettered.ToArray());
}
public override PropertyDescriptorCollection GetProperties()
{
return GetProperties(null);
}
}
如上面所定义,该取代的特定类型的属性,但可以通过名称如果需要的更大的分辨率替代性质。
只需添加一个编辑属性到您的类。
不隶属于 StackOverflow