Jus*_*ing 97 c# parameters user-controls constructor winforms
叫我疯了,但我喜欢那种喜欢带参数的构造函数(如果需要)的人,而不是没有参数的构造函数,后跟设置属性.我的思考过程:如果需要实际构造对象的属性,它们应该进入构造函数.我有两个好处:
这种心态开始在形式/用户控制开发方面受到伤害.想象一下UserControl
:
public partial class MyUserControl : UserControl
{
public MyUserControl(int parm1, string parm2)
{
// We'll do something with the parms, I promise
InitializeComponent();
}
}
Run Code Online (Sandbox Code Playgroud)
在设计时,如果我将其UserControl
放在表单上,我得到一个Exception
:
无法创建组件'MyUserControl'...
System.MissingMethodException - 没有为此对象定义的无参数构造函数.
对我来说,似乎唯一的办法是添加默认构造函数(除非其他人知道某种方式).
public partial class MyUserControl : UserControl
{
public MyUserControl()
{
InitializeComponent();
}
public MyUserControl(int parm1, string parm2)
{
// We'll do something with the parms, I promise
InitializeComponent();
}
}
Run Code Online (Sandbox Code Playgroud)
不包括无参数构造函数的重点是避免使用它.我甚DesignMode
至无法使用该属性执行以下操作:
public partial class MyUserControl : UserControl
{
public MyUserControl()
{
if (this.DesignMode)
{
InitializeComponent();
return;
}
throw new Exception("Use constructor with parameters");
}
}
Run Code Online (Sandbox Code Playgroud)
这也不起作用:
if (LicenseManager.UsageMode == LicenseUsageMode.Designtime)
Run Code Online (Sandbox Code Playgroud)
很好,继续......
我有我的无参数构造函数,我可以将它放在表单上,表单InitializeComponent
将如下所示:
private void InitializeComponent()
{
this.myControl1 = new MyControl();
// blah, blah
}
Run Code Online (Sandbox Code Playgroud)
并且相信我,因为我做到了(是的,忽略了Visual Studio生成的评论),我试着搞乱并且我传递参数InitializeComponent
以便我可以将它们传递给构造函数MyControl
.
这让我想到了这个:
public MyForm()
{
InitializeComponent(); // Constructed once with no parameters
// Constructed a second time, what I really want
this.myControl1 = new MyControl(anInt, aString);
}
Run Code Online (Sandbox Code Playgroud)
对于我使用UserControl
带参数的构造函数,我必须添加一个我不需要的第二个构造函数?并实例化控件两次?
我觉得我一定做错了.思考?意见?保证(希望)?
Gre*_*g D 62
关于Windows窗体的工作方式的设计决策或多或少地排除了Windows窗体组件的参数化.ctors.你可以使用它们,但是当你这样做时,你会走出普遍认可的机制.相反,Windows窗体更喜欢通过属性初始化值.如果没有广泛使用,这是一种有效的设计技术.
不过,这有一些好处.
SplitContainer
)在这种技术中,与设计师合作的形式也有很多支持.之类的东西DefaultValueAttribute
,DesignerSerializationVisibilityAttribute
和BrowsableAttribute
给你机会,提供以最小的努力丰富的客户体验.
(这不是Windows窗体中客户端体验的唯一妥协.抽象基类组件也会变得毛茸茸.)
我建议坚持使用无参数构造函数并在Windows窗体设计原则中工作.如果存在UserControl
必须强制实际的先决条件,请将它们封装在另一个类中,然后通过属性将该类的实例分配给您的控件.这样可以更好地分离关注点.
Kev*_*ler 36
设计类有两种竞争范式:
在Visual Studio中的Windows窗体设计器迫使你提供一个控制参数的constuctor才能正常工作.实际上,它只需要一个无参数构造函数来实例化控件,而不是设计它们(设计器实际上会在设计控件时解析InitializeComponent方法).这意味着您可以使用设计器来设计没有无参数构造函数的表单或用户控件,但是您无法设计另一个控件来使用该控件,因为设计器将无法实例化它.
如果您不打算以编程方式实例化控件(即"手动"构建UI),则不必担心创建参数化构造函数,因为它们不会被使用.即使您要以编程方式实例化控件,也可能需要提供无参数构造函数,以便在需要时仍可以在设计器中使用它们.
无论您使用哪种范例,在OnLoad()
方法中放置冗长的初始化代码通常也是一个好主意,特别是因为DesignMode
属性将在加载时工作,但在构造函数中不起作用.
我会推荐
public partial class MyUserControl : UserControl
{
private int _parm1;
private string _parm2;
private MyUserControl()
{
InitializeComponent();
}
public MyUserControl(int parm1, string parm2) : this()
{
_parm1 = parm1;
_parm2 = parm2;
}
}
Run Code Online (Sandbox Code Playgroud)
这样,始终首先调用基础构造函数,并且对组件的任何引用都是有效的.
然后,如果需要,您可以重载公共ctor,确保控件始终使用正确的值进行实例化.
无论哪种方式,您都可以确保永远不会调用无参数ctor.
我没有测试过,所以如果它失败了我道歉!
不幸的是,这是一个经常发生的设计问题,而不仅仅是在控制空间中。
通常情况下,您需要有一个无参数构造函数,尽管无参数构造函数并不理想。例如,在我看来,许多值类型如果没有无参数构造函数会更好,但不可能创建一种以这种方式工作的类型。
在这些情况下,您必须以尽可能最好的方式设计控件/组件。使用合理的(最好是最常见的)默认参数可以带来很大帮助,因为您至少可以(希望)用一个好的值来初始化组件。
另外,尝试以可以在生成组件后更改这些属性的方式设计组件。对于 Windows 窗体组件,这通常很好,因为您几乎可以在安全加载之前执行任何操作。
我再次同意——这并不理想,但这只是我们必须忍受和解决的问题。