3

私はこれについてどこでも検索しましたが、似たようなことをしている人を見つけることができません。私は非オブジェクト指向言語で 15 年間働いてきた C# の初心者なので、単純なものを見落としていないことを願っています。

継承される標準の Winform を作成しようとしています。これにより、毎回使用するコードを繰り返す必要がなくなります (私が長年使用してきたものに対する .Net の利点の 1 つは、物事を遠くに集中できることです)もっと)。

私の問題は、MDI から起動されたときに派生クラスを「単一インスタンス」または「複数インスタンス」として呼び出す機能を実装したいということです。多くの検索の後、「ジェネリック」を使用してこれをほぼ達成しました。しかし、現在のフォームがどのクラスであるかを知り、それをジェネリッククラスに渡してフォームを閉じる方法に行き詰まっています。

私のコードの簡略化されたバージョンは、私の問題を理解するのに役立ちます. これは、フォームを起動および閉じるために設計された汎用クラスです。T のインスタンスが既に存在するかどうかを判断します。起動するインスタンスが 1 つなのか複数なのかによって、それが表示されるか、フォームの新しいインスタンスが作成されます。MDI が launch メソッドに渡され、新しいフォームをそれにアタッチできるようにします。

public class FormLaunch<T> where T : MyBaseForm, new()
{
    public static T Instance;
    public static void LaunchultipleInstnace(FRMMDI mdi)
    {
        Instance = new T();
        Instance.MdiParent = mdi;
        Instance.Show();
        Instance.BringToFront();
    }
    public static void LaunchSingleInstance(FRMMDI mdi)
    {
        if (Instance == null) Instance = new T();
        Instance.MdiParent = mdi;
        Instance.Show();
        Instance.BringToFront();
    }
    public static void CloseInstance()
    {
        Instance = null;
    }
}

フォームの「単一インスタンス」バージョンは、次のステートメントを使用して MDI から起動されます。

        FormLaunch<MyDerivedClass>.LaunchSingleInstance(this);

問題は、フォームのクローズを基本フォームで一度処理し、派生フォームで毎回処理する必要がないことです。しかし、私はこれを行う方法を理解できません。

public partial class MyBaseForm : Form
{
    public MyBaseForm()
    {
        InitializeComponent();
    }
    private void MyBaseForm_FormClosed(object sender, FormClosedEventArgs e)
    {
        FormLaunch<this.GetType()>.CloseInstance();
    }
}

しかし、 this.GetType() は機能しません。このフォームを継承するのではなく直接使用していた場合は、そのまま使用できます

        FormLaunch<MyBaseForm>.CloseInstance();

または、すべての派生クラスで FormClosed イベントを処理した場合は、そのまま使用できます

        FormLaunch<MyDerivedClass>.CloseInstance();

しかし、派生クラスで毎回これを行うのを忘れないように、これを本当にやりたいと思っています...これは数か月前に書いたもので、使用するたびにほとんど忘れていたからです。

編集: 私の質問は、本当に、T の代わりに何を渡すかです。

        FormLaunch<T>.CloseInstance()

これは派生クラスを参照する必要があり、それが見つからないようです。this.GetType() は正しいガラスを参照しますが、機能しません。

4

2 に答える 2

1

単にサブスクライブして、フォーム自体から close イベントの処理を完全に削除できFormClosedますLaunchSingleInstance()

public static void LaunchSingleInstance(FRMMDI mdi)
{
    if (Instance == null)
    {
        Instance = new T();
        Instance.FormClosed += (s, e) => CloseInstance();
    }
    Instance.MdiParent = mdi;
    Instance.Show();
    Instance.BringToFront();
}

より直接的な答え - リフレクションを使用して可能です:

typeof(FormLaunch<>).MakeGenericType(this.GetType())
                    .GetMethod("CloseInstance")
                    .Invoke(null, null);
于 2013-07-31T10:19:33.580 に答える