【问题标题】:custom collection in property grid属性网格中的自定义集合
【发布时间】:2011-01-04 12:04:42
【问题描述】:

我使用这篇文章作为在 propertygrid 中使用自定义集合的参考: LINK

当我打开集合编辑器并删除所有项目然后按确定时,如果为 null,则会出现异常。

我该如何解决?
我正在使用:

public T this[int index]
{
   get
   {
      if (List.Count == 0)
      {
         return default(T);
      }
      else
      {
         return (T)this.List[index];
      }
   }
}

作为一个项目的吸气剂,当然,如果我没有对象,我如何重新启动整个集合?

这是整个代码

/// <summary>
/// A generic folder settings collection to use in a property grid.
/// </summary>
/// <typeparam name="T">can be import or export folder settings.</typeparam>
[Serializable]
[TypeConverter(typeof(FolderSettingsCollectionConverter)), Editor(typeof(FolderSettingsCollectionEditor), typeof(UITypeEditor))]
public class FolderSettingsCollection_New<T> : CollectionBase, ICustomTypeDescriptor
{
    private bool m_bRestrictNumberOfItems;
    private int m_bNumberOfItems;
    private Dictionary<string, int> m_UID2Idx = new Dictionary<string, int>();
    private T[] arrTmp;

    /// <summary>
    /// C'tor, can determine the number of objects to hold.
    /// </summary>
    /// <param name="bRestrictNumberOfItems">restrict the number of folders to hold.</param>
    /// <param name="iNumberOfItems">The number of folders to hold.</param>
    public FolderSettingsCollection_New(bool bRestrictNumberOfItems = false , int iNumberOfItems = 1)
    {
        m_bRestrictNumberOfItems = bRestrictNumberOfItems;
        m_bNumberOfItems = iNumberOfItems;
    }

    /// <summary>
    /// Add folder to collection.
    /// </summary>
    /// <param name="t">Folder to add.</param>
    public void Add(T t)
    {
        if (m_bRestrictNumberOfItems)
        {
            if (this.List.Count >= m_bNumberOfItems)
            {
                return;
            }
        }

        int index = this.List.Add(t);

        if (t is WriteDataFolderSettings || t is ReadDataFolderSettings)
        {
            FolderSettingsBase tmp = t as FolderSettingsBase;
            m_UID2Idx.Add(tmp.UID, index);
        }
    }

    /// <summary>
    /// Remove folder to collection.
    /// </summary>
    /// <param name="t">Folder to remove.</param>
    public void Remove(T t)
    {
        this.List.Remove(t);

        if (t is WriteDataFolderSettings || t is ReadDataFolderSettings)
        {
            FolderSettingsBase tmp = t as FolderSettingsBase;
            m_UID2Idx.Remove(tmp.UID);
        }
    }

    /// <summary>
    /// Gets ot sets a folder.
    /// </summary>
    /// <param name="index">The index of the folder in the collection.</param>
    /// <returns>A folder object.</returns>
    public T this[int index]
    {
        get
        {
            //if (List.Count == 0)
            //{
            //   return default(T);
            //}
            //else
            //{
                return (T)this.List[index];
            //}
        }
    }

    /// <summary>
    /// Gets or sets a folder.
    /// </summary>
    /// <param name="sUID">The UID of the folder.</param>
    /// <returns>A folder object.</returns>
    public T this[string sUID]
    {
        get
        {
            if (this.Count == 0 || !m_UID2Idx.ContainsKey(sUID))
            {
                return default(T);
            }
            else
            {
                return (T)this.List[m_UID2Idx[sUID]];
            }
        }
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="sUID"></param>
    /// <returns></returns>
    public bool ContainsItemByUID(string sUID)
    {
        return m_UID2Idx.ContainsKey(sUID);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    public String GetClassName()
    {
        return TypeDescriptor.GetClassName(this, true);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    public AttributeCollection GetAttributes()
    {
        return TypeDescriptor.GetAttributes(this, true);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    public String GetComponentName()
    {
        return TypeDescriptor.GetComponentName(this, true);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    public TypeConverter GetConverter()
    {
        return TypeDescriptor.GetConverter(this, true);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    public EventDescriptor GetDefaultEvent()
    {
        return TypeDescriptor.GetDefaultEvent(this, true);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    public PropertyDescriptor GetDefaultProperty()
    {
        return TypeDescriptor.GetDefaultProperty(this, true);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="editorBaseType"></param>
    /// <returns></returns>
    public object GetEditor(Type editorBaseType)
    {
        return TypeDescriptor.GetEditor(this, editorBaseType, true);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="attributes"></param>
    /// <returns></returns>
    public EventDescriptorCollection GetEvents(Attribute[] attributes)
    {
        return TypeDescriptor.GetEvents(this, attributes, true);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    public EventDescriptorCollection GetEvents()
    {
        return TypeDescriptor.GetEvents(this, true);
    }


    /// <summary>
    /// 
    /// </summary>
    /// <param name="pd"></param>
    /// <returns></returns>
    public object GetPropertyOwner(PropertyDescriptor pd)
    {
        return this;
    }

    /// <summary>
    /// 
    /// </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 employees
        for (int i = 0; i < this.List.Count; i++)
        {
            // Create a property descriptor for the employee item and add to the property descriptor collection
            CollectionPropertyDescriptor_New<T> pd = new CollectionPropertyDescriptor_New<T>(this, i);
            pds.Add(pd);
        }
        // return the property descriptor collection
        return pds;
    }

    public T[] ToArray()
    {
        if (arrTmp == null)
        {
            arrTmp = new T[List.Count];
            for (int i = 0; i < List.Count; i++)
            {
                arrTmp[i] = (T)List[i];
            }
        }

        return arrTmp;
    }

}

/// <summary>
/// Enable to display data about a collection in a property grid.
/// </summary>
/// <typeparam name="T">Folder object.</typeparam>
public class CollectionPropertyDescriptor_New<T> : PropertyDescriptor
{
    private FolderSettingsCollection_New<T> collection = null;
    private int index = -1;
    /// <summary>
    /// 
    /// </summary>
    /// <param name="coll"></param>
    /// <param name="idx"></param>
    public CollectionPropertyDescriptor_New(FolderSettingsCollection_New<T> coll, int idx) : base("#" + idx.ToString(), null)
    {
        this.collection = coll;
        this.index = idx;
    }

    /// <summary>
    /// 
    /// </summary>
    public override AttributeCollection Attributes
    {
        get
        {
            return new AttributeCollection(null);
        }
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="component"></param>
    /// <returns></returns>
    public override bool CanResetValue(object component)
    {
        return true;
    }

    /// <summary>
    /// 
    /// </summary>
    public override Type ComponentType
    {
        get
        {
            return this.collection.GetType();
        }
    }

    /// <summary>
    /// 
    /// </summary>
    public override string DisplayName
    {
        get
        {
            if (this.collection[index] != null)
            {
                return this.collection[index].ToString();
            }
            else
            {
                return null;
            }
        }
    }

    public override string Description
    {
        get
        {
            return "";
        }
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="component"></param>
    /// <returns></returns>
    public override object GetValue(object component)
    {
        if (this.collection[index] != null)
        {
            return this.collection[index];
        }
        else
        {
            return null;
        }
    }

    /// <summary>
    /// 
    /// </summary>
    public override bool IsReadOnly
    {
        get { return false; }
    }

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

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

    public override void ResetValue(object component)
    {

    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="component"></param>
    /// <returns></returns>
    public override bool ShouldSerializeValue(object component)
    {
        return true;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="component"></param>
    /// <param name="value"></param>
    public override void SetValue(object component, object value)
    {
        // this.collection[index] = value;
    }
}

谢谢大家的帮助。

我终于赢了。

当 (index = 0) == null 时,显示名称返回 null。

而不是 String.Empty ...

希望这对你们中的一些人有所帮助

【问题讨论】:

  • 在List为空的情况下,我不会返回T的默认值(如果T是一个类则为null),看起来有点奇怪。无论如何,我想你的问题出在你代码的另一个地方,你能发布更多吗?
  • Mmh...我找不到任何明显的错误(但无法调试它有点困难),所以我建议您逐步调试它(您也可以在设计时间 --> msdn.microsoft.com/en-us/library/5ytx0z24%28v=VS.90%29.aspx)。

标签: c# collections propertygrid


【解决方案1】:

如果你简单地使用你会得到什么:

public T this[int index]
{
   get
   {
      return (T)this.List[index];
   }
}

【讨论】:

  • 如果 this.List[index] 在没有定义项目时为空,我仍然会遇到异常。我有些需要将其恢复到原始状态。
  • 您在 imo 的另一部分代码中存在问题。因为如果列表中没有任何值,您的收藏编辑器不应调用this[index]。也许您在Count 属性和您的内部列表之间存在同步问题...
  • 看起来他的代码中有一个错误 - 如果您在删除项目之前不扩展集合,它会起作用。
猜你喜欢
  • 1970-01-01
  • 2017-11-02
  • 2010-09-27
  • 2018-08-14
  • 1970-01-01
  • 1970-01-01
  • 2014-12-03
  • 2011-01-18
  • 1970-01-01
相关资源
最近更新 更多