确定是否打开了MDI表单

时间:2018-09-17 14:27:04

标签: c# winforms

我有一个基本表单(BaseMDIForm),几个表单(客户,库存,订单等)都继承自其中。在此基本格式上是受保护的字符串“ windowID”。每个表单都会设置此ID,以唯一标识当前以该表单打开的对象(Client.ID,Inventory.ID,Order.ID等)。

我已成功在“客户”表单上使用此方法在任何打开的“客户”表单上找到特定的客户ID:

// method is in the Client form (and is coded to specifically look for Client forms)
private Boolean FindFormWithWindowID(string windowID)
{
    foreach (Form form in this.MdiParent.MdiChildren)
    {
        if (form.GetType() == typeof(frmClient))
        {
            frmClient clientForm = (frmClient)form;
            if (clientForm.windowID == windowID)
            {
                // close this form because the client is open on an existing form
                if (this.windowID == "") // this won't be set yet if we're searching for an existing form
                    Close();

                form.Activate();
                return true;
            }
        }
    }
}

此概念背后的思想是,当用户尝试打开已在现有表单上打开的客户记录(或库存,订单等)时,将重点放在现有表单上并将其置于最前面(并且然后关闭新打开的表单。)

我正在尝试将此方法移至基本形式,因此不需要以任何继承的形式(从这些形式调用这些形式)连续创建此方法,例如:

if (!FindFormWithWindowID(ClientForm, windowID))
{
    // continue loading new form
}

有没有一种方法可以传递表单类型(客户,库存,订单等),然后让这种新的基本方法遍历特定传入表单类型的现有MdiChildern,以查找包含给定的窗口ID(请记住,将从许多不同类型的继承表单中调用此方法)?我试图避免添加switch语句来确定表单类型,因为这将迫使我在将全新表单添加到项目中时对其进行更新。

2 个答案:

答案 0 :(得分:1)

WindowID实际上不存在于窗体上,因此我假设您已经为您添加了WindowID到继承的基本窗体中。

public InheritedForm : Form
{
    public string WindowID { get; set; }
}

在这种情况下,您可以将当前的FindFormWithWindowID方法替换为:

string windowidtolookfor = "1234";

InheritedForm foundform = Application.OpenForms.OfType<InheritedForm>().Where(f => f.WindowID = windowidtolookfor).FirstOrDefault();

如果要使用特定类型的表单:

MyForm foundform = Application.OpenForms.OfType<MyForm>().Where(f => f.WindowID = windowidtolookfor).FirstOrDefault();

在尝试进行操作之前,您需要检查foundform是否不为null,因为FirstOrDefault()如果无法返回匹配项,则将返回null。

可以在任何地方调用它,因此您不必担心为它选择一个合适的位置。

这似乎有点困惑,所以我将其分解:

Application.OpenForms是一个属性,列出了在应用程序中打开的所有表单。

我们称呼它,然后通过`OfType()指定要查找的Form的类型,这会将OpenForms筛选为仅具有typeX的FormX。

此后,我们添加Where(f => f.WindowID = "1234")

这告诉查询我们只需要WindowID为“ 1234”的FormX形式。

最后,我们添加FirstOrDefault(),这将返回它找到Form为FormX并且WindowID =“ 1234”的第一个实例。如果不存在符合条件的表单,则它将返回NULL。

它在功能上等同于FindFormWithWindowID,但每次使用它时,您都可以通过使用所需的任何表单类型替换OfType来对其进行更改。

如果您只想在最后获得布尔结果,则可以这样做:

if (Application.OpenForms.OfType<FormX>().Where(f => f.WindowID == windowidtolookfor).FirstOrDefault() != null)
{
    // Found a window matching the criteria
}
else
{
    // Not found a window matching the criteria.
}

答案 1 :(得分:0)

对于固定数量的类型,您可以传递代表该类型的字符串,然后检查每个窗口类型以查看是否匹配。

System.Type getTypeOfForm(string docType) {
    switch (docType) {
        case "Customer":
            return typeof(MyNameSpace.CustomerMDIForm);
        case "Invoice":
            return typeof(MyNameSpace.InvoiceMDIForm);
        case "Order":
            return typeof(MyNameSpace.OrderMDIForm);

            ...

        default:
            throw new Exception("Unknown Form Type");
    }
}

您可以通过将返回的运行时类型插入到具有== typeof(frmClient)的位置来将返回类型缝合到现有循环中。如果您为目标表单类型传递了完全合格的类字符串,则还可以使用System.GetType(string)将其转换为System.Type对象。

如果您仅将System.Type变量传递给搜索,也可以避免使用任何字符串来键入映射恶作剧:

if (!FindFormWithWindowID(typeof(MyNameSpace.CustomerMDIForm), windowID))