带有 C# 参数的“UserControl"构造函数 [英] 'UserControl' constructor with parameters in C#

查看:30
本文介绍了带有 C# 参数的“UserControl"构造函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

说我疯了,但我是那种喜欢带参数的构造函数(如果需要)的人,而不是不带参数的构造函数,然后设置属性.我的思考过程:如果实际构造对象需要属性,它们应该放在构造函数中.我有两个好处:

Call me crazy, but I'm the type of guy that likes constructors with parameters (if needed), as opposed to a constructor with no parameters followed by setting properties. My thought process: if the properties are required to actually construct the object, they should go in the constructor. I get two advantages:

  1. 我知道当一个对象被构造时(没有错误/异常),我的对象是好的.
  2. 这有助于避免忘记设置某个属性.

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

This mindset is starting to hurt me in regards to form/usercontrol development. Imagine this UserControl:

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

在设计时,如果我将此 UserControl 放在表单上,​​我会得到 Exception:

At designtime, if I drop this UserControl on a form, I get an Exception:

未能创建组件MyUserControl"...
System.MissingMethodException - 没有为此对象定义无参数构造函数.

Failed to create component 'MyUserControl' ...
System.MissingMethodException - No parameterless constructor defined for this object.

在我看来,唯一的解决方法是添加默认构造函数(除非其他人知道方法).

It seems like, to me, the only way around that was to add the default constructor (unless someone else knows a way).

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 属性来做类似的事情:

The whole point of not including the parameterless constructor was to avoid using it. And I can't even use the DesignMode property to do something like:

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 将如下所示:

I have my parameterless constructor, I can drop it on the form, and the form's InitializeComponent will look like this:

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

  // blah, blah
}

相信我,因为我做到了(是的,忽略了 Visual Studio 生成的评论),我试着搞砸了,我将参数传递给 InitializeComponent 以便我可以将它们传递给 InitializeComponent 的构造函数代码>MyControl.

And trust me, because I did it (yes, ignoring the comments Visual Studio generated), I tried messing around and I passed parameters to InitializeComponent so that I could pass them to the constructor of MyControl.

这导致我这样做:

public MyForm()
{
  InitializeComponent(); // Constructed once with no parameters

  // Constructed a second time, what I really want
  this.myControl1 = new MyControl(anInt, aString);  
}

为了让我使用带有参数的 UserControl 构造函数,我必须添加第二个我不需要的构造函数吗?并实例化控件两次?

For me to use a UserControl with parameters to the constructor, I have to add a second constructor that I don't need? And instantiate the control twice?

我觉得我一定做错了什么.想法?意见?保证(希望如此)?

I feel like I must be doing something wrong. Thoughts? Opinions? Assurance (hopefully)?

推荐答案

关于 Windows 窗体工作方式的设计决策或多或少排除了 Windows 窗体组件的参数化 .ctors.您可以使用它们,但是当您使用它们时,您会超出通常批准的机制.相反,Windows 窗体更喜欢通过属性初始化值.这是一种有效的设计技术,即使没有被广泛使用.

Design decisions made regarding the way Windows Forms works more or less preclude parameterized .ctors for windows forms components. You can use them, but when you do you're stepping outside the generally approved mechanisms. Rather, Windows Forms prefers initialization of values via properties. This is a valid design technique, if not widely used.

不过,这有一些好处.

  1. 易于客户使用.客户端代码不需要追踪一堆数据,它可以立即创建一些东西,然后用合理的(如果无趣的)结果来查看它.
  2. 设计人员易于使用.总体而言,设计器代码更清晰、更易于解析.
  3. 不鼓励在单个组件中出现异常的数据依赖关系.(虽然连微软都用 SplitContainer)

在表单中也有很多支持与设计人员在此技术中正常工作.DefaultValueAttribute 之类的东西,DesignerSerializationVisibilityAttribute,以及 BrowsableAttribute 给你机会以最少的努力提供丰富的客户体验.

There's a lot of support in forms for working properly with the designer in this technique also. Things like DefaultValueAttribute, DesignerSerializationVisibilityAttribute, and BrowsableAttribute give you the opportunity to provide a rich client experience with minimal effort.

(这不是为 Windows 窗体中的客户端体验做出的唯一妥协.抽象基类组件也可能会变得很麻烦.)

(This isn't the only compromise that was made for client experience in windows forms. Abstract base class components can get hairy too.)

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

I'd suggest sticking with a parameterless constructor and working within the windows forms design principles. If there are real preconditions that your UserControl must enforce, encapsulate them in another class and then assign an instance of that class to your control via a property. This will give a bit better separation of concern as well.

这篇关于带有 C# 参数的“UserControl"构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆