폐쇄 소스 유형의 모든 속성에 대해 사용자 정의 UityPeeditor를 어떻게 주입합니까?

StackOverflow https://stackoverflow.com/questions/849202

문제

사용자 정의 UityPeeditor를 작성한 특정 유형의 모든 인스턴스에 편집장을 배치하지 않습니다.

소스를 수정할 수 없기 때문에 유형에 편집장을 배치 할 수 없습니다.

사용될 유일한 PropertyGrid 인스턴스에 대한 참조가 있습니다.

PropertyGrid 인스턴스 (또는 모든 인스턴스)에 특정 유형이 발생할 때마다 사용자 정의 UityPeeditor를 사용하도록 지시 할 수 있습니까?

여기 .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의 솔루션은 전 세계 막대 유형에 편집장을 무뚝뚝하게 적용합니다. 섬세한 처분이있는 경우 특정 사례의 속성에 주석을 달 수 있습니다. 아아, 그건 가능하지 않습니다 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);
    }
}

위에서 정의 된 바와 같이, 이것은 특정 유형의 속성을 대체하지만 더 큰 해상도가 필요한 경우 속성을 이름으로 대체 할 수 있습니다.

그냥 추가하십시오 편집기 속성 수업에.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top