2

次のように、呼び出しフォームの中央にポップアップするカスタムメッセージボックス(基本的にはWinForm)があります。

public partial class Form1 : Form
{
    private void button1_Click(object sender, EventArgs e)
    {
        MsgBox.Show(this, "asdsdfsdf");
    }
}

thisここで、の所有者として(Form1)を渡しますMsgBox。これで、親フォーム()も渡すので、MsgBoxフォームを配置する場所がわかりましForm1た。

ただし、他のクラスから呼び出された場合でも、このカスタムメッセージボックスを(中央から親フォームに)整列させる必要があります。

public class Computer
{
    public void Do(int i)
    {
        MsgBox.Show(i.ToString());
    }
}

ここでの問題は、親フォームの参照をMsgBoxクラスに渡すことができないことです。したがって、ここではカスタムボックスを配置できません。私が欲しいのは、MsgBoxクラスが呼び出しスタックの最後のフォームクラスを判別する機能です。

私はこれを試しました:

public partial class MsgBox : Form
{
    private void X()
    {
        StackTrace df = new StackTrace();
        foreach (var item in df.GetFrames())
        {
            var type = item.GetMethod().DeclaringType;
            if (type.BaseType == typeof(Form))
            {
                IWin32Window w = //how to get the form instance here??
                //------------
                break;
            }
        }
    }
}

私は内側のif節にたどり着きます。type問題は、変数からフォームインスタンスまたはフォームのIWin32Windowハンドルを取得する方法がわからないことです。ではなくクラスのインスタンス自体を取得するためにできることはありますか?

大きな編集:お詫びします。親フォームの参照を取得することは子フォームを中央に配置することであると私が言った大きな間違いです。他のことも行うので、MsqBoxインスタンスに親フォームのハンドルが必要です。要するに、私は親が渡されていないという参照なしに子形式の親フォームが必要です。出来ますか?

4

3 に答える 3

3

MessageBoxをForm.ActiveFormの中央に配置してみてください。

于 2012-09-21T18:07:10.477 に答える
1

ソリューション:

  • 各クラスインスタンスにプライベートForm Parent { get; private set; }プロパティを保持します。MsgBox
  • MsgBox.ActiveForm { get { .. } } を選択する静的プロパティを作成Form.ActiveFormし、それがタイプの場合はそのMsgBox親を返します。

MsgBoxクラスの静的プロパティ:

public static Form ActiveForm
{
    get
    {
        return Form.ActiveForm == null ? null :
            Form.ActiveForm is MsgBox ? ((MsgBox)Form.ActiveForm).Parent :
            Form.ActiveForm;
    }
}
于 2012-09-25T09:34:35.653 に答える
0

これはそれを行う1つの方法です。@Joeに感謝します。

public static Form GetLastForm()
{
    if (Form.ActiveForm != null && !(Form.ActiveForm is MsgBox))
        return Form.ActiveForm;

    var openForms = Application.OpenForms.Cast<Form>().Where(f => !(f is MsgBox));
    if (openForms.Count > 0)
        return openForms[openForms.Count - 1];

    return null;
}

スタックトレースアプローチを介して正しい親フォームを取得するのに問題がありました。ここでの基本的な混乱は、現在アクティブなフォーム、最後に開いたフォーム、またはMsgBoxがポップアップする原因となったフォームが必要かどうかを識別することです。3つすべてが異なる可能性があるため、3つ目を取得するためにスタックトレースアプローチを採用しました。スタックトレースによってはイライラしていました。最後に開いたフォームを取得しない場合は、アクティブなフォームを取得します。Application.OpenFormsフォームを正確に正しい順序で開いてください。

于 2012-09-25T09:23:57.147 に答える