将不同使用表单类型和表单名称的方法简化为一个泛型方法

本文关键字:表单 方法 一个 泛型方法 类型 | 更新日期: 2023-09-27 18:15:06

我有几个按钮都有相同的代码,唯一的区别是使用的表单名称。我试图找到一种方法,使代码更小,而不是使用相同的代码在每个按钮和改变表单名称和类型,如果我可以通过字符串名称与泛型的方法,我可以缩短代码很多。

当前代码(唯一改变的是frmVPNManager

)
private void rbtnVPNManager_Click(object sender, EventArgs e)
{
    var frm = Application.OpenForms["frmVPNManager"] as frmVPNManager;
    if (frm != null)
    {
        frm.WindowState = FormWindowState.Maximized;
        frm.BringToFront();
        frm.Activate();
    }
    else
    {
        frm = new frmVPNManager() { MdiParent = this };
        if (rbnMain.OrbDropDown.RecentItems.All(item => item.Text != frm.Text))
        {
            var rbtn = new RibbonButton { Text = frm.Text, DrawIconsBar = false, MaxSizeMode = RibbonElementSizeMode.Medium, SmallImage = Properties.Resources.preview_24x24 };
            rbtn.Click += (s, ea) =>
            {
                var frmv = Application.OpenForms["frmVPNManager"] as frmVPNManager;
                if (frmv != null)
                {
                    frmv.WindowState = FormWindowState.Maximized;
                    frmv.BringToFront();
                    frmv.Activate();
                }
                else
                {
                    rbnMain.OrbDropDown.RecentItems.RemoveAll(item => item.Text == frm.Text);
                }
            };
            rbnMain.OrbDropDown.RecentItems.Add(rbtn);
        }
        frm.Show();
        frm.BringToFront();
        frm.WindowState = FormWindowState.Maximized;
    }
}

我已经尝试使用泛型,但我不知道如何得到这个工作,有什么建议吗?我还应该说明,下面这行不能工作var from = new T {MdiParent = this};

private void rbtnVPNManager_Click(object sender, EventArgs e)
{
    formtest<frmVPNManager>("frmVPNManager");
}
private void rbtnVPNList_Click(object sender, EventArgs e)
{
    formtest<frmVPNList>("frmVPNList");
}
private void formtest<T>(string formname)
{
    if (Application.OpenForms[formname] != null)
    {
        var frm = Application.OpenForms[formname];
        if (frm is T)
        {
            frm.WindowState = FormWindowState.Maximized;
            frm.BringToFront();
            frm.Activate();
        }
    }
    else
    {
        var frm = new T { MdiParent = this };
        if (rbnMain.OrbDropDown.RecentItems.All(item => item.Text != frm.Text))
        {
            var rbtn = new RibbonButton { Text = frm.Text, DrawIconsBar = false, MaxSizeMode = RibbonElementSizeMode.Medium, SmallImage = Properties.Resources.preview_24x24 };
            rbtn.Click += (s, ea) =>
            {
                var frmv = Application.OpenForms[formname] as T;
                if (frmv != null)
                {
                    frmv.WindowState = FormWindowState.Maximized;
                    frmv.BringToFront();
                    frmv.Activate();
                }
                else
                {
                    rbnMain.OrbDropDown.RecentItems.RemoveAll(item => item.Text == frm.Text);
                }
            };
            rbnMain.OrbDropDown.RecentItems.Add(rbtn);
        }
        frm.Show();
        frm.BringToFront();
        frm.WindowState = FormWindowState.Maximized;
    }
}

将不同使用表单类型和表单名称的方法简化为一个泛型方法

您可以对表单的泛型类型使用泛型限制。

// This is the overload that uses default name for your form generated using the Type name
private void formtest<T>() 
    where T : Form, new
{
    formtest<T>(typeof(T).Name); // assume that type of the form is the name of the form instance.
}
// Here we use first overload that uses default name for the form
private void rbtnVPNList_Click(object sender, EventArgs e)
{
    formtest<frmVPNList>();
}

// This is your original code with generic restrictions. Here you can specify name for the form that differs from its type name.
private void formtest<T>(String formname) 
    where T : Form, new
{
    if (Application.OpenForms[formname] != null)
    {
        var frm = Application.OpenForms[formname];
        if (frm is T)
        {
            frm.WindowState = FormWindowState.Maximized;
            frm.BringToFront();
            frm.Activate();
        }
    }
    else
    {
        var frm = new T() { MdiParent = this };
    if (rbnMain.OrbDropDown.RecentItems.All(item => item.Text != frm.Text))
    {
        var rbtn = new RibbonButton { Text = frm.Text, DrawIconsBar = false, MaxSizeMode = RibbonElementSizeMode.Medium, SmallImage = Properties.Resources.preview_24x24 };
        rbtn.Click += (s, ea) =>
        {
            var frmv = Application.OpenForms[formname] as T;
            if (frmv != null)
            {
                frmv.WindowState = FormWindowState.Maximized;
                frmv.BringToFront();
                frmv.Activate();
            }
            else
            {
                rbnMain.OrbDropDown.RecentItems.RemoveAll(item => item.Text == frm.Text);
            }
        };
        rbnMain.OrbDropDown.RecentItems.Add(rbtn);
    }
    frm.Show();
    frm.BringToFront();
    frm.WindowState = FormWindowState.Maximized;
    }
 }

注::只要确保你的表单的名称是一致的。您可以使用基中间类为您的窗体与构造函数:

public abstract class FormBase : Form
{
     public FormBase()
     {
          // Constructor code
          this.Name = this.GetType().Name;
     }
}
public class myFrvForm : Form
{
     public myFrvForm() // base constructor will set name of the form to appropriate one
     {
     }
}

您几乎就完成了,您只需要添加通用约束到formtest:

private void formtest<T>(string formname) where T : Form, new()

既然你正在使用"this",你需要为你正在使用它的每个表单的方法的非静态副本。我的想法是将Form's name写入设计器中使用的按钮的Tag -属性。名称需要与表单的类名完全相同。:

    private void sharedButton_Click(object sender, EventArgs e)
    {
        buttonFunction(((Button)sender).Tag.ToString());
    }
    private void buttonFunction(string formName)
    {
        Form frm = Application.OpenForms[formName] as Form;
        if (frm != null)
        {
            frm.WindowState = FormWindowState.Maximized;
            frm.BringToFront();
            frm.Activate();
        }
        else
        {
            // Open right form according to formName
            Type CAType = Type.GetType("yournamespacehere." + formName);
            frm = (Form)Activator.CreateInstance(CAType);
            frm.MdiParent = this;
            if (rbnMain.OrbDropDown.RecentItems.All(item => item.Text != frm.Text))
            {
                var rbtn = new RibbonButton { Text = frm.Text, DrawIconsBar = false, MaxSizeMode = RibbonElementSizeMode.Medium, SmallImage = Properties.Resources.preview_24x24 };
                rbtn.Click += (s, ea) =>
                {
                    var frmv = Application.OpenForms["frmVPNManager"] as Form;
                    if (frmv != null)
                    {
                        frmv.WindowState = FormWindowState.Maximized;
                        frmv.BringToFront();
                        frmv.Activate();
                    }
                    else
                    {
                        rbnMain.OrbDropDown.RecentItems.RemoveAll(item => item.Text == frm.Text);
                    }
                };
                rbnMain.OrbDropDown.RecentItems.Add(rbtn);
            }
            frm.Show();
            frm.BringToFront();
            frm.WindowState = FormWindowState.Maximized;
        }
    }

此代码使用https://stackoverflow.com/a/4576428/2538037根据给定的名称解析表单。我还没有测试过。在按钮上使用sharedButton_Click