如果控件已添加到我的 UserControl ControlsCollection,如何获得指示?

how to get an indication if a control was added to my UserControl ControlsCollection?

我有一个用户控件,在紧凑的框架中就像一个面板, 我需要在其上实施 AutoSizeMode 。 我已经编写了计算内部所有控件大小所需的代码,一切正常。

我唯一的问题是我没有任何关于何时从我的 UserControl 添加或删除控件的指示。

目前,我已经在我的 UserControl 中添加了一个方法来添加控件并在需要时调整用户控件的大小,但这会强制使用此 UserControl 的任何人通过此方法而不是标准 Controls.Add

另外,我不知道如何在调整内部控件大小时获得指示(尽管在可预见的未来不会发生这种情况,所以不那么重要)。(感谢 tcarvin 指出监听内部控件调整大小事件的简单解决方案)

这是我当前的代码:

protected void AutoGrow()
{
    if (this.AutoGrowMode != AutoGrowMode.None)
    {
        Size ContentSize = CalculateContentSize();
        int newWidth = this.Size.Width,
            newHeight = this.Size.Height;

        if ((this.AutoGrowMode & AutoGrowMode.Width) == AutoGrowMode.Width && this.Size.Width < ContentSize.Width)
        {
            newWidth = Math.Max(this.Size.Width, ContentSize.Width) + _margin * 2;
        }
        if ((this.AutoGrowMode & AutoGrowMode.Height) == AutoGrowMode.Height && this.Size.Height < ContentSize.Height)
        {
            newHeight = Math.Max(this.Size.Height, ContentSize.Height) + _margin * 2;
        }
        this.Size = new Size(newWidth, newHeight);
        this.Invalidate();
    }
}

protected Size CalculateContentSize()
{
    int MaxBottom = 0,
        MaxRight = 0;
    foreach (Control c in this.Controls)
    {
        MaxBottom = (MaxBottom < c.Bottom) ? c.Bottom : MaxBottom;
        MaxRight = (MaxRight < c.Right) ? c.Right : MaxRight;
    }
    return new Size(MaxRight, MaxBottom);
}

public void AddControl(Control value)
{
    this.Controls.Add(value);
    value.Resize += new EventHandler(ChildControl_Resize);
    AutoGrow();
}

private void ChildControl_Resize(object sender, EventArgs e)
{
    AutoGrow();
}

您可以提供自己的 Controls collection,方法是将其添加到您的 UserControl 代码中:

    protected override ControlCollection CreateControlsInstance()
    {
        ObservableControlCollection controls = new ObservableControlCollection(this);
        controls.ControlAdded += new Action<Control>(controls_ControlAdded);
        return controls;
    }

    void controls_ControlAdded(Control addedControl)
    {
        Debug.WriteLine("Control added:" + addedControl.Name);
    }

    private sealed class ObservableControlCollection : ControlCollection
    {
        public event Action<Control> ControlAdded;

        public ObservableControlCollection(Control owner)
            : base(owner)
        {
        }

        public override void Add(Control control)
        {
            base.Add(control);

            Action<Control> handler = ControlAdded;
            if (handler != null)
            {
                handler(control);
            }
        }

        // Similarly for removing controls:
        public override void Remove(Control value) { ... }
        public override void Clear() { ... }
    }