扩展可滚动控件的用户控件 - 禁用容器功能

UserControl extending ScrollableControl - disable container functinality

我正在通过扩展 ScrollableControl.
来构建自定义控件 问题是我的自定义控件充当容器 - 我可以将控件拖入其中:

我的问题是如何禁用扩展 ScrollableControl

的 class 中的容器功能

下面是两个测试控件,一个扩展 Control,第二个 ScrollableControl

public class ControlBasedControl : Control
{
    protected override Size DefaultSize
    {
        get { return new Size(100, 100); }
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);
        e.Graphics.FillRectangle(Brushes.LightCoral, ClientRectangle);
    }
}

public class ScrollableControlBasedControl : ScrollableControl
{
    public ScrollableControlBasedControl()
    {
        AutoScrollMinSize = new Size(200, 200);
    }

    protected override Size DefaultSize
    {
        get { return new Size(100, 100); }
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);
        e.Graphics.FillRectangle(Brushes.LawnGreen, ClientRectangle);
    }
}

可能有不止一种方法可以实现这一点,但这是我会做的...

首先创建ControlCollection的只读版本

public class ReadOnlyControlCollection : Control.ControlCollection
{
    public ReadOnlyControlCollection(Control owner)
        : base(owner)
    {
    }

    public override bool IsReadOnly
    {
        get { return true; }
    }

    public override void Add(Control control)
    {
        throw new ArgumentException("control");
    }
}

然后让您的 ScrollableControlBasedControl 创建一个 ReadOnlyControlCollection 的实例,而不是默认的 ControlCollection

public class ScrollableControlBasedControl : ScrollableControl
{
    protected override Control.ControlCollection CreateControlsInstance()
    {
        return new ReadOnlyControlCollection(this);
    }

    // The rest of your class goes here...
}

我使用 Visual Studio 2010,当我将控件放在 ScrollableControlBasedControl 上时,控件会神奇地移回原来的位置,就像操作被取消一样。

您在设计时从 [Designer] 属性获得 "acts-like-a-container" 行为。从 Reference Source:

复制粘贴
[
ComVisible(true),
ClassInterface(ClassInterfaceType.AutoDispatch),
Designer("System.Windows.Forms.Design.ScrollableControlDesigner, " + AssemblyRef.SystemDesign)
]
public class ScrollableControl : Control, IArrangedElement {
   // etc...
}

完成工作的是 ScrollableControlDesigner。本身并没有做太多事情,而是派生自 ParentControlDesigner,该设计器允许控件充当子控件的父控件,并在设计时赋予它类似容器的行为。

修复很容易,您只需将自己的 [Designer] 属性用于 select 另一个设计师。添加对 System.Design 的引用并使其看起来像这样:

using System.Windows.Forms;
using System.Drawing;
using System.ComponentModel;
using System.Windows.Forms.Design; // Add reference to System.Design

[Designer(typeof(ControlDesigner))]
public class ScrollableControlBasedControl : ScrollableControl {
    // etc...
}