-2

編集: この投稿には多くの反対票が寄せられているようです。私は自分が何をしようとしているのか、どこでエラーが発生し、どの方向に進みたいのかを説明しようとしました。私が間違っていることについての洞察を求めています。反対票を投じた場合; 質問を改善できるように、理由を教えてください。ありがとう。

私は、1 つのメイン フォームと、ユーザーが作業するいくつかの異なるユーザー コントロールを持つアプリケーションを作成しています。これは、コードを分割し、プログラムのさまざまな部分を管理するのに役立ちます。また、後でアプリケーションを拡張するのも簡単です。

アクティブになる必要があるフォームを引数として、そのクラスの1つの関数を呼び出したいアクティブコントロールを管理するクラスを作成しようとしています。

画像は、このアプリケーションをセットアップする方法を示しています。図コントロール マネージャー クラスは、以下に示すコードの個別のクラスではなく、メインフォームの部分クラスであることに注意してください。画像のように取得する方法に関するヒントは大歓迎です:)

すべてのアクティブ フォームを管理するクラスは次のようになります。まだコードはまったく追加されていません。

    public partial class STP2Main 
        {
// I make each UserControl accessable for the whole class
            SetupDeviceControl.SetupDevice SetupDev = new SetupDeviceControl.SetupDevice();
            GenConfigFileControl.GenConfigFileControl GenConfFile = new GenConfigFileControl.GenConfigFileControl();
            Monitoring.MonitoringControl Monitor = new Monitoring.MonitoringControl();
            GenEncKeyControl.GenEncKeyControl GenEncKey = new GenEncKeyControl.GenEncKeyControl();
            MenuControl.MenuControl MenuControl = new MenuControl.MenuControl();        

            public void SelectActiveWindow()
            {
                // Any active control should be hidden thats what this function does:
                HideCurrentActiveControl();
                // Check whether the window is already created
                if (!WindowExists())
                { // if not created; create the windows: 
                    switch (STP_Design.ProgramParameters.C.NextActiveControl)
                    {
                        case STP_Data.Data.SetupDeviceControl: // control 1:
                            STP_Design.ProgramParameters.C.CurrentActiveControl = STP_Data.Data.SetupDeviceControl;
                            STP_Design.ProgramParameters.C.SetupDeviceControlIsCreated = true;
                            SetupDev.Parent = this;
                            SetupDev.Location = new Point(3, 30);
                            SetupDev.Show();
                            SetupDev.BringToFront();
                            break;
                        case STP_Data.Data.MonitoringControl: //control 2:
                            STP_Design.ProgramParameters.C.CurrentActiveControl = STP_Data.Data.MonitoringControl;
                            STP_Design.ProgramParameters.C.MonitoringControlIsCreated = true;
                            Monitor.Parent = this;
                            Monitor.Location = new Point(3, 125);
                            Monitor.Show();
                            Monitor.BringToFront();
                            break;
                        case STP_Data.Data.MenuControl: // control 3
                            STP_Design.ProgramParameters.C.CurrentActiveControl = STP_Data.Data.MenuControl;
                            STP_Design.ProgramParameters.C.MenuControlIsCreated = true;  
                            MenuControl.Location = new Point(3, 30);
                            MenuControl.Parent = this;
                            MenuControl.Show();
                            MenuControl.BringToFront();
                            break;
                    }
                }
                else
                { // window is already created so needs to be called to front again:
                    switch (STP_Design.ProgramParameters.C.NextActiveControl)
                    {
                        case STP_Data.Data.SetupDeviceControl:
                            STP_Design.ProgramParameters.C.CurrentActiveControl = STP_Data.Data.SetupDeviceControl;
                            SetupDev.BringToFront();
                            break;
                        case STP_Data.Data.MonitoringControl:
                            STP_Design.ProgramParameters.C.CurrentActiveControl = STP_Data.Data.MonitoringControl;
                            Monitor.Visible = true;
                            Monitor.BringToFront();
                            break;
                        case STP_Data.Data.AdvancedMenu:
                            STP_Design.ProgramParameters.C.CurrentActiveControl = STP_Data.Data.AdvancedMenu;
                            tabControl1.Visible = true;
                            tabControl1.BringToFront();
                            break;

                        case STP_Data.Data.MenuControl:
                            STP_Design.ProgramParameters.C.CurrentActiveControl = STP_Data.Data.MenuControl;
                            MenuControl.Visible = true;
                            MenuControl.BringToFront();
                            break;
                    }

                }
                btnMenu.BringToFront();

            }
    // some functions which are called above are not shown; not relevant for this question
    }

私が経験したことは次のとおりです。エラーはまったく発生しません。しかし、コントロールはまったく変わりません。ウィンドウを呼び出すと、メインフォームの部分クラスとして作成したため、ウィンドウは一度だけ作成されます。(私は経験豊富な C# プログラマーではないので、部分クラスを使用してそれを回避しようとしました。)

別の関数を追加します。何もしません:

    private void HideCurrentActiveControl()
    {
        switch (STP_Design.ProgramParameters.C.CurrentActiveControl)
        {
            case STP_Data.Data.SetupDeviceControl:
                SetupDev.Visible = false;
                break;
            case STP_Data.Data.MonitoringControl:
                tabControl1.Visible = false;
                Monitor.Visible = false;
                break;
            case STP_Data.Data.GenConfFileControl:
                GenConfFile.Visible = false;
                break;
            case STP_Data.Data.GenEncKeyControl:
                GenEncKey.Visible = false;
                break;
            case STP_Data.Data.MenuControl:
                MenuControl.Visible = false;
                break;
            case STP_Data.Data.AdvancedMenu:
                tabControl1.Visible = false;
                break;
            default:
                tabControl1.Visible = false;
                break;

        }
    }

コードのこの部分をデバッグしてみましたが、ステートメントが実行されましたが、まったく変更が見られません。

私がやろうとしていることを示したと思います。そして、私がそれをどのようにしようとしているのか。私の質問は、これらのフォームにアクセスして、別のクラス(またはこの場合はメインフォームの部分クラス)から管理できるようにする方法です。

次に、奇妙なことを行うこの最後の関数があります。SelectActiveWindow() 関数を呼び出す前に、変数 STP_Design.ProgramParameters.C.NextActiveControl をたとえば ...AdvancedMenu に更新します。(これはその前でした...MenuControl)しかし、それがまだMenuControlであることを常に示しています。私のコードのどこにも、関数を開始する直前以外にその値を変更するものはありません。(関数 SelectActiveWindow() の引数として nextcontrol を作成しようとしましたが、これも同じでした)

    private bool WindowExists()
    {
        switch (STP_Design.ProgramParameters.C.NextActiveControl)
        {
            case STP_Data.Data.SetupDeviceControl:
                if (STP_Design.ProgramParameters.C.SetupDeviceControlIsCreated)
                    return true;
                else
                    return false;
            case STP_Data.Data.MonitoringControl:
                if (STP_Design.ProgramParameters.C.MonitoringControlIsCreated)
                    return true;
                else
                return false;
            case STP_Data.Data.GenConfFileControl:
                if (STP_Design.ProgramParameters.C.GenConfFileIsCreated)
                    return true;
                else
                    return false;
            case STP_Data.Data.GenEncKeyControl:
                if (STP_Design.ProgramParameters.C.GenEncKeyControlIsCreated)
                    return true;
                else
                    return false;
            case STP_Data.Data.AdvancedMenu:
                return true;
            case STP_Data.Data.MenuControl:
                if (STP_Design.ProgramParameters.C.MenuControlIsCreated)
                    return true;
                else
                    return false;

            default:
                return false;
        }
    }

私が探しているものの要約: さまざまなユーザー コントロールを表示するメイン フォームがあります。プロジェクトの各コントロール/フォームからアクセスできる別のクラスを作成しようとしています。このクラスは、表示されるコントロールを管理する必要があります。上記のコードでは、これを行う方法を示しましたが、期待した結果にはなりません。

4

1 に答える 1

2

わかりました。これで、必要なコンテキストが理解できました。実際、私のプログラムでは非常に似たようなことをしています。これが私たちがそれを行う方法の基本的な概要です...

レイアウト

メイン フォームには、と呼ぶPanelpnlMainコンテナがあります。アクティブなユーザー コントロールを追加および削除するのは、このコントロールです。を表すフォームのグローバル レベルにUserControlオブジェクトもありますcurActiveControl

コード

ユーザーがメニューの 1 つを介してウィンドウを選択すると、次のような関数が実行されます。

switch (UserSelection)
{
    case "Page 1":
        if(curActiveControl.GetType() != typeOf(Page1Control))
        {
            pnlMain.Controls.Remove(curActiveControl);
            curActiveControl = new Page1Control();
            //do setup and configuration things
            pnlMain.Controls.Add(curActiveControl);
        }
        //do some post processing things
        break;
    //other pages/specific page controls
}

Refresh();

この特定の方法の欠点は、ページ自体が永続的ではないことです。そのため、ページ上だけでなく、セッション全体でアクティブにしたいエントリまたは変数がある場合は、それらを他のグローバル オブジェクトに保存してリロードする必要があります。ユーザー コントロールの Load メソッドまたは Constructor メソッドからそれらを取得します。

これと同じことを行うことができますが、毎回新しいコントロール インスタンスを作成する代わりに、curActiveControl単純に新しいコントロールのスタンバイ インスタンスに置き換えることができます。ただし、参照と上書きには注意してください。これは、私が個人的に以前に試したことではありません。

使用するメソッドで重要なのは、ユーザー コントロールを保持する Panel です。多数のユーザー コントロールの可視性と Z オーダーを調整するのではなく、メイン パネルに表示されるコントロールを変更するだけで、他のコントロールは特定の時点では存在しません。

もう 1 つの欠点は、この機能がメイン フォームに直接あることです。これが別の部分クラスとしてうまく機能するかどうかはわかりません。ただし、試してみる価値は間違いありません。

于 2012-10-29T14:09:36.293 に答える