C#Winforms Designer:如何在设计时复制和粘贴集合?

时间:2016-02-18 23:37:11

标签: c# winforms windows-forms-designer

假设我创建了以下自定义控件:

public class BookshelfControl : Control
{
    [Editor(typeof(ArrayEditor), typeof(UITypeEditor)),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
    public Book[] Books { get; set; }

    ...
}

其中Book是一个简单的自定义类,定义为:

public class Book : Component
{
    public string Author { get; set; }
    public string Genre { get; set; }
    public string Title { get; set; }
}

使用它,我可以轻松编辑Visual Studio设计器中的Books集合。

但是,如果我在设计器中创建一个BookshelfControl实例,然后复制并粘贴,则不会复制Books集合,而是会复制第二个控件第一个控制集合中的项目(例如bookshelfControl1.Book[0]等于bookshelfControl2.Book[0])。

因此,我的问题是,在设计时复制和粘贴控件实例时,如何告诉Visual Studio设计者复制我的Books集合?

2 个答案:

答案 0 :(得分:2)

经过数小时的研究,我相信我已经找到了需要做的工作,以指示设计师在设计时通过复制和粘贴操作来复制收集项目。

BookshelfControl使用自定义设计器类,我可以覆盖ComponentDesigner.Associated components属性。根据{{​​3}}:

  

ComponentDesigner.AssociatedComponents属性表示在复制,拖动或移动操作期间要复制或移动设计器管理的组件的任何组件。

修改后的课程最终成为:

[Designer(typeof(BookshelfControl.Designer))]
public class BookshelfControl : Control
{
    internal class Designer : ControlDesigner
    {
        private IComponent component;

        public override void Initialize(IComponent component)
        {
            base.Initialize(component);
            this.component = component;
        }

        //
        // Critical step getting the designer to 'cache' related object
        // instances to be copied with this BookshelfControl instance:
        //
        public override System.Collections.ICollection AssociatedComponents
        {
            get
            {
                return ((BookshelfControl)this.component).Books;
            }
        }
    }

    [Editor(typeof(ArrayEditor), typeof(UITypeEditor)),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
    public Book[] Books { get; set; }

    ...
}

AssociatedComponents属性的结果为设计器提供了一组对象(可以是嵌套控件,其他对象,基元,等。),这些对象被复制到剪贴板中被粘贴在其他地方。

在测试中,我确定在设计时发出复制命令(AssociatedComponents)后立即读取CTRL + C属性。

我希望这有助于其他人想要节省时间来追踪这个相当模糊的功能!

答案 1 :(得分:1)

我的答案解决了你的问题,除非你有很多东西。 您不应该从Book继承Component。 只需使用:

    [Serializable]
    public class Book 
    {

        public string Author { get; set; }

        public string Genre { get; set; }

        public string Title { get; set; }
    }

我测试了它并且它正常工作。 如果您确实想要使用Component,则应创建自定义EditorAttribute class