2

以下类(Windows 窗体控件)是一种列表控件,ListControlItem不继承任何 Windows 控件类。

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 尝试将列表内容序列化到表单的资源文件中,而不是创建用于实例化每个项目的代码,然后像使用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});

我试图搜索ListViewListViewItem解决这个问题, 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可以提供帮助。

4

1 回答 1

1

有必要TypeConverter为该类实现一个。这样TypeConverter做只是返回类的构造函数描述符。

此外,TypeConverter使用参数指定类的[TypeConverter(typeof(typeConverter))]

根据 MSDN How to: Implement a Type Converter in this case,更具体地说,是在运行时为属性初始化生成代码的类型转换器上。

.NET Framework 提供了在设计时生成动态属性初始化代码的能力,该代码将在运行时初始化属性。

开发人员可以构建一个生成基于构造函数的初始化代码的类型转换器。这些类型转换器可以使用在设计时设置的值动态生成构造函数代码,以便在运行时配置类型的属性。类型转换器实现了为属性配置构造函数的类型和值的逻辑。

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

如果您需要生成除构造函数之外的代码来初始化属性,则可以通过实现自定义 CodeDomSerializer 并应用 DesignerSerializerAttribute 将类型的 CodeDomSerializer 与该类型相关联来动态生成代码。这种方法通常仅用于组件初始化的动态控制或自定义代码生成很重要的场景。有关此方法的更多信息,请参阅 CodeDomSerializer 的文档。

也就是说,使用 answer 方法时,需要在构造函数参数上传递属性值。如果还不够(比如在构造函数上设置属性),那么可能需要CodeDomSerializer像@Octopoid 所说的那样使用。

于 2015-01-28T20:10:03.113 回答