代码之家  ›  专栏  ›  技术社区  ›  Seth Spearman

Winforms用户控件未使用我创建的继承树。我做错什么了

  •  0
  • Seth Spearman  · 技术社区  · 16 年前

    我正在开发一个向导窗体框架,它允许我轻松地创建向导窗体。

    我有一个向导窗体,上面有一个面板。

    我的计划是动态地将用户控件加载到表单上的这个面板中。

    加载到表单面板上的每个用户控件必须实现某些属性(allownavigatenext、allownavigate previous等)。因此,我创建了一个接口来强制执行该约定,以便任何自定义用户控件都可以在向导中使用,只要它实现了该接口。到现在为止,一直都还不错。

    我创建了我的第一个用户控件。我实现了接口。一切都很好。

    我开始做第二个用户控件,我意识到第二个用户控件将具有与第一个用户控件完全相同的接口实现。所以……我想……啊哈……重复的代码……我怎么能摆脱它呢?

    所以…

    我创建了一个新的用户控件,并将其命名为usercontrolwizardbase。我让这个新的usercontrolwizardbase继承了同一个接口,并在其中放置了与前两个相同的实现。

    然后我回到自定义用户控件1和2。我删除了其中的接口实现和接口语句。我进入了每个的设计器文件,并将每个的继承从usercontrol更改为usercontrolwizardbase。

    直到我添加了一个这样调用基构造函数的公共构造函数,它才完全编译…

    public sub new(byval shownavigatecancel as boolean,)_ ByVal ShowNavigateFinish作为布尔值,_ ByVal ShowNavigateNext作为布尔值,_ ByVal ShowNavigatePrevious作为布尔值)

        MyBase.New(showNavigateCancel, _
                        showNavigateFinish, _
                        showNavigateNext, _
                        showNavigatePrevious)
    

    结束子

    (那时我知道您不能继承基类的构造函数。或者你能和我只是不知道我在做什么吗?)

    在任何情况下…现在所有编译…实际上根本没有运行时错误。但当我运行代码并通过加载到向导窗体上的面板来加载CustomUserControl 1时…它根本不加载CustomUserControl,而是加载UserControlWizardbase。

    现在希望你能理解我的问题,你能给我指明正确的方向来解决它。

    编辑-更多信息

    我更接近于对这个问题有所了解。这就是问题所在。将用户控件加载到“我的向导”窗体面板的代码如下

            Public Sub InitUserControl(ByVal wizardUserControl As UserControl)
    
        wizardUserControl.Dock = DockStyle.Fill
    
        Try
    
            Dim iwp As IWizardUserControl = DirectCast(wizardUserControl, IWizardUserControl)
            _wizardDialog.NavigatePrevious.Enabled = iwp.ShowNavigatePrevious
            _wizardDialog.NavigateNext.Enabled = iwp.ShowNavigateNext
            _wizardDialog.NavigateFinish.Enabled = iwp.ShowNavigateFinish
            _wizardDialog.NavigateCancel.Enabled = iwp.ShowNavigateCancel
            TryCast(_wizardDialog, Form).Text = iwp.StepCaption
            _wizardDialog.PageDescription.Text = iwp.Description
            _wizardDialog.PictureBox.Image = iwp.PageImage
            _wizardDialog.PageHelpText.Text = iwp.PageHelpText
            _wizardDialog.UIRoot.Controls.Clear()
            _wizardDialog.UIRoot.Controls.Add(wizardUserControl)
    
        Catch
            ' Do Nothing
        End Try
    
        End Sub
    

    您看到问题了吗…例程正在传入一个用户控件,然后将其强制转换为IwizardUserControl类型。

    问题是它需要将特定类型加载到面板中,而不是接口或用户控件类型。但是,如何在不将它与IwizardUserControl的特定实现联系起来的情况下做到这一点呢?

    帮助。你看,我还在学OOP。

    另一个编辑-更多信息
    让我描述一下问题的性质。这里看到的代码没有运行时错误。但它正在加载基类型而不是派生类型,即使initUserControl正在传递一个派生类型。(我知道,因为如果我在那里放置一个断点并钻取到类型中,它显示的类型不是UserControlWizardBase,而是正确的类型,它是派生类型之一…在本例中是SetupWizardStartPage)。

    请记住,setupwizardstartpage有一个大标签,它有一个大字体和许多描述向导功能的文本。

    但当它加载时,没有显示任何内容。如果我试着看看那个描述标签是否在那里,它就不在那里。我在UserControlWizardBase中实现的唯一控件是什么?

    这就是我如何知道基本控件而不是派生控件正在加载到面板中的原因。尽管如此,如果我查询wizardUserControl,它显示的是派生类型而不是基类型。

    塞思

    3 回复  |  直到 16 年前
        1
  •  0
  •   drs9222    16 年前

    您是正确的,因为您不能继承构造函数。
    我打赌它正在加载您的类,但它将它显示为一个UserControlWizardBase。尝试将其强制转换到接口或基类( UserControlWizardBase.TryCast(control) )

        2
  •  0
  •   Adam Robinson    16 年前

    我看不出你的实现有什么问题,除了你真的应该传入 wizardUserControl Controls.Add 不是 iwp . 除此之外,你还遇到了什么特殊的问题?

        3
  •  0
  •   Seth Spearman    16 年前

    我觉得自己真的很傻。问题是,调用基本构造函数的代码行 MyBase.NEW 应该后跟它自己的初始化组件。唯一被调用的初始化组件是基类,而不是派生类。

    杜赫。

    塞思

    推荐文章