Wie spritze ich eine benutzerdefinierte UITypeEditor für alle Eigenschaften eines Closed-Source-Typ?

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

Frage

Ich möchte zu vermeiden, auf jede Instanz eines bestimmten Typs ein Editor platzieren, die ich eine benutzerdefinierte UITypeEditor für geschrieben habe.

Ich kann keinen Editor von der Art statt, weil ich die Quelle nicht ändern kann.

Ich habe einen Verweis auf die nur Property Instanz, die verwendet wird.

Kann ich eine Instanz Property sagen (oder alle Instanzen) eine benutzerdefinierte UITypeEditor zu verwenden, wenn es eine bestimmte Art begegnet?

Hier ist ein MSDN-Artikel, der Punkt beginnen, bietet auf .NET 2.0 oder höher, wie dies in tun.

War es hilfreich?

Lösung

Sie können in der Regel-Editoren usw. zur Laufzeit über TypeDescriptor.AddAttributes zuordnen. Zum Beispiel (sollte die Bar Eigenschaft zeigen, mit einem „...“, die unter ‚Bearbeiten‘ zeigt):

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() } } });
    }
}

Andere Tipps

Marc-Lösung gilt unverblümt der Editor an die Bar global geben. Wenn Sie eine empfindliche Verfügung haben, könnten Sie eher Eigenschaften eines bestimmten Fällen mit Anmerkungen versehen. Ach, das ist nicht möglich, mit TypeDescriptor.AddAttributes

war meine Lösung einen Wrapper ViewModel<T> zu schreiben, die Kopien Eigenschaften von T, einige mit zusätzlichen Attributen mit Anmerkungen versehen. Angenommen, wir haben eine variable datum vom Typ Report, würden wir es so verwenden

        var pretty = ViewModel<Report>.DressUp(datum);
        pretty.PropertyAttributeReplacements[typeof(Smiley)] = new List<Attribute>() { new EditorAttribute(typeof(SmileyEditor),typeof(UITypeEditor))};
        propertyGrid1.SelectedObject = pretty;

Wo ViewModel<T> definiert:

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);
    }
}

Wie oben definiert, diese ersetzt Eigenschaften eines bestimmten Typs, aber Sie können Eigenschaften von Namen ersetzen, wenn Sie die größere Auflösung benötigen.

Fügen Sie einfach ein Editor Attribut zu Ihrer Klasse.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top