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

时间:2014-07-28 08:33:26

标签: c# winforms generics

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

当前代码(唯一改变的是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 frm = 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;

    }
}

3 个答案:

答案 0 :(得分:1)

你几乎就在那里,你只需要在formtest中添加通用约束:

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

答案 1 :(得分:1)

您可以在表单的通用generic restrictions上使用type

// 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;
    }
 }

P.S。:只需确保您的表单&#39; Names是一致的。您可以使用构造函数为表单使用基本中间类:

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
     {
     }
}

答案 2 :(得分:0)

由于你正在使用“this”,你需要为你正在使用它的每个表单制作一个方法的非静态副本。我的​​想法是将Form's name写入使用过的按钮{ {1}} - 设计师中的属性。名称必须与表单的类名完全相同。:

Tag

此代码使用https://stackoverflow.com/a/4576428/2538037根据给定名称解析表单。我没有测试过这个。在按钮上使用 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; } }