0

I'm trying to write a form theme class library to adjust the form layout in a simple way for any project I'll be working on.
This is basically an idea of what it should look like:

http://www.beaverdistrict.nl/form_layout.png

In essence, the plugin works as follows:

// form class, which inherits the plugin class
class FormToTheme : ThemedForm
{
    public FormToTheme()
    {
        // some code here
    }
}

// plugin class itself
class ThemedForm: Form
{
    public ThemedForm()
    {
        // some code here
    }
}

Basically I set the FormBorderStyle to None, and drew the layout by code.
But now, the controls that are added can be placed over the custom titlebar, which isn't possible in a normal form if you keep the default FormBorderStyle. So I figured that I could work around this by automatically adding the controls to the content panel, instead of the usercontrol.

So what I tried to do was this:

private void ThemedForm_ControlAdded(Object sender, ControlEventArgs e)
{
    // some simple code to set the control to the current theme I'm using
    e.Control.BackColor = Color.FromArgb(66, 66, 66);
    e.Control.ForeColor = Color.White;

    // the code where I try to place the control in the contentPanel controls array, 
    // and remove it from it's parent's controls array.
    if (e.Control.Name != contentPanel.Name)
    {
        e.Control.Parent.Controls.Remove(e.Control);
        contentPanel.Controls.Add(e.Control);
    }
}

But when I try to add a new control in the main form as well as in the visual editor, i get the following error:

child is not a child control of this parent

So my question is: is there a way to work around this error, and move the controls from the usercontrol to the content panel?
Note that I do want this to be automated in the ThemedForm class, instead of calling methods from the main form.

EDIT:
I tried this:
http://forums.asp.net/t/617980.aspx
But that will only cause visual studio to freeze, and then I need to restart.

4

1 回答 1

2

我知道回答自己的问题并不合适,但是我想出的解决方案需要一些解释,这对于通过编辑添加到我的问题中来说太多了。

所以我们开始:

在继承的“ThemedForm”类中,我创建了一个私有变量,以便能够在调用 Controls 属性时返回该变量:

private Controls controls = null;

我将变量设置为 null,因为我需要将变量传递给“ThemedForm”类构造函数中的类。稍后我将创建该类的一个新实例。

然后我创建了一个类来替换 Controls 属性:

public class Controls
{
    private Control contentPanel = null;
    private ThemedForm themedform = null;
    public Controls(ThemedForm form, Control panel)
    {
        contentPanel = panel;
        themedform = form;
    }
    public void Add(Control control)
    {
        if (control != contentPanel)
        {
            contentPanel.Controls.Add(control);
        }
        else
        {
            themedform.Controls_Add(control);
        }
    }
    public void Remove(Control control)
    {
        if (control != contentPanel)
        {
            contentPanel.Controls.Remove(control);
        }
        else
        {
            themedform.Controls_Remove(control);
        }
    }
}

我知道这个类与原始 Controls 属性的所有功能相去甚远,但现在必须这样做,如果你愿意,你可以添加自己的功能。

正如您在 Controls 类的 Add 和 Remove 方法中看到的那样,我尝试确定需要添加的控件是要添加其余控件的内容面板,还是需要添加的任何其他控件被添加到内容面板。

如果控件实际上是内容面板,我将它添加到或从“ThemedForm”类的基类的 Controls 属性中删除,它是一个“Form”类。否则,我只是将控件添加到内容面板的 Controls 属性中。

然后我将 Controls_Add 和 Controls_Remove 方法添加到“ThemedForm”类,以便能够从“ThemedForm”基类的 Controls 属性中添加或删除控件。

public void Controls_Add(Control control)
{
    base.Controls.Add(control);
}
public void Controls_Remove(Control control)
{
    base.Controls.Remove(control);
}

它们是不言自明的。

为了从外部类调用 Controls.Add 或 Controls.Remove 方法,我需要添加一个隐藏当前 Controls 属性的公共属性,并返回我分配给替换类的私有变量。

new public Controls Controls
{
    get { return controls; }
}

最后,我创建了一个 Controls 类的新实例,传递了当前的“ThemedForm”类和 contentPanel 控件,以使其全部运行。

_controls = new Controls(this, contentPanel);

完成所有这些操作后,我能够将添加到 UserControl(甚至在可视化编辑器中)的任何控件“重定向”到内容面板。这允许我使用任何控件的 Dock 属性,它会停靠在内容面板内,而不是停靠在我的整个表单上。

这仍然有点问题,因为在可视化编辑器中,停靠的控件似乎仍然停靠在整个表单上,但是在运行应用程序时,结果是我想要的。

我真的希望这对任何人都有帮助。

于 2012-08-31T05:25:20.717 回答