65.9K
CodeProject 正在变化。 阅读更多。
Home

VB.NET 中窗体继承的一切你想知道的 - “最佳”

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.40/5 (38投票s)

2003 年 10 月 20 日

9分钟阅读

viewsIcon

174596

downloadIcon

2333

如何在设计时编辑窗体中继承控件的属性。

Sample Image - BestFormInheritance.jpg

目录

  • 为什么需要窗体继承
  • 引言
  • 继承的概念
  • 可视化继承
  • 如何继承窗体
  • 如何创建自定义属性
  • 如何在子窗体中使用自定义属性
  • 如何从父窗体更改不在父窗体中的控件(即在子窗体中)的属性
  • 如何从子窗体覆盖父窗体的功能
  • 如何在设计时更改继承控件的属性(即如何重新定位控件、设置不同属性等)

为什么需要窗体继承?

那么,在阅读本文之前,最大的问题是——窗体继承的必要性是什么。

首先,我们将所有基础/通用代码编写到基窗体(任何我们想要从中继承的窗体)中。然后,而不是复制或编写一些全局函数来更改属性或调用方法等来使用基窗体的一些功能(就像我们在以前的语言中那样),我们可以在这里使用窗体继承。

我们可以将基窗体继承到我们想要实现通用功能的窗体中。当我们继承窗体时,基窗体的所有公共/受保护的功能都会合并到子窗体中。

例如:在一个常见的场景中,我们需要在应用程序中设计导航面板,以便在记录之间导航。以前,为了避免重复代码,我们使用了 ActiveX 控件。我们先设计导航的 ActiveX 控件,然后将其放置在我们想要实现该功能的窗体上。

但这次,我们可以将导航面板的功能编写到基窗体中,然后继承该窗体以在子窗体中实现类似功能,并充分利用窗体继承。

在大多数情况下,当您想在项目中提供导航面板、状态栏、信息标签等功能时,您可以在那里使用窗体继承。将所有这些功能都编写在基窗体中,然后将基窗体继承到您想要实现相同功能的窗体中。如果您愿意,还可以从子窗体覆盖基窗体的部分/全部功能,而不会影响基窗体。

现在您已经知道为什么应该阅读本文。所以,伙计们,您可以尽情阅读。

引言

VB 程序员发生的最大变化是,当微软宣布推出新的 VB.NET 来成为我们最喜欢的编程语言 Visual Basic 的最佳继承者时。

VB 缺乏的是 INHERITANCE 的强大功能,因此微软决定在 VB.NET 中实现继承。每次我们在应用程序中需要一个新窗体时,我们都会创建一个 System.Windows.Forms.Form 类的实例,更改其属性以满足我们的需求。放置一些控件,我们的窗体就可以使用了。我们知道,通过将一些控件放置到一个新窗体上,我们就将窗体类扩展为 NewForm1,这意味着我们创建了一个名为 NewForm1 的新类。我们的新窗体是一个类,由于 .NET 支持继承,我们可以扩展任何类。

因此,我们可以得出结论,我们可以设计基窗体并在所有窗体中使用基窗体设计。

就像我们有:

基窗体

Public Class PMainForm
    Inherits System.Windows.Forms.Form

子窗体

Public Class ChildForm
    Inherits PmainForm

现在我们可以按照我们期望的方式使用子窗体。我们可以对子窗体做的事情:在子窗体本身中覆盖基窗体功能(即使用子窗体中函数的 Shadows 关键字 - 我们将在本文后面详细介绍),我们可以为基窗体添加自定义属性并在子窗体中设置它们(用于控制原始不在父窗体中的控件),以及我们想要的一切。

继承的概念

我知道,OO 程序员必须了解 INHERITANCE 的一切。本节尤其针对非 OO 编程的程序员,因此经验丰富的 OO 程序员可以跳过本节。

定义(继承):继承是一种机制,允许类 A 继承类 B 的属性。我们说“A 继承自 B”。因此,类 A 的对象可以访问类 B 的属性和方法,而无需重新定义它们。 以下定义了两个术语,当我们使用继承时,我们可以称呼参与的类。

定义(超类/子类):如果类 A 继承自类 B,则 B 被称为 A 的超类。A 被称为 B 的子类。子类的对象可以在预期超类对象的地方使用。这是因为子类的对象与超类的对象具有相同的行为。

超类称为父类。子类可以称为子类派生类

当然,您可以再次从子类继承,使该类成为新子类的超类。这就导致了超类/子类关系的层次结构。如果您绘制此层次结构,您将得到一个继承图

一种常见的绘图方案是使用带箭头的线来指示两个类或对象之间的继承关系。

可视化继承

我们知道如何创建类的对象。以类似的方式,我们也可以继承窗体,我发誓我没有开玩笑。

是否可以继承父窗体的组件?

是的,这是可能的。但是继承控件并不意味着我们能够在子窗体中看到这些控件,因为我们继承了控件,但没有继承我们在父窗体中设置的那些控件的属性。也就是说,假设我们在父窗体中放置了一个按钮。它的顶部位置是 200px。这并不意味着如果我们为子类继承父窗体,我们将能够看到相同的按钮在相同的位置(即 Button1.Top = 200)。

那么,这一切是如何发生的呢?我们如何才能在子窗体中看到父窗体的控件在相同的位置。

VS.NET 通过在子窗体中重新定位控件来实现这一点。您可以亲身体验。去父窗体中更改位置,并且不要构建父窗体。现在打开子窗体,看看按钮位置的差异,它在旧位置。

这意味着,即使我们在父窗体中更改了按钮的位置,它也没有改变。因此,VS.NET 在我们编译父窗体时,它会重置子窗体中控件的属性。

现在你们都知道 VS.NET 是如何实现可视化继承的。

本文新增内容

如果您只是继承窗体,您将无法更改在基窗体中放置的控件的属性。此示例涵盖

  1. 如何继承窗体?
  2. 如何创建自定义属性?
  3. 如何在子窗体中使用自定义属性?
  4. 您如何从父窗体更改不在父窗体中的控件(即在子窗体中)的属性?
  5. 如何从子窗体覆盖父窗体功能?
  6. 如何在设计时更改继承控件的属性?(即如何重新定位控件、设置不同属性等)
 
  1. 如何继承窗体?

    打开子窗体,将子窗体的 Inherits 行从 <System.Windows.Forms.Form> 替换为 <父窗体名称>。

    基窗体

    Public Class PMainForm
        Inherits System.Windows.Forms.Form

    子窗体

    Public Class ChildForm
        Inherits PmainForm
  2. 如何创建自定义属性?

    打开父窗体并创建一个属性(作用域为 Protected Friend)。

        'CurrentPosition Property
        Dim LPosition As Long
        Protected Property Position() As Long
            Get
                Return LPosition
            End Get
            Set(ByVal Value As Long)
                LPosition = Value
            End Set
        End Property
  3. 如何在子窗体中使用自定义属性?

    打开子窗体。使用 Me.<propertyName> 更改属性。例如:我们在子窗体的 Load 事件中更改属性。

    Private Sub CForm3_Load(ByVal sender As System.Object, _ 
        ByVal e As System.EventArgs) Handles MyBase.Load
            Me.Position = 99
    End Sub
  4. 您如何从父窗体更改不在父窗体中的控件(即在子窗体中)的属性?

    在父窗体中定义一个接受 <Control> 作为返回类型的属性。

        'InfoLabel Property (Control which 
       'we want to use from the child form)
        Dim localLabel As Label
        Protected Property InfoLabel() As Label
            Get
                Return localLabel
            End Get
            Set(ByVal Value As Label)
                localLabel = Value
            End Set
        End Property

    现在,打开子窗体。放置您想与父窗体一起使用的控件。在子窗体的任何事件中,为父窗体更改 Child Form 的 ControlProperty。在本例中,我在子窗体的 load 事件中进行了此操作。

    Private Sub CForm3_Load(ByVal sender As System.Object, _
            ByVal e As System.EventArgs) Handles MyBase.Load
        Me.InfoLabel = Label1 
        'Control to be controlled by the Parent Form
        
        Me.Position = 99
    End Sub
  5. 如何从子窗体覆盖父窗体功能?

    覆盖父窗体中处理特定功能的函数(例如,父窗体中按钮的单击事件)。

    如果您复制并粘贴该函数从父窗体。请不要忘记添加 Shadows 属性,以禁止父窗体中的函数(注意:当我们使用 Shadows 关键字时,在父窗体中无需为该函数使用 Overridable 关键字)。

    父窗体

    子窗体

    'Overiding the implementation of the Parent Form
    'please don't forget to remove the handles keyword from the last while
    'implementing in the child form
     
    Protected Friend Overrides Sub BParent_Click(ByVal sender _ 
        As System.Object, ByVal e As System.EventArgs)
    MsgBox("Functionality of Child is used.")
    End Sub

    或者

    Protected Friend Shadows Sub BParent_Click(ByVal _ 
           sender As System.Object, ByVal e As System.EventArgs)
      MsgBox("Functionality of Child is used.")
    End Sub
  6. 如何在设计时更改继承控件的属性?(即如何重新定位控件、设置不同属性等)

    继承任何 ParentForm 的主要问题 - 非常简单。将我们想从 Child Form 控制的控件的 Modifiers 属性从 Friend 更改为 Protected Friend。

注意:Protected Friend 不会列在那里,所以请多费点心执行以下步骤。

  1. 打开父窗体的代码窗口。
  2. 展开“Windows Form Designer generated code”部分。
  3. 找到 InitializeComponent() 函数。
    <System.Diagnostics.DebuggerStepThrough()> _ 
      Private Sub InitializeComponent()
  4. 在此函数上方,您将找到放置在窗体中的控件的初始化代码。它们将是这样的
    'NOTE: The following procedure is required by the Windows Form Designer
        'It can be modified using the Windows Form Designer.  
        'Do not modify it using the code editor.
        Friend WithEvents Button1 As System.Windows.Forms.Button
        Friend WithEvents PBNavPrev As System.Windows.Forms.Button
        Friend WithEvents NavCaption As System.Windows.Forms.Label
     
        Friend WithEvents BParent As System.Windows.Forms.Button
        Friend WithEvents NavPanel As System.Windows.Forms.Panel
        <System.Diagnostics.DebuggerStepThrough()> _ 
          Private Sub InitializeComponent()

    更改控件的访问修饰符为 Protected Friend,以便在子窗体中共享它们。

  5. 'NOTE: The following procedure is required by the Windows Form Designer
        'It can be modified using the Windows Form Designer.  
        'Do not modify it using the code editor.
        Protected Friend WithEvents Button1 As System.Windows.Forms.Button
        Protected Friend WithEvents PBNavPrev As System.Windows.Forms.Button
        Protected Friend WithEvents NavCaption As System.Windows.Forms.Label
     
        Protected Friend WithEvents BParent As System.Windows.Forms.Button
        Protected Friend WithEvents NavPanel As System.Windows.Forms.Panel
        <System.Diagnostics.DebuggerStepThrough()> _
           Private Sub InitializeComponent()
 

为了完全理解这个概念,您可以下载附带的应用程序。这将为您提供更好的窗体继承视图。

好吧,伙计们,就这样。希望本文能让您更好地理解窗体继承的内部工作原理。以及如何利用 VS.NET 的可视化窗体继承功能的优势。

请不要忘记给本文评分,这样我才能继续写作,提高自己,并为您呈现一些“最佳”内容。如果您有任何疑问,请随时通过 saurabh.verma@india.rsystems.com 与我联系。我将感到非常荣幸。您可以从下载文件中提供的 Readme.doc 中阅读整个文章。

那么,现在去享受这些吧。我很快就会带着一些关于 ADO.NET 的“最佳”代码示例回来,在此之前,请保重。再见。

© . All rights reserved.