PropertyGrid - Proprietà derivata da Ilist , come posso aggiungere a PropertyGrid in modo che l'utente possa aggiungere/modificare/rimuovere gli elementi

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

Domanda

Vorrei fornire un po 'di storia su come ho raggiunto questo punto.

Inizialmente avevo una proprietà all'interno della mia classe che derivava da collezioni basate e avevo questa raccolta mappato a PropertyGrid e l'utente poteva aggiungere/modificare/rimuovere gli elementi dall'elenco a piacimento.

Tuttavia, non sono riuscito a mappare la base di raccolte con NHibernate, quindi ho dovuto eliminare la mia implementazione iniziale e invece di derivare dalla base di raccolte, ho avuto la classe derivante da Ilist.

Ora posso mappare su Nhibernate, ma non sono in grado di modificare la raccolta tramite PropertyGrid.

Ho bisogno di un po 'di aiuto per far giocare bene i 2.

Nella mia classe principale ho una proprietà definita come:

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

La mia collezione di zone che eredita ilist è definita come segue:

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

}

Ora, il mio icustomtypedescriptor e la proprietàDescriptor hanno funzionato bene quando questa classe derivava da raccolte basi, ma ora mostra solo il nome di classe zonecollection nel nome della proprietà senza il pulsante "..." per aggiungere/modificare/rimuovere gli elementi dall'elenco.

Cosa sto facendo di sbagliato ora che è ereditato da Ilist che non funziona?

Se aggiungo:

[TypeConverter(typeof(ExpandableObjectConverter))]

All'inizio della Zonecollection, ottengo gli articoli nell'elenco elencati in un albero espandibile, ma non è quello che sto cercando. Dove è andato il pulsante "..." che ha aperto una finestra popup che mi ha permesso di aggiungere/modificare/rimuovere gli elementi nella raccolta quando ho ereditato da Ilist anziché collectionbase?

Nessuna soluzione corretta

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top