Collection<T>
我正在尝试制作一个带有 a作为属性的 WinForms 用户控件(其中 T 代表一些自定义类)。我已经阅读了很多关于这个主题的内容,但是我不能让它在设计时正常工作(在运行时一切正常)。更准确地说:当我单击属性窗口中的“...”按钮时,集合编辑器显示正常,我可以添加和删除项目。但是当我单击 OK 按钮时,什么也没有发生,当我重新打开集合编辑器时,所有项目都丢失了。当我查看设计器文件时,我看到我的属性被分配为 null,而不是组合集合。我将向您展示最重要的代码:
用户控制:
[Browsable(true),
Description("The different steps displayed in the control."),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
Editor(typeof(CustomCollectionEditor), typeof(UITypeEditor))]
public StepCollection Steps
{
get
{
return wizardSteps;
}
set
{
wizardSteps = value;
UpdateView(true);
}
}
StepCollection 类:
public class StepCollection : System.Collections.CollectionBase
{
public StepCollection() : base() { }
public void Add(Step item) { List.Add(item); }
public void Remove(int index) { List.RemoveAt(index); }
public Step this[int index]
{
get { return (Step)List[index]; }
}
}
阶梯类:
[ToolboxItem(false),
DesignTimeVisible(false),
Serializable()]
public class Step : Component
{
public Step(string name) : this(name, null, StepLayout.DEFAULT_LAYOUT){ }
public Step(string name, Collection<Step> subSteps) : this(name, subSteps, StepLayout.DEFAULT_LAYOUT){ }
public Step(string name, Collection<Step> subSteps, StepLayout stepLayout)
{
this.Name = name;
this.SubSteps = subSteps;
this.Layout = stepLayout;
}
// In order to provide design-time support, a default constructor without parameters is required:
public static int NEW_ITEM_ID = 1;
public Step()
: this("Step" + NEW_ITEM_ID, null, StepLayout.DEFAULT_LAYOUT)
{
NEW_ITEM_ID++;
}
// Some more properties
}
自定义集合编辑器:
class CustomCollectionEditor : CollectionEditor
{
private ITypeDescriptorContext mContext;
public CustomCollectionEditor(Type type) : base(type) { }
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
{
mContext = context;
return base.EditValue(context, provider, value);
}
protected override object CreateInstance(Type itemType)
{
if (itemType == typeof(Step))
{
Step s = (Step)base.CreateInstance(itemType);
s.parentContext = mContext; // Each step needs a reference to its parentContext at design time
return s;
}
return base.CreateInstance(itemType);
}
}
我已经尝试过的事情:
- 使 Step 类成为此处所述的组件:http: //www.codeproject.com/Articles/5372/How-to-Edit-and-Persist-Collections-with-Collectio
- 更改
Collection<Step>
为继承 System.Collections.CollectionBase 的自定义集合类StepCollection
(在之前的代码项目文章中也有描述) - 将 DesignerSerializationVisibility 设置为 Content,如下所述:设计时用户控件中的集合编辑器当它设置为 Visible 时,设计器将 null 分配给我的属性;当它设置为内容时,设计者什么也不分配。
- 我还发现了这个:如何使用可以在设计时编辑的集合制作用户控件?但是 CollectionBase 类已经为我做了这个。
- 调试了很多,但由于没有例外,我真的不知道出了什么问题。当我向 collectionForm 的关闭事件添加事件侦听器时,即使我在集合编辑器中添加了几个步骤,我也可以看到(collectionForm 的)EditValue 属性仍然为空。但我也不知道这是为什么...
完成这篇文章时,我刚刚发现了这个主题:在设计模式中编辑集合的最简单方法? 这与我遇到的问题完全相同,但是我不能使用建议的答案,因为我不使用标准集合。