Unter Verwendung des .NET-Auflistungs-Editor ohne eine Eigenschaft Grid-Control zu verwenden

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

Frage

Ich habe eine Property auf meiner Form. Mein Chef denkt, es ist hässlich. Ungehobelt. Ungekünstelt.

Er will eine schöne, gepflegte, saubere Form. Hier ist der Haken: Eine der Eigenschaften ist eine Sammlung von unseren einheimischen Objekten. Er mag die Sammlung Editor für diese Sammlung.

Ich weiß, ich kann meine eigene Sammlung Editor bauen. Aber gibt es eine saubere, einfache Lösung mir ein paar Stunden der Kodierung zu speichern, so dass ich erstellen und eine Sammlung Editor direkt ohne Verwendung der Eigenschaftenraster verwenden kann?

War es hilfreich?

Lösung

Sie können diese Funktionalität von der UITypeEditor erhalten (via TypeDescriptor), aber es ist nicht trivial - Sie brauchen eine IServiceProvider einzurichten, eine IWindowsFormsEditorService und idealerweise eine ITypeDescriptorContext - ziemlich viel faff. Es könnte einfacher sein, es von Hand zu tun, wenn Sie nicht vertraut mit diesen Werkzeugen sind.

Als Alternative - einen Blick auf SmartPropertyGrid.NET , eine Alternative zu PropertyGrid.


Update: Hier ist ein funktionierendes Beispiel ... definitiv nicht-trivial, aber fühlen Sie sich frei, den Code zu stehlen. Es funktioniert nur für modal-Editoren, nicht Drop-Down. Es ist auch kein gutes Beispiel für „Trennung von Bedenken“. Die MyHelper Klasse ist das interessant.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing.Design;
using System.Windows.Forms;
using System.Windows.Forms.Design;
class Foo
{
    public Foo() { Bars = new List<Bar>(); }
    public List<Bar> Bars { get; private set; }
}
class Bar
{
    public string Name { get; set; }
    public DateTime DateOfBirth { get; set; }
}
static class Program
{
    [STAThread]
    static void Main()
    {
        Foo foo = new Foo();
        Bar bar = new Bar();
        bar.Name = "Fred";
        bar.DateOfBirth = DateTime.Today;
        foo.Bars.Add(bar);
        Application.EnableVisualStyles();
        using(Form form = new Form())
        using (Button btn = new Button())
        {
            form.Controls.Add(btn);
            btn.Text = "Edit";
            btn.Click += delegate
            {
                MyHelper.EditValue(form, foo, "Bars");
            };
            Application.Run(form);
        }
    }
}

class MyHelper : IWindowsFormsEditorService, IServiceProvider, ITypeDescriptorContext
{
    public static void EditValue(IWin32Window owner, object component, string propertyName) {
        PropertyDescriptor prop = TypeDescriptor.GetProperties(component)[propertyName];
        if(prop == null) throw new ArgumentException("propertyName");
        UITypeEditor editor = (UITypeEditor) prop.GetEditor(typeof(UITypeEditor));
        MyHelper ctx = new MyHelper(owner, component, prop);
        if(editor != null && editor.GetEditStyle(ctx) == UITypeEditorEditStyle.Modal)
        {
            object value = prop.GetValue(component);
            value = editor.EditValue(ctx, ctx, value);
            if (!prop.IsReadOnly)
            {
                prop.SetValue(component, value);
            }
        }
    }
    private readonly IWin32Window owner;
    private readonly object component;
    private readonly PropertyDescriptor property;
    private MyHelper(IWin32Window owner, object component, PropertyDescriptor property)
    {
        this.owner = owner;
        this.component = component;
        this.property = property;
    }
    #region IWindowsFormsEditorService Members

    public void CloseDropDown()
    {
        throw new NotImplementedException();
    }

    public void DropDownControl(System.Windows.Forms.Control control)
    {
        throw new NotImplementedException();
    }

    public System.Windows.Forms.DialogResult ShowDialog(System.Windows.Forms.Form dialog)
    {
        return dialog.ShowDialog(owner);
    }

    #endregion

    #region IServiceProvider Members

    public object GetService(Type serviceType)
    {
        return serviceType == typeof(IWindowsFormsEditorService) ? this : null;
    }

    #endregion

    #region ITypeDescriptorContext Members

    IContainer ITypeDescriptorContext.Container
    {
        get { return null; }
    }

    object ITypeDescriptorContext.Instance
    {
        get { return component; }
    }

    void ITypeDescriptorContext.OnComponentChanged()
    {}

    bool ITypeDescriptorContext.OnComponentChanging()
    {
        return true;
    }

    PropertyDescriptor ITypeDescriptorContext.PropertyDescriptor
    {
        get { return property; }
    }

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