具有通用和多个参数的方法
Method with generic and multiple parameters
我想 enable/disable 根据用户权限在 Windows Forms 应用程序中进行控制。
最初我想在每种形式 class 中编写一个方法来检查用户凭据,然后 enable/disable 它的控件。但后来我意识到我可以(也许)创建一个静态 class 方法,它将表单作为参数并完成工作。
所以我开始编写它,假设有时我只想启用一个或两个面板的控件,而不是整个表单。所以,我需要的参数是:
- 不同数量的面板 and/or
- 表格class.
我在这项任务中遇到的困难是我在尝试使面板参数变化时遇到错误,而且我不知道如何设置可以采用任何形式的参数 class。我所有的表单 classes 显然都继承自通用表单 class,但我不知道如何应用它。
这是我得到的:
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)
{
}
}
}
如果我们记得 Form
class 派生自 Control
(间接地,通过派生自 ContainerControl
,派生自 ScrollableControl
,派生自Control
), 而Enabled
属性 属于Control
class, 我们可以写一个方法来启用any 控件的子控件(包括 Form
或 TableLayoutPanel
控件),因为 Controls
集合也属于 Control
class:
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);
}
}
现在我们可以将其与 Form
或 TableLayoutPanel
控件的集合(或任何在其 Controls
集合中包含控件的控件)一起使用。
使用示例:
var myForm = new Form1();
EnableChildren(this); // 'this' is the current form
EnableChildren(myForm); // a separate instance of a form control
EnableChildren(tableLayoutPanel1, false); // A single TableLayoutPanel control
var tableLayoutPanels = new [] {tableLayoutPanel1, tableLayoutPanel2, tableLayoutPanel3};
EnableChildren(tableLayoutPanels); // An array of tableLayoutPanel controls
我可以考虑您正在尝试做的事情的一种简单方法是这个。让我离开这里一会儿。我从事的项目中,所有表单控件都是从元数据构建的。 meta 附带了许可信息。因此,当控件被放置在它应该放置的位置时,它也会被禁用或根据元数据设置 read-only,但如果许可信息限制对它的访问,整个功能将被隐藏。回到你的方法,这不是一个坏方法,我看到这是可以做到的。它可以通过两种方式完成,(从我的脑海中快速想到)。
- 使用用户控件作为您想要的组件的表面enable/disable。创建接口
public interface IDisableableControl // make your fine name, no methods needed - marker interface
. . . . .
public class MyFineUserControl : UserControl, IDisableableControl
然后在您要编写的 static
方法中传递表单,并找到实现此接口的所有控件并按您希望的方式工作。
2。
同样,您可以使用每个控件上可用的 属性 Tag
。这样,您实际上可以设置可以来自 DB-stored 元数据的复杂安全性 object,然后评估存储在 Tag
中的这个 object 以应用您的配置
你的方法需要递归
internal static void SetAllControls(Control parent)
{
// Do something with control, for example parent.Enabled = false
if (parent is IDisableableControl)
{
// here you use your logic, evaluate your parent you're dialing with and
// enable/disable correspondingly
parent.Enabled = false;
return;
}
foreach(var c in parent.Controls)
SetAllControls(c);
}
在现实生活中,您的 TOP parent 将是一种形式,不需要被禁用,但肯定 children 会。事实上,大多数时候,一旦你发现一个 UserControl
实现了 IDisableableControl
应该是行尾,这意味着你不需要进入 children 控件,因为它们都是坐在这个 parent 上,所有都将被禁用
我设法用下面的代码完成了我想做的事情,这几乎是我得到的所有有用答案的混合:
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;
}
}
}
欢迎社区提出改进建议,因为我远不是专业程序员。再次感谢大家。
我想 enable/disable 根据用户权限在 Windows Forms 应用程序中进行控制。
最初我想在每种形式 class 中编写一个方法来检查用户凭据,然后 enable/disable 它的控件。但后来我意识到我可以(也许)创建一个静态 class 方法,它将表单作为参数并完成工作。
所以我开始编写它,假设有时我只想启用一个或两个面板的控件,而不是整个表单。所以,我需要的参数是:
- 不同数量的面板 and/or
- 表格class.
我在这项任务中遇到的困难是我在尝试使面板参数变化时遇到错误,而且我不知道如何设置可以采用任何形式的参数 class。我所有的表单 classes 显然都继承自通用表单 class,但我不知道如何应用它。
这是我得到的:
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)
{
}
}
}
如果我们记得 Form
class 派生自 Control
(间接地,通过派生自 ContainerControl
,派生自 ScrollableControl
,派生自Control
), 而Enabled
属性 属于Control
class, 我们可以写一个方法来启用any 控件的子控件(包括 Form
或 TableLayoutPanel
控件),因为 Controls
集合也属于 Control
class:
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);
}
}
现在我们可以将其与 Form
或 TableLayoutPanel
控件的集合(或任何在其 Controls
集合中包含控件的控件)一起使用。
使用示例:
var myForm = new Form1();
EnableChildren(this); // 'this' is the current form
EnableChildren(myForm); // a separate instance of a form control
EnableChildren(tableLayoutPanel1, false); // A single TableLayoutPanel control
var tableLayoutPanels = new [] {tableLayoutPanel1, tableLayoutPanel2, tableLayoutPanel3};
EnableChildren(tableLayoutPanels); // An array of tableLayoutPanel controls
我可以考虑您正在尝试做的事情的一种简单方法是这个。让我离开这里一会儿。我从事的项目中,所有表单控件都是从元数据构建的。 meta 附带了许可信息。因此,当控件被放置在它应该放置的位置时,它也会被禁用或根据元数据设置 read-only,但如果许可信息限制对它的访问,整个功能将被隐藏。回到你的方法,这不是一个坏方法,我看到这是可以做到的。它可以通过两种方式完成,(从我的脑海中快速想到)。
- 使用用户控件作为您想要的组件的表面enable/disable。创建接口
public interface IDisableableControl // make your fine name, no methods needed - marker interface
. . . . .
public class MyFineUserControl : UserControl, IDisableableControl
然后在您要编写的 static
方法中传递表单,并找到实现此接口的所有控件并按您希望的方式工作。
2。
同样,您可以使用每个控件上可用的 属性 Tag
。这样,您实际上可以设置可以来自 DB-stored 元数据的复杂安全性 object,然后评估存储在 Tag
中的这个 object 以应用您的配置
你的方法需要递归
internal static void SetAllControls(Control parent)
{
// Do something with control, for example parent.Enabled = false
if (parent is IDisableableControl)
{
// here you use your logic, evaluate your parent you're dialing with and
// enable/disable correspondingly
parent.Enabled = false;
return;
}
foreach(var c in parent.Controls)
SetAllControls(c);
}
在现实生活中,您的 TOP parent 将是一种形式,不需要被禁用,但肯定 children 会。事实上,大多数时候,一旦你发现一个 UserControl
实现了 IDisableableControl
应该是行尾,这意味着你不需要进入 children 控件,因为它们都是坐在这个 parent 上,所有都将被禁用
我设法用下面的代码完成了我想做的事情,这几乎是我得到的所有有用答案的混合:
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;
}
}
}
欢迎社区提出改进建议,因为我远不是专业程序员。再次感谢大家。