C# 具有泛型和多参数的方法

C# 具有泛型和多参数的方法,c#,visual-studio,methods,overloading,C#,Visual Studio,Methods,Overloading,我想根据用户权限启用/禁用Windows窗体应用程序中的控件 最初,我想在每个表单类中编写一个方法,检查用户凭据,然后启用/禁用其控件。但后来我意识到我可以(也许)创建一个静态类方法,它将表单作为一个参数来完成这项工作 所以我开始写它,假设有时我只想启用一个或两个面板的控件,而不是整个表单。因此,我需要参数为: 不同数量的面板和/或 一个正式的班级 我在这个任务中遇到的困难是,我在尝试使panels参数变化时遇到了一个错误,我不知道如何设置可以采用任何形式的类的参数。我所有的表单类显然都继承

我想根据用户权限启用/禁用Windows窗体应用程序中的控件

最初,我想在每个表单类中编写一个方法,检查用户凭据,然后启用/禁用其控件。但后来我意识到我可以(也许)创建一个静态类方法,它将表单作为一个参数来完成这项工作

所以我开始写它,假设有时我只想启用一个或两个面板的控件,而不是整个表单。因此,我需要参数为:

  • 不同数量的面板和/或
  • 一个正式的班级
我在这个任务中遇到的困难是,我在尝试使panels参数变化时遇到了一个错误,我不知道如何设置可以采用任何形式的类的参数。我所有的表单类显然都继承自表单泛型类,但我不知道如何应用它

以下是我得到的:

public static void Enable(TableLayoutPanel[] containers = null)
    {
        if (MyOF.isEnabled)
        {
            return;
        }
        else
        {
            try
            {
                foreach (TableLayoutPanel table in containers)
                {
                    foreach (Control control in table.Controls)
                    {
                        control.Enabled = false;
                    }
                }
            }
            catch (NullReferenceException)
            {
            }
        }
    }

如果我们记得
表单
类派生自
控件
(间接地,通过派生自
滚动控件
,派生自
控件
)的
容器控件
,而
启用的
属性属于
控件
类,我们可以编写一个方法来启用任何控件的子控件(包括
窗体
表格布局面板
控件),因为
控件
集合也属于
控件
类:

public static void EnableChildren(Control control, bool enabled = true)
{
    foreach (Control child in control.Controls)
    {
        child.Enabled = enabled;
    }
}
然后,如果我们还希望能够将其用于控件集合(如您的示例所示),我们可以编写一个重载来获取一个集合:

public static void EnableChildren(IEnumerable<Control> controls = null, 
    bool enabled = true)
{
    if (controls == null) return;

    foreach (var control in controls)
    {
        EnableChildren(control, enabled);
    }
}

我可以用一个简单的方法来思考你想做什么,就是这样。让我离开一会儿。我从事的项目中,所有表单控件都是从元数据构建的。meta附带了许可信息。因此,当控件放置在它应该放置的位置时,它也被禁用或基于元数据设置为只读,但如果许可信息限制对它的访问,则整个功能将被隐藏。回到你的方法上来,这是一个不错的方法,我认为这是可以做到的。这可以通过两种方式实现(从我的头脑中快速实现)

  • 使用用户控件作为要启用/禁用的组件的曲面。创建一个接口
  • public interface IDisableControl//make your fine name,无需任何方法-marker interface
    . .  . . . 
    公共类MyFineUserControl:UserControl、IDisableControl
    
    在您将要编写的
    静态
    方法中,传递表单,找到实现此接口的所有控件,并以您想要的方式对其进行操作

    二,。 类似地,您可以使用属性
    标记
    ,这在每个控件上都可用。这样,您就可以设置复杂的安全对象,该对象可以来自DB存储的元数据,然后对存储在
    Tag
    中的该对象进行评估,以应用您的配置

    您的方法需要是递归的

    内部静态void SetAllControls(控件父控件)
    {
    //对控件执行某些操作,例如parent.Enabled=false
    如果(父项为IDisableControl)
    {
    //在这里,您可以使用您的逻辑,评估您正在拨打的家长,然后
    //相应地启用/禁用
    parent.Enabled=false;
    返回;
    }
    foreach(父控件中的var c)
    设置所有控件(c);
    } 
    

    在现实生活中,你的顶级父母将是一种形式,不需要被禁用,但某些孩子会。事实上,在大多数情况下,一旦您找到了一个实现了
    IDisableControl
    UserControl
    ,它应该是行的末尾,这意味着您不需要进入子控件,因为它们都位于该父控件上,并且都将被禁用

    我设法完成了我试图用下面的代码所做的事情,这几乎是我得到的所有有用答案的混合:

    public static void EnableContainer(params Control[] containers)
        {
            if(containers.Count() == 0) { return; }
            if (MyOF.isEnabled)
            {
                return;
            }
            else
            {
                try
                {
                    foreach (var container in containers)
                    {
                        foreach (Control control in container.Controls)
                        {
                            control.Enabled = false;
                        }
                    }
                }
                catch (NullReferenceException)
                {
                }
            }
        }
        public static void EnableForm<form>(form f) where form : Form
        {
            if (MyOF.isEnabled)
            {
                return;
            }
            else
            {
                foreach(Control control in f.Controls)
                {
                    control.Enabled = false;
                }
            }
        }
    
    publicstaticvoidenablecainer(参数控制[]容器)
    {
    if(containers.Count()==0){return;}
    如果(MyOF.isEnabled)
    {
    返回;
    }
    其他的
    {
    尝试
    {
    foreach(容器中的var容器)
    {
    foreach(container.Controls中的控件)
    {
    control.Enabled=false;
    }
    }
    }
    捕获(NullReferenceException)
    {
    }
    }
    }
    公共静态无效启用表格(表格f),其中表格:表格
    {
    如果(MyOF.isEnabled)
    {
    返回;
    }
    其他的
    {
    foreach(f.Controls中的控件)
    {
    control.Enabled=false;
    }
    }
    }
    

    欢迎社区提出改进建议,因为我远不是一名专业程序员。再次感谢大家。

    实际上,C#中有一个叫做“泛型类型”的功能,可以解决您的问题。从这个意义上讲,您使用术语“通用”的方式是不正确的<代码>表单是所有表单的基类。您可以创建这样一个方法
    publicstaticvoiddostuff(T someForm),其中T:Form{//implementhere}
    可以接受任何特定表单作为参数,并访问特定于该表单类型的成员。谢谢James。我在上一次搜索中遇到了这个问题,但是我缺少了
    where T:Form
    部分。我试试看。另外,我如何使TableLayoutPanel参数在数量上有所不同?当我试图调用只传递一个面板的方法时,我得到一个错误“无法从…面板转换到…面板[]”,请查找
    params
    keyword@JamesFaix这-
    公共静态无效DoStuff(T someForm),其中T:Form
    我称之为异端邪说。:-)完全滥用一般用途。这就足够了-
    publicstaticvoiddostuff(formsomeform)
    pur是什么
    public static void EnableContainer(params Control[] containers)
        {
            if(containers.Count() == 0) { return; }
            if (MyOF.isEnabled)
            {
                return;
            }
            else
            {
                try
                {
                    foreach (var container in containers)
                    {
                        foreach (Control control in container.Controls)
                        {
                            control.Enabled = false;
                        }
                    }
                }
                catch (NullReferenceException)
                {
                }
            }
        }
        public static void EnableForm<form>(form f) where form : Form
        {
            if (MyOF.isEnabled)
            {
                return;
            }
            else
            {
                foreach(Control control in f.Controls)
                {
                    control.Enabled = false;
                }
            }
        }