【问题标题】:Shared Base Class for numerous winforms UserControls?许多winforms UserControls的共享基类?
【发布时间】:2021-01-15 21:03:28
【问题描述】:

当我找到答案时,感觉就像我要踢自己一样。我希望一些用户控件共享一些属性(如 ID)和事件(即它们都会引发相同的事件)。我尝试创建一个 BaseClass UserControl,然后在我的 UserControls 上尝试 Inherits BaseClass。但是,我得到了错误:

为 Class Viewer 指定的基类“BaseClass”不能是 不同于其其他之一的基类UserControl 部分类型。

我在这里错过了什么?

编辑:为清楚起见,添加一些代码。希望这能说明我希望它如何工作:

Public Class BaseUserControl
    Inherits UserControl

    Public Property ID
    Public Event ItemSelected()

End Class

Public Class Browser
    Inherits BaseUserControl

    Private Sub ButtonPressed() Handles Button1.click

        RaiseEvent ItemSelected()

    End Sub
End Class

Public Class NavBar
    Inherits BaseUserControl

    Private Sub EnterKeyDown() Handles TextBox1.KeyDown

        RaiseEvent ItemSelected()

    End Sub
End Class

Public Class Main

    Dim WithEvents browser As Browser With {.id = 12}
    Dim WithEvents navbar As NavBar With {.id = 624}

    Public Sub New()

        Me.controls.add(browser)
        Me.controls.add(navbar)

    End Sub

    Private Sub SelectionInBrowser() Handles brower.ItemSelected
        'Do amazing stuff
    End Sub

    Private Sub SelectionInNavBar() Handles navbar.ItemSelected
        'Do amazing stuff
    End Sub

End Class

【问题讨论】:

    标签: c# vb.net inheritance user-controls partial


    【解决方案1】:

    您必须将基类创建为UserControl。例如。将其命名为BaseUserControl。编译它。然后右键单击项目或项目中的文件夹,然后单击Add > New Item。然后选择左侧的Windows Forms,然后选择Inherited User Control (Windows Forms)。给它一个名字,然后点击 Add 按钮。现在将打开一个对话框,您可以在其中选择您的BaseUserControl。然后单击确定。 Visual Studio 为您提供了一些魔法。例如。它覆盖了设计器生成的代码中的Dispose。您可以手动完成,但像这样您可以免费获得它。

    您可以在BaseUserControl 上放置控件。它们将被继承并在派生用户控件中可见。

    请注意,您必须将基本用户控件中的控件修饰符更改为ProtectedProteced FriendPublic,以使它们能够在继承的用户控件中进行修改。


    继承示例。在BaseUserControl 中,我放置了两个按钮Button1Button2 并让它们Protected 使它们在派生类中可见。然后我双击Button1。这将创建一个 Button1_Click 事件处理程序。我把它的签名改成了

    Public Class BaseUserControl
        Protected Overridable Sub Button1_Click(sender As Object, e As EventArgs) _
            Handles Button1.Click
    
            MessageBox.Show($"Hello from {NameOf(BaseUserControl)}.{NameOf(Button1_Click)}")
        End Sub
    End Class
    

    即,设为Protected Overridable。这不是绝对必要的,但它允许您在后代中覆盖它。

    保存并编译,然后打开MyUserControl,其中两个按钮可见。点击Button2,它还没有点击事件处理程序来创建一个。

    Public Class MyUserControl
        Private Sub Button2_Click(sender As Object, e As EventArgs) _
            Handles Button2.Click
    
            MessageBox.Show($"Hello from {NameOf(MyUserControl)}.{NameOf(Button2_Click)}")
        End Sub
    
        Protected Overrides Sub Button1_Click(sender As Object, e As EventArgs)
            MyBase.Button1_Click(sender, e)
            MessageBox.Show($"Hello from {NameOf(MyUserControl)}.{NameOf(Button1_Click)}")
        End Sub
    End Class
    

    如您所见,我也确实覆盖了Button1_ClickMyBase.Button1_Click(sender, e)BaseUserControl 调用原始实现。

    然后我将MyUserControl 放在表单上并启动应用程序。点击Button1首先显示:

    来自 BaseUserControl.Button1_Click 的问候

    在关闭第一个消息框后点击OK

    来自 MyUserControl.Button1_Click 的问候

    点击Button2 显示:

    来自 MyUserControl.Button2_Click 的问候

    【讨论】:

    • 嘿。当您输入 Olivier 时,我正在更新我的帖子。谢谢你 - 我会试一试,虽然我想我要放弃这个晚上,因为所有编码之王今天一直是一个正确的 git。会反馈
    • 无法抗拒。绝对完美的答案@Olivier - 谢谢。有趣的东西。您可以在 BaseClass 中放置属性和控件,但不能在事件中放置。我敢肯定这在某处是有逻辑的。我还有一个我已经做了很多工作的 UserControl。我刚刚打开它的 Designer.vb 并将顶部附近的继承从 System.Windows.Forms.UserControl 更改为我的完整 BaseUserControl 路径 + 做到了!再次感谢。
    • 你可以把所有东西都放在基类中,甚至是事件。
    • 很奇怪,那个。当我昨晚这样做时,我收到一个错误(想想编译),说无法将事件存储在基类中+在继承的基类中引用它们。但是,在仅修改设计器代码而不是通过菜单路线之后,我无法让它重现该错误。所以我的基类中有TestEvent,但它没有在我的派生类中公开。我得再看看这个......
    • 在引发事件的名为OnTestEvent 的基类中创建一个公共或受保护的方法。然后你可以在派生类中调用这个。 Step by Step: Event handling in VB.NET.
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-16
    • 2010-10-30
    • 2011-02-22
    • 1970-01-01
    相关资源
    最近更新 更多