一尘不染

C#中带有参数的“ UserControl”构造函数

c#

叫我疯了,但我是那种喜欢带参数的构造函数(如果需要)的人,而不是没有参数后再设置属性的构造函数。我的思考过程:如果需要属性来实际构造对象,则应将其放入构造函数中。我有两个优点:

  1. 我知道在构造对象时(没有错误/异常),我的对象很好。
  2. 它有助于避免忘记设置某些属性。

在表单/用户控件开发方面,这种心态开始伤害我。想象一下UserControl

public partial class MyUserControl : UserControl
{
  public MyUserControl(int parm1, string parm2)
  {
    // We'll do something with the parms, I promise
    InitializeComponent();
  }
}

在设计时,如果将其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();
  }
}

不包括无参数构造函数的全部目的是避免使用它。而且我什DesignMode至不能使用该属性来做类似的事情:

public partial class MyUserControl : UserControl
{
  public MyUserControl()
  {
    if (this.DesignMode)
    {
      InitializeComponent();
      return;
    }

    throw new Exception("Use constructor with parameters");
  }
}

这也不起作用:

if (LicenseManager.UsageMode == LicenseUsageMode.Designtime)

很好,继续前进…

我有我的无参数构造函数,可以将其放在表单上,​​表单的形式InitializeComponent如下:

private void InitializeComponent()
{
  this.myControl1 = new MyControl();

  // blah, blah
}

并相信我,因为我做到了(是的,忽略了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);  
}

对于UserControl要在构造函数中使用with参数的情况,我必须添加第二个不需要的构造函数?并实例化控件两次?

我觉得我一定做错了。有什么想法吗?意见?保证(希望)?


阅读 632

收藏
2020-05-19

共1个答案

一尘不染

有关Windows窗体工作方式的设计决策或多或少排除了Windows窗体组件的参数化.ctors。您可以使用它们,但是当您这样做时,便会超出公认的机制。而是Windows窗体更喜欢通过属性初始化值。如果未广泛使用,这是一种有效的设计技术。

不过,这有一些好处。

  1. 易于客户使用。客户端代码不需要跟踪一堆数据,它可以立即创建某些内容,并以有意义(如果不感兴趣)的结果来查看它。
  2. 设计者易于使用。通常,设计器代码更清晰,更易于解析。
  3. 阻止单个组件中异常的数据依赖关系。(尽管甚至Microsoft都用吹灭了它SplitContainer

表单中也有很多支持,可以与设计师一起使用此技术。,和这样的东西DefaultValueAttribute,使您有机会以最小的努力提供丰富的客户体验。DesignerSerializationVisibilityAttributeBrowsableAttribute

(这并不是在Windows窗体中为客户体验做出的唯一折衷。抽象基类组件也可能变得很笨拙。)

我建议坚持使用无参数构造函数,并在Windows窗体设计原则中进行工作。如果UserControl必须执行一些实际的先决条件,则将它们封装在另一个类中,然后通过一个属性将该类的实例分配给您的控件。这也将更好地分离关注点。

2020-05-19