正确的架构扩展WinForm UserControl基类

本文关键字:WinForm UserControl 基类 扩展 | 更新日期: 2023-09-27 18:06:43

我有很多非常相似的UserControls。它们有很多共同的行为。我一直在使用一个基类,它具有常见的东西,然后根据需要对类进行专门化。

class BaseControl : UserControl 
{
   // common
}  
class RedControl : BaseControl
{
   // specialized
}
class BlueControl : BaseControl
{
   // specialized
}

等等……

在我需要开始插入或更改BaseControl中包含的子控件的布局之前,这工作得相当好。例如,RedControl需要在基础控件的特定面板上添加一个Button。在其他情况下,我需要更改其他基本子控件的大小或布局。

当我尝试下面的代码时,我在运行时没有看到任何按钮…

public partial class RedControl : BaseControl
{
  public RedControl()
  {
    InitializeComponent();
    addButtonToBase();  // no button shows up 
    this.PerformLayout();
  }
  void addButtonToBase()
  {
    Button button  = new Button();
    button.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)));
    button.Location = new System.Drawing.Point(3, 3);
    button.Size = new System.Drawing.Size(23, 23);
    button.Text = "My Button";
    baseSplitContainer.Panel1.Controls.Add(button); // protected child control in base
  }
  // ...
}

可以使按钮显示为baseSplitContainer的子,如果我使addButtonToBase()虚拟并手动将其添加到BaseControl的InitalizeComponent()中生成的代码。BaseControl的布局还在继续,你可以在c# .Net的构造函数中调用虚函数....

所以即使它有效,它也不是一个好的解决方案。一方面,当我在VS设计器中编辑BaseControl时,initializecomponent中对addBaseControl()的调用被删除了,另一方面,在构造函数中调用虚函数感觉很危险。

我想我需要让基控件的布局再次发生在派生控件…我试过了,但要么做错了,要么行不通。

我知道WPF很擅长这个。由于其他系统的限制,不能使用它。

正确的架构扩展WinForm UserControl基类

修改基本控件布局的正确方法是重写control . onlayout ()

中的布局调用

所以像

public RedControl()
{
    //....
    protected override void OnLayout(LayoutEventArgs e)
    {
        addButtonToBase(); // modify base layout
        base.OnLayout(e);
    }
}

我认为你只是错过了一些调用基本初始化逻辑来创建控件的东西,然后你的更改被覆盖。试着把它命名为

public RedControl()
: base()
  { ... }

public RedControl()
  {
    base.InitializeComponent();
    InitializeComponent();
    addButtonToBase();  // no button shows up 
    this.PerformLayout();
  }