C# Winforms Designer:如何在 design-time 处复制和粘贴 collections?

C# Winforms Designer: How to copy and paste collections at design-time?

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

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

    ...
}

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

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

使用它,我可以在 Visual Studio 设计器中轻松编辑 Books collection。

但是,如果我创建一个 BookshelfControl 的实例,然后在设计器中 复制并粘贴 Books collection 不是已复制,但第二个控件引用了第一个控件的 collection 中的所有项目( 例如 bookshelfControl1.Book[0] 等于 bookshelfControl2.Book[0])。

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

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

    [Serializable]
    public class Book 
    {

        public string Author { get; set; }

        public string Genre { get; set; }

        public string Title { get; set; }
    }

我测试了它,它工作正常。 如果你真的想使用 Component 而不是你应该创建一个自定义 EditorAttribute class .

经过数小时的研究,我相信我已经找到了在设计时指示设计人员使用 复制和粘贴 操作复制集合项目需要做的事情.

为我的 BookshelfControl 使用自定义设计器 class,我可以覆盖 ComponentDesigner.Associated 组件 属性。根据the MSDN documentation:

The ComponentDesigner.AssociatedComponents property indicates any components to copy or move along with the component managed by the designer during a copy, drag, or move operation.

修改后的 class 最终为:

[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 属性 的结果为设计者提供了一组对象(可以是嵌套控件、其他对象、基元、) 复制到剪贴板以粘贴到其他地方。

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

我希望这可以帮助其他想要节省时间来追踪这个相当晦涩的功能的人!