首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何为闭源类型的所有属性注入自定义UITypeEditor?

如何为闭源类型的所有属性注入自定义UITypeEditor?
EN

Stack Overflow用户
提问于 2009-05-11 17:45:17
回答 3查看 9.4K关注 0票数 9

我希望避免在为其编写自定义UITypeEditor的特定类型的每个实例上放置EditorAttribute。

我不能在类型上放置EditorAttribute,因为我不能修改源代码。

我有一个对将要使用的唯一PropertyGrid实例的引用。

我可以告诉一个PropertyGrid实例(或所有实例)在遇到特定类型时使用自定义UITypeEditor吗?

Here是一篇MSDN文章,它提供了在.NET 2.0或更高版本中如何做到这一点的起点。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2009-05-11 19:56:39

您通常可以在运行时通过TypeDescriptor.AddAttributes关联编辑器等。例如( Bar属性应显示一个"...“显示“正在编辑!”):

代码语言:javascript
复制
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() } } });
    }
}
票数 24
EN

Stack Overflow用户

发布于 2012-09-26 00:06:52

Marc的解决方案直截了当地将EditorAttribute全局应用于Bar类型。如果您有一个微妙的配置,您可能会更倾向于注释特定实例的属性。遗憾的是,这在TypeDescriptor.AddAttributes中是不可能的

我的解决方案是编写一个包装器ViewModel<T>,它从T复制属性,用额外的属性注释一些属性。假设我们有一个类型为Report的变量datum,我们将像这样使用它

代码语言:javascript
复制
        var pretty = ViewModel<Report>.DressUp(datum);
        pretty.PropertyAttributeReplacements[typeof(Smiley)] = new List<Attribute>() { new EditorAttribute(typeof(SmileyEditor),typeof(UITypeEditor))};
        propertyGrid1.SelectedObject = pretty;

其中定义了ViewModel<T>

代码语言:javascript
复制
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);
    }
}

如上所述,这将替换特定类型的属性,但如果需要更高的分辨率,您可以按名称替换属性。

票数 3
EN

Stack Overflow用户

发布于 2009-05-11 17:51:02

只需在类中添加一个Editor attribute即可。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/849202

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档