winforms 从表单集合问题调用公共方法

ujv3wf0j  于 2022-11-30  发布在  其他
关注(0)|答案(2)|浏览(162)

我通过窗体集合隐藏和显示窗体作为用户超时功能,并且需要在再次显示窗体时调用每个窗体中的公共方法,以便使用登录用户更新窗体(如果它发生更改)。
然而,我对此有异议,因为我似乎不能直接从表单集合的迭代中完成此操作。有人有什么建议吗?
这是我正在工作的代码。任何帮助都非常感谢!

FormCollection fc = Application.OpenForms;

foreach (Form frm in fc)
{
  if (frm.Visible == false && frm.Name != "FStart" && frm.Name != "FMain")
  {
     //Here I would like to call frm.UpdateUser(.....);
     frm.Show();
  }
}

感谢大家的帮助,这个方法在每一种形式中都是一个公共的空白。
我尝试从窗体集合访问公共方法,并且尝试直接访问该方法。

wf82jlnq

wf82jlnq1#

代码中的第一个潜在问题是,您正在迭代Application.OpenForms集合,希望找到Visible==false的示例。(取决于关闭的方法)可能不包含随后隐藏的表单。由于第一个循环条件可能计算为false,不保证执行frm.Show()行。
一个解决方案是创建自己的Forms集合,然后迭代该集合。

public partial class MainForm : Form
{
    /// <summary>
    /// Mixed list of Form references where "some" will implement `UpdateUser`
    /// </summary>
    List<Form> AllForms = new List<Form>();

    public MainForm()
    {
        InitializeComponent();
    }
    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
        AllForms.Add(this);
        AllForms.Add(new UserFormA());
        AllForms.Add(new UserFormB());
    }
}

第二个问题是,您的语法告诉编译器将循环对象解释为循环foreach (Form frm in fc)...中的Form,但Form类本身没有UserUpdate方法。在调用UpdateUser方法之前,我们需要确定集合中的特定继承类是支持UpdateUser方法的类,还是支持一个健壮的方法是创建一个接口(我们可以称之为IUpdatableUserForm),然后选择继承的Form类中的哪一个来实现它。例如:

interface IUpdatableUserForm
{
    void UpdateUser();
    string Name { get; set; }
    bool Visible { get; set; }
    public void Show(IWin32Window owner);
}
public class UserFormA : Form, IUpdatableUserForm
{
    public UserFormA()
    {
        Name = nameof(UserFormA);
    }
    public void UpdateUser()
    {
        Size = new Size(500, 300);
        Text = Name;
    }
}

现在,当您在Form上迭代集合时,可以确保 * 特定 * 继承的Form使用is运算符实现UpdateUser方法,并且仅在该方法存在时才调用该方法。(通过比较,如果dynamic关键字遇到Form的派生项,而该派生项不实现UpdateUser,则该关键字将引发异常)。

private void onTest()
{
    foreach (Form frm in AllForms)
    {
        if (frm is IUpdatableUserForm safeForm)
        {
            if (!safeForm.Visible)
            {
                switch (safeForm.Name)
                {
                    case "FStart":
                    case "FMain":
                        break;
                    default:
                        // Here I would like to call frm.UpdateUser(.....);
                        safeForm.UpdateUser();
                        safeForm.Show(this);
                        break;
                }
            }
        }
    }
}

8qgya5xd

8qgya5xd2#

尝试使用dynamic keyword访问方法UpdateUser。下面是一个示例:

FormCollection fc = Application.OpenForms;

foreach (dynamic frm in fc)
{
    if (frm.Name != "FStart" && frm.Name != "FMain")
    {
       frm.UpdateUser(); //You will still have to add the arguments....
       frm.Show();
    }
 }

请记住,当您使用dynamic关键字时,它并不关心您试图调用什么方法,也不关心您为它们提供了什么参数,所以在使用它时要小心。

相关问题