Question

Je suis une peaufinage application WinForms. Cette application a une Form qui contient un PropertyGrid. Un objet est affecté à la propriété de SelectedObject de telle sorte que la grille des propriétés affiche les propriétés de l'objet.

Le type de l'objet attribué a une propriété qui porte un EditorAttribute spécifiant un UITypeEditor.

Cette mise en œuvre des déclarations UITypeEditor UITypeEditorEditStyle.Drop dans son remplacement de la méthode de GetEditStyle. Sa méthode de EditValue affiche un ListBox à partir de laquelle peut se voir attribuer une valeur pour la propriété d'instance.

Tout cela est bien un bien jusqu'à présent.

Maintenant, j'ai une exigence supplémentaire qui appelle les éléments disponibles dans la liste à modifier en fonction de l'autre Etat détenu par l'Form qui héberge le PropertyGrid. Je ne peux pas travailler sur la façon d'obtenir cette information contextuelle à la méthode EditValue.

Il ne semble pas être quelque chose sur le paramètre context même si je tente de le jeter à des types plus spécifiques. Je ne puis trouver comment ajouter un autre service pour récupérer de la provider.

Toutes les idées?

Était-ce utile?

La solution

Je me demande si ce que vous essayez de faire serait serait mieux comme TypeConverter via GetStandardValues? Mais de toute façon, à la fois context.Instance et context.PropertyDescriptor semblent pour être placés dans un test rapide (pour les GetEditStyle et 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()
                }
            }
        });
    }
}

Ou comme un type convertisseur:

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

Autres conseils

J'étais dans la même situation, je voulais injecter un objet dans le constructeur de mon UITypeEditor personnalisé.

J'ai suivi Nicolas Cadilhac commentaire dans Ici , donnez-lui tout le crédit. Il utilise TypeDescriptionProvider.

Voici l'ensemble complet de code.

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

Dans la méthode EditValue surchargée, context.Container fournira l'objet que l'éditeur appartient. La propriété context.Container.Components établira une liste de toutes les commandes qui comprend la forme et tous ses enfants.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top