我有一个用户控件,其属性是自定义对象类型的列表。当我通过继承List<>来创建自定义类时,它主要起作用:
public class CustomCol : List<CustomItem> {
// ...
}
然后我可以在用户控件中实现这样的属性:
CustomCol _items = new CustomCol();
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public CustomCol Items
{
get { return _items; }
}
这使它的行为与我期望的一样。我可以单击Designer中的省略号按钮,它会调出CollectionEditor,正确添加项目会添加CustomItems。
不幸的是,此方法不允许我检测何时在CollectionEditor中添加,删除或修改项目。经过大量研究后,我发现这是因为设计器编辑器调用IList.Add()来添加新项目,这是不可覆盖的,所以我不能在没有实现我自己的集合类的情况下拦截这些调用来实现IList。
这正是我试图做的事情。我尝试的代码看起来像这样:
public class CustomCol: System.Collections.IList
{
private List<CustomItem> = new List<CustomItem>();
int System.Collections.IList.Add(Object value)
{
_items.Add((CustomItem)value);
return _items.Count;
}
// All of the other IList methods are similarly implemented.
}
在继续之前,我已经看到了一个问题。 CollectionEditor将传递通用的System.Objects,而不是我的CustomItem类。
所以接下来我尝试的是实现IList,因此:
public class CustomCol: IList<CustomClass>
{
private List<CustomItem> = new List<CustomItem>();
void ICollection<CustomItem>.Add(NameValueItem item)
{
_items.Add(item);
}
// All of the other IList methods are similarly implemented.
}
理论上,这是有效的,但我无法让CollectionEditor在设计师中启动。我一整天都在努力,在网上寻找解决方案,试图了解这一切是如何运作的。在这一点上,我非常头痛,正在寻找任何指导。
总结一下:我想创建一个具有属性的用户控件,该属性是我可以使用CollectionEditor(或类似的东西)在Designer中编辑的自定义集合类,我需要知道何时进行这些设计器更改以便我可以更新控件的外观。
答案 0 :(得分:1)
您可以按照框架集合的方式实现自定义集合。不要看太多。
像往常一样实现非通用IList,但将实现的方法设为私有。然后为每个实现的方法添加另一个公共方法,但这次这些公共方法将接受您想要的自定义类型。将使用类型转换从已实现的私有方法调用这些方法。
这是框架集合遵循的方式。看看UIElementCollection课程。您将看到完全相同的实现。
IList.Add方法的示例:
假设自定义类名为TextElement
。
private int IList.Add(object value)
{
return Add((TextElement)value);
}
public int Add(TextElement element)
{
[Your custom logic here]
}
编辑:
您不能使用私有方法隐式实现接口。你必须明确这样做。例如,您需要执行private int IList.Add
代替private int Add
,private void ICollection.CopyTo
代替private void CopyTo
才能使所有这些工作。