从子窗体导航到其兄弟窗体

3
在父表单A中,有以下代码来调用子表单“B”:
        Window frmChildB;
        frmChildB = new FormB();
        frmChildB.ShowDialog();

在同一个表单中:以下代码调用子表单“C”:
        Window frmChildC;
        frmChildC = new FormC();
        frmChildC.ShowDialog();

现在我想在表单B中制作一个按钮,以便如果我单击该按钮,它会自动导航到表单C。
如果可能的话,应避免在表格B中使用类似于此question答案中的表格C的引用对象。原因是有超过十个像B、C这样的表单,每个表单都必须能够导航到另一个表单。在一个表单中拥有10个表单引用对象是不好的。
我认为一定有某种方法可以实现这种效果。有人知道吗?

Form.ShowDialog 显示一个模态对话框,这在您发布的代码中似乎有问题。如果 FormB 正在以模态方式显示,则在显示 FormC 之前需要取消激活它,那么为什么不使用 Form.Show 呢? - M.Babcock
@M.Babcock:这是因为该应用程序不允许用户在关闭子窗体之前返回主窗体。换句话说,用户一次只能在一个窗体上工作。 - Hoàng Long
1
你为什么要使用不同的形式?使用框架或用户控件不是更适合吗? - M.Babcock
听起来对我来说很像一个巫师。 - M.Babcock
类似于这个链接,但是除了包含下一步和上一步按钮之外,还要包括所有步骤的按钮? - M.Babcock
显示剩余4条评论
3个回答

1
尝试在frmChildB中创建一个事件并在父级中进行订阅。然后,您可以自由操作而无需在frmChildB中引用frmChildC。

看看这个 MSDN link

这很粗糙,但应该能给你一个想法。

在子窗体中创建事件

public delegate void SwapEventHandler(object sender, EventArgs e);
public partial class Form2 : Form
{
    public event SwapEventHandler Swap;

    public Form2()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        Swap(sender, e);
    }
}

在父表单中使用它

private void button1_Click(object sender, EventArgs e)
{
    frmChildB = new Form2();
    frmChildB.Name = "frmChildB";
    frmChildB.Swap += new SwapEventHandler(frmChildB_Swap);
    frmChildB.ShowDialog();
}


private void frmChildB_Swap(object sender, EventArgs e)
{
    frmChildB.Swap -= new SwapEventHandler(frmChildB_Swap);
    frmChildB.Close();
    frmChildB.Dispose();
    frmChildB = null;
    frmChildC = new Form2();
    frmChildC.Name = "frmChildC";
    frmChildC.Swap += new SwapEventHandler(frmChildC_Swap);
    frmChildC.ShowDialog();
}

void frmChildC_Swap(object sender, EventArgs e)
{
    frmChildC.Swap -= new SwapEventHandler(frmChildC_Swap);
    frmChildC.Close();
    frmChildC.Dispose();
    frmChildC = null;
    frmChildB = new Form2();
    frmChildB.Name = "frmChildC";
    frmChildB.Swap += new SwapEventHandler(frmChildB_Swap);
    frmChildB.ShowDialog();
}

非常抱歉如果这是一个新手问题,但我还没有完全理解你的答案。您介意指向一些参考资源,如教程或示例源代码吗? - Hoàng Long

1

如果我正确理解了您的问题,您想要每个表单的单个实例,并在它们之间来回导航。

如果这是您想要的,您可以实现一个静态的FormManager类,创建表单的实例并根据需要显示它们。您甚至可以使用枚举进一步减少复杂性。

以下是此类的示例(它需要一些额外的工作,但应该能给您一个很好的想法):

public class FormManager
{
    private static FormB m_FormB;
    public static FormB formB
    {
        get
        {
            if (m_FormB == null)
            {
                m_FormB = new FormB();
            }
            return m_FormB;
        }
    }
    private static FormC m_FormC;
    puClic static FormC formC
    {
        get
        {
            if (m_FormC == null)
            {
                m_FormC = new FormC();
            }
            return m_FormC;
        }
    }

    public enum FormId
    {
        FormB,
        FormC
    }

    public static Form ShowForm(FormId whichForm)
    {
        Form oForm;

        switch (whichForm)
        {
            case FormId.FormB:
                oForm = FormManager.formB;
                break;

            case FormId.FormC:
                oForm = FormManager.formC;
                break;

            default:
                oForm = null;
                break;
        }

        if (oForm != null)
        {
            oForm.ShowDialog();
        }
        return oForm;
    }
}

可以从子窗体中调用此函数:

FormManager.ShowForm(FormManager.FormId.FormB);

这种方法很好。但是当我想关闭一个子窗体,然后再次打开它时,它会提示:“窗口关闭后无法设置可见性或调用Show或ShowDialog”。我不太明白为什么使用这种方法会导致错误,但我需要关闭子窗体以返回主窗口。 - Hoàng Long

0

从基本层面上看,使用标准的“向导”模式比为每个问题单独创建表单更有益。例外情况是,除了通常的下一步和返回按钮之外,您应该有按钮可以跳转到任何一个问题。这里有一个很好的教程,将引导您完成创建向导的常规步骤。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接