2

ウィザードのような一連の 5 つの単純なフォームを使用するアプリケーションを作成しています。最初のフォームである NewProfile は、メイン アプリケーションである MainForm のメニュー項目から開かれるため、MainForm のサブフォームです。2 番目のフォームである TwoProfile は、NewProfile のボタンから開きます。3 番目のフォームである ThreeProfile は、TwoProfile のボタンから開かれます。5 つのフォームすべてについても同様です。シーケンスは次のとおりです: MainForm --> NewProfile <--> TwoProfile <--> ThreeProfile <--> FourProfile <--> FiveProfile。私の問題は、任意のフォーム (NewProfile、TwoProfile、ThreeProfile、FourProfile、または FiveProfile) が開いているときに、ユーザーが NewProfile のインスタンスを作成できないようにすることです。

私は、途中で動作するシングルトン パターンを実装することから始めました。NewProfile が開いている場合に機能し、MainForm に移動して NewProfile の別のインスタンスを作成しようとします。次のフォームに進むことによって NewProfile が破棄され、TwoProfile、ThreeProfile、FourProfile、または FiveProfile のいずれかが開いている場合は機能しません。NewProfile.IsDisposed が true であることがわかり、Singleton インスタンスへの不適切な参照が表示されます。

私が理解できないのは、TwoProfile、ThreeProfile、FourProfile、または FiveProfile のいずれかが開いている場合、または NewProfile 自体が開いている場合に NewProfile が作成されないようにロジックを実行する方法です。

これが理にかなっていることを願っています。シングルトンで行ったことを除いて、投稿するコードはあまりありません。

   private static NewProfile _instance = null;
   public static NewProfile Instance
    {
        get
        {
            if (_instance == null)
            {
                _instance = new NewProfile();
            }
            return _instance
        }
    }

ありがとうございました :)

4

2 に答える 2

1

これを処理する方法は、開いているフォーム インスタンスを追跡する静的ウィンドウ マネージャー クラスを用意することです。ユーザーが新しいウィンドウを開くアクションを実行すると、まずウィンドウ マネージャーをチェックして、フォームが既に開いているかどうかを確認します。そうであれば、新しいインスタンスを作成するのではなく、それにフォーカスを設定します。

開かれるすべてのフォームは、開かれると自動的にウィンドウ マネージャーに登録され、閉じられるとその登録が削除される基本フォームの実装から継承されます。

WindowManager クラスの大まかな概要は次のとおりです。

public class WindowManager
{
    private static Dictionary<string, Form> m_cOpenForms = new Dictionary<string, Form>();

    public static Form GetOpenForm(string sKey)
    {
        if (m_cOpenForms.ContainsKey(sKey))
        {
            return m_cOpenForms[sKey];
        }
        else
        {
            return null;
        }
    }
    public static void RegisterForm(Form oForm)
    {
        m_cOpenForms.Add(GetFormKey(oForm), oForm);
        oForm.FormClosed += FormClosed;
    }

    private static void FormClosed(object sender, FormClosedEventArgs e)
    {
        Form oForm = (Form)sender;
        oForm.FormClosed -= FormClosed;
        m_cOpenForms.Remove(GetFormKey(oForm);
    }

    private static string GetFormKey(Form oForm)
    {
        return oForm.Name;
    }
}

そして、次のように使用できます。

        Form oForm = WindowManager.GetOpenForm("Form1");
        if (oForm != null)
        {
            oForm.Focus();
            oForm.BringToFront();
        }
        else
        {
            oForm = new Form1();
            WindowManager.RegisterForm(oForm);
            // Open the form, etc
        }
于 2013-01-19T20:15:18.270 に答える
1

コメントで示唆されているように、各「フォーム」は実際には交換するユーザーコントロールである可能性があります。そうすれば、1 つのフォームと複数のページしかありません。または、フォームを非表示にすることもできます。

代わりに複数のフォームが必要な場合は、開いているすべてのフォームをループして、確認したいフォームが開いているかどうかを確認できます。そうでない場合は、開くことができますNewProfile

bool shouldOpenNewDialog = true;

foreach (Form f in Application.OpenForms)
{       
    //give each dialog a Tag value of "opened" (or whatever name)
    if (f.Tag.ToString() == "opened")
        shouldOpenNewDialog = false;    
}


if(shouldOpenNewDialog)
    np = new NewProfile();

Tagこれはテストされていませんが、開いているすべてのフォームをループして、ことわざがあるものを探す必要がありますopened。見つかった場合は、shouldOpenNewDialogフラグを falseに設定し、NewProfile呼び出されません。

于 2013-01-19T19:34:01.947 に答える