【问题标题】:WinForms Inheritance InitializeComponentWinForms 继承 InitializeComponent
【发布时间】:2017-08-13 14:19:24
【问题描述】:

我有一个 BaseForm,它指定了几个在 BaseForm.InitializeComponent() 中初始化的受保护控件。我已经对这些控件进行了保护,以便我可以在我的 DerivedForm 中访问下拉列表等的值。使 DerivedForm 可以访问这些控件会导致设计器将它们包含在 DerivedForm.InitializeComponent() 中,这会重置它们,从而撤消我在 BaseForm 构造函数中所做的任何额外工作。

有没有办法在 DerivedForm 中访问我的 BaseForm 控件,但不能再次初始化它们?

    public SettingsDialogBase(Settings settings)
    {
        InitializeComponent();

        // Additional work which initializes dropdowns, etc
        InitializeSettings();
    }

    public SettingsDialog(Settings settings) : base(settings)
    {
        InitializeComponent();
        // InitializeSettings() rendered useless on controls that are set to protected
        // because SettingsDialog.InitializeComponent() included them automatically
    }

【问题讨论】:

  • Windows Form inheritance的可能重复
  • 嗯,我不这么认为。我的 BaseForm 和 DerivedForm 都成功调用了它们自己的 InitializeComponent() 方法。问题是 BaseForm 构造函数在 InitializeComponent() 之后对控件进行了额外的工作,并且由于它们是受保护的控件,因此 DerivedForm 在调用自己的 InitializeComponent() 方法时会撤消所有工作。
  • 从派生类的构造函数中移除InitializeComponent()
  • 我的 DerivedForm 具有特定于它的组件需要初始化....
  • 初始化组件并不是一个神奇的方法。它通常在表单设计器文件中生成,但您不需要拥有设计器文件。如果您愿意,可以将它们全部内联到主 .cs 文件中。如果您必须按照自己的方式做事,为什么不编写两个版本的 InitializeComponent 并让每个类调用自己的版本?

标签: c# .net winforms visual-studio inheritance


【解决方案1】:

我已将这些控件设为受保护,以便我可以访问下拉菜单的值

你的问题。

不要进行这些控件protected。将它们 private 保留在基类中。将它们完全公开给子类:通过将对控件的访问包装在公共属性中,允许访问那些需要访问的控件的方面。

例如:

class BaseForm : Form
{
    public string PromptText
    {
        get { return textBox1.Text; }
        set { textBox1.Text = value; }
    }

    public int SelectedIndex
    {
        get { return comboBox1.SelectedIndex; }
        set { comboBox1.SelectedIndex = value; }
    }

    // etc.
}

请注意,如果像 ComboBox 这样的东西使用例如枚举值,您可以创建一个类似SelectedValue 的属性,当从comboBox1.SelectedValue 属性返回时具有枚举类型和强制转换。

另请注意,解决此类设计问题的另一种方法是编写UserControl 对象而不是表单,并使用组合来构建特定于任务的表单。这完全避免了继承。

【讨论】:

  • 我试图访问的大部分字段都是 ComboBox 控件,所以这将正常工作。我还发现将 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 添加到其他控件,如 GroupBox,似乎可以防止它在 DerivedForm.InitializeComponent() 中变得过于疯狂
【解决方案2】:

BaseForm 的 InitializeSettings 实现:

protected virtual void InitializeSettings(Settings settings)
{
    //initialization of settings
}

DerivedForm 的 InitializeSettings 实现:

protected override void InitializeSettings(Settings settings)
{
    base.InitializeSettings(x);
    //reinitialization of settings
}

在 DerivedForm 的构造函数中调用 InitializeSettings() 将设置您的设置。

好吧,我的目标还不清楚。

如果您只想对设置进行 1 次初始化,请不要在构造函数中应用它们。基本上,你应该使用

protected override void OnLoad(EventArgs e)
{
    base.OnLoad(e);
    //initialization of settings
}

解决问题的第二种方法是甚至没有参数化构造函数,并在默认构造函数创建表单后调用InitializeSettings。

【讨论】:

  • 所以我的组件还是被初始化了两次,然后设置被初始化了两次来弥补?我真的在寻找一次性完成组件和设置初始化的解决方案。具体来说,BaseForm 初始化其组件,而 DerivedForm 仅初始化其组件,而不是那些受保护的 BaseForm 组件。
猜你喜欢
  • 2012-11-16
  • 2019-12-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-13
  • 1970-01-01
  • 2011-12-10
  • 1970-01-01
相关资源
最近更新 更多