Frage

Ich optimiere eine WinForms -Anwendung. Diese Anwendung hat a Form das enthält a PropertyGrid. Ein Objekt wird dem zugewiesen SelectedObject Eigenschaft so dass das Eigenschaftsnetz die Eigenschaften für das Objekt zeigt.

Der Typ des zugewiesenen Objekts hat eine Eigenschaft, die eine trägt EditorAttribute angeben a UITypeEditor.

Diese Implementierung von UITypeEditor kehrt zurück UITypeEditorEditStyle.Drop in seiner Übersteuerung von GetEditStyle Methode. Es ist EditValue Methode zeigt a ListBox von dem ein Wert für die Instanzeigenschaft zugewiesen werden kann.

Alles gut ein Gut bisher.

Jetzt habe ich eine zusätzliche Anforderung, nach der die verfügbaren Elemente in der Liste gefordert werden sollen, die auf dem anderen von der gehaltenen Bundesstaat geändert werden sollen Form Hosting der PropertyGrid. Ich kann nicht herausfinden, wie ich diese Kontextinformationen an die erhalten kann EditValue Methode.

Es scheint nichts auf der context Parameter Auch wenn ich versuche, es auf spezifischere Typen zu geben. Ich kann auch nicht herausfinden, wie ich einen anderen Service hinzufügen kann, um von der abzurufen provider.

Irgendwelche Ideen?

War es hilfreich?

Lösung

Ich frage mich, ob das, was Sie versuchen, als besser wäre TypeConverter über GetStandardValues? Aber so oder so beide context.Instance und context.PropertyDescriptor erscheinen in einem kurzen Test bevölkert werden (für beide GetEditStyle und EditValue):

using System;
using System.ComponentModel;
using System.Drawing.Design;
using System.Windows.Forms;
class MyData
{
    [Editor(typeof(MyEditor), typeof(UITypeEditor))]
    public string Bar { get; set; }

    public string[] Options { get; set; }
}
class MyEditor : UITypeEditor
{
    public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
    {
        // break point here; inspect context
        return UITypeEditorEditStyle.DropDown;
    }
    public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
    {
        // break point here; inspect context
        return base.EditValue(context, provider, value);
    }

}
class Program
{
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.Run(new Form
        {
            Controls =
            {
                new PropertyGrid {
                    Dock = DockStyle.Fill,
                    SelectedObject = new MyData()
                }
            }
        });
    }
}

Oder als Typ-Konverter:

using System;
using System.ComponentModel;
using System.Windows.Forms;

class MyData
{
    [TypeConverter(typeof(MyConverter))]
    public string Bar { get; set; }

    public string[] Options { get; set; }
}
class MyConverter : StringConverter
{
    public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
    {
        return true;
    }
    public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
    {
        MyData data = (MyData)context.Instance;
        if(data == null || data.Options == null) {
            return new StandardValuesCollection(new string[0]);
        }
        return new StandardValuesCollection(data.Options);
    }
}
class Program
{
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.Run(new Form
        {
            Controls =
            {
                new PropertyGrid {
                    Dock = DockStyle.Fill,
                    SelectedObject = new MyData()
                }
            }
        });
    }
}

Andere Tipps

Ich war in einer ähnlichen Situation, ich wollte ein Objekt in den Konstruktor meines benutzerdefinierten UityPeeditors injizieren.

Ich folgte Nicolas Cadilhac Kommentar in Hier, Geben Sie ihm den ganzen Kredit. Es verwendet typedescriptionProvider.

Hier ist der vollständige Codesatz.

class Foo
{
    public Foo() { Bar = new Bar(); }
    public Bar Bar { get; set; }
}

class Bar
{
    public string Value { get; set; }
}

class BarTypeDescriptionProvider : TypeDescriptionProvider
{
    private TypeDescriptionProvider _baseProvider;
    string _extraParam;

    public BarTypeDescriptionProvider(Type t, string extraParam)
    {
        this._extraParam = extraParam;
        _baseProvider = TypeDescriptor.GetProvider(t);
    }

    public string ExtraParam
    { 
        get { return _extraParam; } 
    }

    public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance)
    {
        return new BarTypeDescriptor(this, _baseProvider.GetTypeDescriptor(objectType, instance), objectType);
    }
}


class BarTypeDescriptor : CustomTypeDescriptor
{
    private Type _objectType;
    private BarTypeDescriptionProvider _provider;

    public BarTypeDescriptor(BarTypeDescriptionProvider provider,  ICustomTypeDescriptor descriptor, Type objectType): base(descriptor)
    {
        if (provider == null) throw new ArgumentNullException("provider");
        if (descriptor == null)
            throw new ArgumentNullException("descriptor");
        if (objectType == null)
            throw new ArgumentNullException("objectType");
        _objectType = objectType;
        _provider = provider;
    }

    public override object GetEditor(Type editorBaseType)
    {
        return new BarEditor(_provider.ExtraParam);
    }
}


class BarEditor : UITypeEditor
{
    private string _extraParam;
    public BarEditor(string x)
        : base()
    {
        _extraParam = x;
    }

    public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
    {
        return UITypeEditorEditStyle.Modal;
    }
    public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
    {
        MessageBox.Show(_extraParam);
        return base.EditValue(context, provider, value);
    }
}

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        string extraParam = "Extra param from main form";

        TypeDescriptor.AddProvider(new BarTypeDescriptionProvider(typeof(Bar), extraParam), typeof(Bar));

        this.propertyGrid1.SelectedObject = new Foo();
    }
}

Michael

In der überragenden EditValue -Methode, context.Container Wird das Objekt bereitstellen, zu dem der Editor gehört. Das context.Container.Components Immobilien werden alle Kontrollen auflisten, die das Formular und alle ihre Kinder enthalten.

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