PropertyGrid - Propriété dérivée d'Ilist , comment puis-je ajouter à la propriété pour que l'utilisateur puisse ajouter / modifier / supprimer les éléments

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

Question

Permettez-moi de fournir un peu d'histoire sur la façon dont j'ai atteint ce point.

J'avais à l'origine une propriété au sein de ma classe qui dérive de CollectionsBase et avait cette collection mappée sur PropertyGrid et l'utilisateur pourrait ajouter / modifier / supprimer les éléments de la liste à volonté.

Cependant, je n'ai pas pu cartographier la base de collections avec Nhibernate, donc j'ai dû supprimer mon implémentation initiale et au lieu de dériver de la base de collections, j'ai eu la classe dérivée d'Ilist.

Maintenant, je peux mapper pour nhibernate, mais je ne suis pas en mesure de modifier la collection via la propriété.

J'ai besoin d'aide pour que le 2 joue bien entre eux.

Dans ma classe principale, j'ai une propriété définie comme:

    public virtual ZoneCollection Zones
    {
        get { return zones; }
        set { zones = value; }
    }

Ma collection de zone qui hérite d'Ilist est définie comme suit:

public class ZoneCollection : IList<Zone>, ICustomTypeDescriptor
{
    private IList<Zone> _list;

    public IList<Zone> _List
    {
        get { return _list; }
    }

    public ZoneCollection()
    {
        _list = new List<Zone>();
    }

    #region Implementation of IEnumerable

    public IEnumerator<Zone> GetEnumerator()
    {
        return _list.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

    #endregion

    #region Implementation of ICollection<Zone>

    public void Add(Zone item)
    {
        _list.Add(item);
    }

    public void Clear()
    {
        _list.Clear();
    }

    public bool Contains(Zone item)
    {
        return _list.Contains(item);
    }

    public void CopyTo(Zone[] array, int arrayIndex)
    {
        _list.CopyTo(array, arrayIndex);
    }

    public bool Remove(Zone item)
    {
        return _list.Remove(item);
    }

    public int Count
    {
        get { return _list.Count; }
    }

    public bool IsReadOnly
    {
        get { return false; }
    }

    #endregion

    #region Implementation of IList<Zone>

    public int IndexOf(Zone item)
    {
        return _list.IndexOf(item);
    }

    public void Insert(int index, Zone item)
    {
        _list.Insert(index, item);
    }

    public void RemoveAt(int index)
    {
        _list.RemoveAt(index);
    }

    public Zone this[int index]
    {
        get { return (Zone)_list[index]; }
        set { _list[index] = value; }
    }

    #endregion

    // Implementation of interface ICustomTypeDescriptor 
    #region ICustomTypeDescriptor impl

    public String GetClassName()
    {
        return TypeDescriptor.GetClassName(this, true);
    }

    public AttributeCollection GetAttributes()
    {
        return TypeDescriptor.GetAttributes(this, true);
    }

    public String GetComponentName()
    {
        return TypeDescriptor.GetComponentName(this, true);
    }

    public TypeConverter GetConverter()
    {
        return TypeDescriptor.GetConverter(this, true);
    }

    public EventDescriptor GetDefaultEvent()
    {
        return TypeDescriptor.GetDefaultEvent(this, true);
    }

    public PropertyDescriptor GetDefaultProperty()
    {
        return TypeDescriptor.GetDefaultProperty(this, true);
    }

    public object GetEditor(Type editorBaseType)
    {
        return TypeDescriptor.GetEditor(this, editorBaseType, true);
    }

    public EventDescriptorCollection GetEvents(Attribute[] attributes)
    {
        return TypeDescriptor.GetEvents(this, attributes, true);
    }

    public EventDescriptorCollection GetEvents()
    {
        return TypeDescriptor.GetEvents(this, true);
    }

    public object GetPropertyOwner(PropertyDescriptor pd)
    {
        return this;
    }


    /// <summary>
    /// Called to get the properties of this type. Returns properties with certain
    /// attributes. this restriction is not implemented here.
    /// </summary>
    /// <param name="attributes"></param>
    /// <returns></returns>
    public PropertyDescriptorCollection GetProperties(Attribute[] attributes)
    {
        return GetProperties();
    }

    /// <summary>
    /// Called to get the properties of this type.
    /// </summary>
    /// <returns></returns>
    public PropertyDescriptorCollection GetProperties()
    {
        // Create a collection object to hold property descriptors
        PropertyDescriptorCollection pds = new PropertyDescriptorCollection(null);

        // Iterate the list of zones
        for (int i = 0; i < this._list.Count; i++)
        {
            // Create a property descriptor for the zone item and add to the property descriptor collection
            ZoneCollectionPropertyDescriptor pd = new ZoneCollectionPropertyDescriptor(this, i);
            pds.Add(pd);
        }
        // return the property descriptor collection
        return pds;
    }

    #endregion
}

/// <summary>
/// Summary description for CollectionPropertyDescriptor.
/// </summary>
public class ZoneCollectionPropertyDescriptor : PropertyDescriptor
{
    private ZoneCollection collection = null;
    private int index = -1;

    public ZoneCollectionPropertyDescriptor(ZoneCollection coll, int idx) :
        base("#" + idx.ToString(), null)
    {
        this.collection = coll;
        this.index = idx;
    }

    public override AttributeCollection Attributes
    {
        get
        {
            return new AttributeCollection(null);
        }
    }

    public override bool CanResetValue(object component)
    {
        return true;
    }

    public override Type ComponentType
    {
        get
        {
            return this.collection.GetType();
        }
    }

    public override string DisplayName
    {
        get
        {
            Zone zone = this.collection[index];
            return zone.ID.ToString();
        }
    }

    public override string Description
    {
        get
        {
            Zone zone = this.collection[index];
            StringBuilder sb = new StringBuilder();
            sb.Append(zone.ID.ToString());

            if (zone.Streets.Route != String.Empty || zone.Streets.Crossing != String.Empty)
                sb.Append("::");
            if (zone.Streets.Route != String.Empty)
                sb.Append(zone.Streets.Route);
            if (zone.Streets.Crossing != String.Empty)
            {
                sb.Append(" and ");
                sb.Append(zone.Streets.Crossing);
            }

            return sb.ToString();
        }
    }

    public override object GetValue(object component)
    {
        return this.collection[index];
    }

    public override bool IsReadOnly
    {
        get { return false; }
    }

    public override string Name
    {
        get { return "#" + index.ToString(); }
    }

    public override Type PropertyType
    {
        get { return this.collection[index].GetType(); }
    }

    public override void ResetValue(object component)
    {
    }

    public override bool ShouldSerializeValue(object component)
    {
        return true;
    }

    public override void SetValue(object component, object value)
    {
        // this.collection[index] = value;
    }
}

}

Maintenant, mon iCustomTypeDescriptor et PropertyDescriptor ont bien fonctionné lorsque cette classe dérive de CollectionsBase, mais maintenant il affiche simplement le nom de classe ZonEcollection dans le nom de la propriété sans le bouton "..." pour ajouter / modifier / supprimer les éléments de la liste.

Qu'est-ce que je fais de mal maintenant qu'il est hérité d'Ilist que cela ne fonctionne pas?

Si j'ajoute:

[TypeConverter(typeof(ExpandableObjectConverter))]

Au début de la zonecollection, j'obtiens les éléments de la liste répertoriés dans un arbre extensible, mais ce n'est pas ce que je recherche. Où est allé le bouton "..." qui a ouvert une fenêtre contextuelle qui m'a permis d'ajouter / modifier / supprimer les éléments de la collection lorsque j'ai hérité d'ILIST au lieu de CollectionBase?

Pas de solution correcte

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