以下类(Windows窗体控件)是一种列表控件,
并且ListControlItem
不继承任何Windows Control类。
public class ListControl : Control
{
private List<ListControlItem> items;
public ListControl()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose(disposing);
}
void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.items = new List<ListControlItem>();
}
public List<ListControlItem> Items
{
get { return items; }
set { items = value; }
}
}
问题是,在设计时,Visual Studio尝试将列表内容序列化为Form的资源文件,而不是创建用于实例化每个项目的代码,然后像ListView
一样添加到控件中。 ListViewItem
。
Visual Studio设计为ListControl
生成代码:
this.listControl1.Items = ((System.Collections.Generic.List<ListControlItem>)(resources.GetObject("listControl1.Items")));
ListView
:
System.Windows.Forms.ListViewItem listViewItem1 = new System.Windows.Forms.ListViewItem("");
System.Windows.Forms.ListViewItem listViewItem2 = new System.Windows.Forms.ListViewItem("");
System.Windows.Forms.ListViewItem listViewItem3 = new System.Windows.Forms.ListViewItem("");
System.Windows.Forms.ListViewItem listViewItem4 = new System.Windows.Forms.ListViewItem("");
System.Windows.Forms.ListViewItem listViewItem5 = new System.Windows.Forms.ListViewItem("");
System.Windows.Forms.ListViewItem listViewItem6 = new System.Windows.Forms.ListViewItem("");
this.listView1.Items.AddRange(new System.Windows.Forms.ListViewItem[] {
listViewItem1,
listViewItem2,
listViewItem3,
listViewItem4,
listViewItem5,
listViewItem6});
我尝试搜索ListView
和ListViewItem
来解决问题,
ListView
有一个名为ListViewItemCollection
的“自己的列表类”,它实现了接口IList, ICollection, IEnumerable
,但List<T>
实现了相同的接口。
我是否需要为它实现自定义序列化?也许这只是序列化到资源文件。我找不到太多文档,因为它没有继承任何Windows窗体控件基类。
更新
将属性[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
放在List<T>
属性中为每个List<T>
项提供一个资源。
this.listControl1.Items.Add(((ListControlItem)(resources.GetObject("listControl1.Items"))));
this.listControl1.Items.Add(((ListControlItem)(resources.GetObject("listControl1.Items1"))));
this.listControl1.Items.Add(((ListControlItem)(resources.GetObject("listControl1.Items2"))));
this.listControl1.Items.Add(((ListControlItem)(resources.GetObject("listControl1.Items3"))));
this.listControl1.Items.Add(((ListControlItem)(resources.GetObject("listControl1.Items4"))));
this.listControl1.Items.Add(((ListControlItem)(resources.GetObject("listControl1.Items5"))));
就像为ListControlItem
实现自定义序列化一样可以提供帮助。
答案 0 :(得分:1)
有必要为班级实施TypeConverter
。这个TypeConverter
做的只是返回类的构造函数描述符。
另外,使用参数TypeConverter
指定班级的[TypeConverter(typeof(typeConverter))]
。
根据MSDN How to: Implement a Type Converter,更具体地说,是在运行时生成属性初始化代码的类型转换器。
.NET Framework提供了生成动态的功能 属性初始化代码在设计时将初始化a 在运行时的财产。
开发人员可以构建一个生成基于构造函数的类型转换器 初始化代码。这些类型转换器可以生成构造函数 使用在设计时设置的值动态编码以进行配置 运行时类型的属性。类型转换器实现了 用于配置构造函数的类型和值的逻辑 属性。
Visual Studio设计器的结果代码
this.listControl1.Items.Add(new ListControlItem());
this.listControl1.Items.Add(new ListControlItem());
this.listControl1.Items.Add(new ListControlItem());
this.listControl1.Items.Add(new ListControlItem());
this.listControl1.Items.Add(new ListControlItem());
this.listControl1.Items.Add(new ListControlItem());
TypeConverter
只返回一个无参数构造函数,但可以在TypeConverter
代码中更改。
关于CodeDomSerializer
如果除了构造函数之外还需要生成代码来初始化a 属性,可以通过实现动态生成代码 自定义CodeDomSerializer并应用DesignerSerializerAttribute 将CodeDomSerializer与类型相关联的类型。这个 方法通常仅用于动态的场景 用于组件初始化的受控或定制代码生成 很重要有关此方法的更多信息,请参阅 CodeDomSerializer的文档。
也就是说,使用answer方法,需要在构造函数参数上传递属性值。如果还不够(比如设置属性不在构造函数上),则可能需要使用CodeDomSerializer
,如@Octopoid所说。