0

作業するプロジェクトのフォームレイアウトを簡単な方法で調整するために、フォームテーマクラスライブラリを作成しようとしています。
これは基本的にそれがどのように見えるべきかについての考えです:

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

基本的に、プラグインは次のように機能します。

// 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
    }
}

基本的に、FormBorderStyleをNoneに設定し、コードでレイアウトを描画しました。
ただし、追加されたコントロールをカスタムタイトルバーに配置できるようになりました。これは、デフォルトのFormBorderStyleを保持している場合、通常のフォームでは不可能です。そこで、ユーザーコントロールではなく、コンテンツパネルにコントロールを自動的に追加することで、これを回避できると考えました。

だから私がやろうとしたのはこれでした:

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);
    }
}

しかし、メインフォームとビジュアルエディターで新しいコントロールを追加しようとすると、次のエラーが発生します。

child is not a child control of this parent

だから私の質問は:このエラーを回避し、コントロールをユーザーコントロールからコンテンツパネルに移動する方法はありますか?
メインフォームからメソッドを呼び出すのではなく、ThemedFormクラスでこれを自動化する必要があることに注意してください。

編集:
私はこれを試しました:http:
//forums.asp.net/t/617980.aspx
しかし、それはビジュアルスタジオをフリーズさせるだけであり、それから私は再起動する必要があります。

4

1 に答える 1

2

自分の質問に答えるのはあまり適切ではないことは知っていますが、私が思いついた解決策にはかなりの説明が必要であり、編集して質問に追加するには多すぎます。

だからここに行きます:

継承された'ThemedForm'クラス内に、Controlsプロパティが呼び出されたときに変数を返すことができるように、プライベート変数を作成しました。

private Controls controls = null;

'ThemedForm'クラスコンストラクターのクラスに変数を渡す必要があるため、変数をnullに設定しました。後でクラスの新しいインスタンスを作成します。

次に、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メソッドでわかるように、追加する必要のあるコントロールが、残りのコントロールを追加するコンテンツパネルであるか、その他の必要なコントロールであるかを判断しようとしています。コンテンツパネルに追加されます。

コントロールが実際にコンテンツパネルである場合は、「Form」クラスである「ThemedForm」クラスの基本クラスのControlsプロパティにコントロールを追加または削除します。それ以外の場合は、コンテンツパネルのControlsプロパティにコントロールを追加するだけです。

次に、「ThemedForm」基本クラスのControlsプロパティからコントロールを追加または削除できるようにするために、Controls_AddメソッドとControls_Removeメソッドを「ThemedForm」クラスに追加しました。

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; }
}

そして最後に、すべてを実行するために、現在の「ThemedForm」クラスとcontentPanelコントロールを渡して、Controlsクラスの新しいインスタンスを作成しました。

_controls = new Controls(this, contentPanel);

これをすべて行った後、UserControlに追加されたコントロール(ビジュアルエディター内でも)をコンテンツパネルに「リダイレクト」することができました。これにより、任意のコントロールのDockプロパティを使用できるようになり、フォーム全体ではなく、コンテンツパネル内にドッキングしました。

ビジュアルエディター内では、ドッキングされたコントロールがフォーム全体にドッキングされているように見えるため、これはまだ少しバグがありますが、アプリケーションを実行すると、期待どおりの結果が得られます。

これが誰にでも役立つことを本当に願っています。

于 2012-08-31T05:25:20.717 に答える