【问题标题】:Can I create a property of a property?我可以创建属性的属性吗?
【发布时间】:2013-04-03 23:12:47
【问题描述】:

所以我最近掌握了在我的 Visual Basic 编程中使用类的概念,我发现它非常有用。在我当前的项目中,我有几个复选框组框(每个复选框表示一个“行为”),并且在每个组框中,总是有一个复选框具有文本框控件而不是标签(允许用户指定“其他”行为)。正是那个用户生成的标签给我带来了麻烦......

我创建了一个名为“行为”的类,它基本上执行以下操作:

  1. getChecked > 此方法获取每个选中的复选框并将其添加到 给定表单的 BehaviorCollection。
  2. behaviorCollection > 表示选中的集合 复选框。
  3. getOtherChecked > 的作用与“getChecked”相同,除了 “其他行为”复选框。
  4. otherBehaviorCollection > 表示选中的集合 “其他”复选框。

问题是对于每个选中的“其他行为”复选框,我需要存储其对应文本框的值。我想设置我的 getOtherChecked() 方法来做到这一点,这样最后我就可以做到这样......

Dim myBoxes as new Behaviors
Dim cBox as Checkbox
Dim cBoxLabel as String

myBoxes.getOtherChecked(myUserForm) 'This would get each checked "Other Behaviors" checkbox object, and also somehow add another property to it called "LinkedTextboxLabel" that would be assigned the value of the corresponding textbox.
cBox = myBoxes.otherBehaviorCollection.item(0) 'Assign a checkbox from my "Other Behaviors" collection to a variable.
cBoxLabel = cBox.LinkedTextboxLabel 'Assign the user-inputted value of the linked textbox to a variable.

所以基本上我应该/应该如何/应该向集合项或复选框添加自定义属性?

我曾考虑将控件的名称添加到临时 DataTable 或 SQL 表中,以便每一行在一列中具有复选框的名称,在下一列中具有相应的文本框值,但我希望有一种更常用和接受的方法。

提前谢谢你!

【问题讨论】:

  • 好问题!值得投票和收藏。

标签: vb.net class methods properties visual-studio-2012


【解决方案1】:

我知道它不能回答将属性添加到属性的问题,但是您可以为“其他”复选框创建一个类并覆盖它的功能吗?然后您可以将复选框和 OtherCheckBoxes 添加到您的通用集合中?例如,(绝不是完整的,但你应该明白)

编辑:更改代码以显示阴影

Public Class OptionalCheckbox : Inherits CheckBox
Private mOptionalText As String

Public Shadows Property Text() As String
    Get
        Return mOptionalText
    End Get
    Set(value As String)
        mOptionalText = value
        MyBase.Text = value
    End Set
End Property
End Class

对于每个项目,如果您要检索 .Text,您将获得文本框值或复选框标签(如果它是普通复选框)

以及如何在代码的其他部分中使用。同样,这只是一个例子。您仍然需要使用分配给 OtherCheckBox 的文本框,以使其将文本写入其中,并从中读取到 Class 的 .Text 属性中。

    Dim newCheckBoxCollection As New Collection

    Dim cBox As New CheckBox
    cBox.Text = "Standard Value Here"
    'other properties of the checkbox can be modified here
    newCheckBoxCollection.Add(cBox)

    Dim cOBox As New OptionalCheckbox
    cOBox.Text = "Optional Text Here"
    'other properties of the checkbox can be modified here
    newCheckBoxCollection.Add(cOBox)

    For Each cb As CheckBox In newCheckBoxCollection
        Me.FlowLayoutPanel1.Controls.Add(cb)
    Next

【讨论】:

  • 这看起来很不错。我以前见过这样的特定覆盖,但从未深入研究过它们的使用。我明天会尝试这个,如果它有效,请将其标记为正确!再次感谢。
  • 这对我不起作用:/ IDE 不允许我在这里使用 Overrides,它说我需要使用阴影。我花了几个小时阅读覆盖、阴影、扩展运算符、派生类和基类,但似乎没有任何效果。我已经为这个特定项目找到了一个解决方案,但我仍然希望看到一个成功的例子来创建一个属性的属性......或者像你建议的那样替换一个类型。
  • 我更改了上面的代码,让您了解 Shadows 的工作原理。它当然需要更多的工作才能让它为你工作(比如让它从文本框读/写),但是如果你把它粘贴到 IDE 中,你应该明白了。另一个想法是创建一个将 Checkbox 或 OptionalCheckBox 控件作为属性的用户控件,然后执行您需要它执行的操作。 (显示文本框,隐藏复选框文本等)。将用户控件视为具有可视元素的类。
【解决方案2】:

您可以为与“其他行为”复选框关联的文本添加一个属性。

编辑:您可能试图过于概括您的数据,因为“其他行为”是一种特殊情况,值得单独考虑。

如果您查看以下代码(在新的 Windows 窗体项目中)创建了什么,它可能会给您一些想法:

Public Class Form1

    ''' <summary>
    ''' A behaviour domain and its characteristics, with one user-defined entry.
    ''' </summary>
    ''' <remarks></remarks>
    Public Class BehavioursSectionDescriptor
        Property BehaviourTypeName As String
        Property BehaviourNames As List(Of String)
        Property CustomBehaviours As String
    End Class

    ''' <summary>
    ''' Return a GroupBox containing CheckBoxes and one Checkbox with a TextBox adjacent to it.
    ''' </summary>
    ''' <param name="behaviourSet"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function GetBehaviourGroupPanel(behaviourSet As BehavioursSectionDescriptor) As GroupBox

        Dim gb As New GroupBox
        gb.Text = behaviourSet.BehaviourTypeName

        Dim fixedBehaviourNames As List(Of String) = behaviourSet.BehaviourNames
        Dim customBehavioursValue As String = behaviourSet.CustomBehaviours

        Dim cbVertSeparation As Integer = 4
        Dim gbPadding As Integer = 20

        Dim cb As New CheckBox

        Dim yLoc As Integer = gbPadding

        For i = 0 To fixedBehaviourNames.Count - 1
            cb = New CheckBox
            cb.Location = New Point(gbPadding, yLoc)
            cb.Text = fixedBehaviourNames(i)
            ' you can use the .Tag Object of a Control to store information
            cb.Tag = behaviourSet.BehaviourTypeName & "-Cb-" & i.ToString()
            gb.Controls.Add(cb)
            yLoc += cb.Height + cbVertSeparation

        Next

        cb = New CheckBox
        cb.Text = ""
        cb.Location = New Point(gbPadding, yLoc)
        cb.Tag = behaviourSet.BehaviourTypeName & "-Custom behaviours"
        gb.Controls.Add(cb)

        Dim tb As New TextBox
        tb.Location = New Point(gbPadding + 18, yLoc)
        tb.Width = 100
        tb.Text = customBehavioursValue
        gb.Controls.Add(tb)
        ' make sure the textbox appears in front of the checkbox's label area
        tb.BringToFront()

        gb.Size = New Size(160, yLoc + gbPadding * 2)

        Return gb

    End Function

    Private Function GetTestData() As List(Of BehavioursSectionDescriptor)
        Dim bsds = New List(Of BehavioursSectionDescriptor)
        bsds.Add(New BehavioursSectionDescriptor With {.BehaviourTypeName = "In water", _
                                                     .BehaviourNames = New List(Of String) From {"Floats", "Spins"}, _
                                                     .CustomBehaviours = "Paddles"})

        bsds.Add(New BehavioursSectionDescriptor With {.BehaviourTypeName = "Under light", _
                                                     .BehaviourNames = New List(Of String) From {"Shines", "Glows", "Reflects"}, _
                                                     .CustomBehaviours = "Iridesces"})

        bsds.Add(New BehavioursSectionDescriptor With {.BehaviourTypeName = "Near food", _
                                                     .BehaviourNames = New List(Of String) From {"Sniffs", "Looks"}, _
                                                     .CustomBehaviours = ""})

        Return bsds

    End Function

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

        Dim bsds As List(Of BehavioursSectionDescriptor) = GetTestData()

        Dim gbs As New List(Of GroupBox)
        Dim xLoc As Integer = 20
        Dim yLoc As Integer = 20

        ' make some GroupBoxes to present the data input fields
        For i = 0 To bsds.Count - 1
            Dim gb = GetBehaviourGroupPanel(bsds(i))
            gb.Location = New Point(xLoc, yLoc)
            gb.Dock = DockStyle.None
            yLoc += gb.Height + 30
            Me.Controls.Add(gb)
        Next

        ' size the form to fit the content
        Me.Size = New Size(240, yLoc + 40)

    End Sub


End Class

【讨论】:

  • 这无法完成,因为相应的文本框充当此复选框的标签。复选框文本值应为空白。
  • @Lopside 我添加了一些代码,展示了如何合并自定义元素。
  • 这确实给了我一个想法。我可以将每个“其他”复选框放入只有其文本框对应项的面板中。然后我可以很容易地引用每个像这样的 panelName.Controls(0) 用于复选框和 panelName.Controls(1) 用于文本框。
【解决方案3】:

如果您只是想将数据保存到 DataTable 或 SQL 表之类的东西中,那么代码可能有点过头了。我建议您使用流读取器/写入器并尝试以这种方式检查值,因为代码会更简单。

【讨论】:

  • 感谢您的提示。我不熟悉流式阅读器/作者,但现在将开始阅读它。有趣的是,属性中的属性似乎并不罕见。 . .希望一些 VB 大师可以展示它是如何完成的 :)
  • 是的,它们非常有用,我一直都在使用它们 :) 方便保存设置表格 :) 是的,我希望有一个出现:L
  • 不会在这里工作,但我喜欢用它来保存设置的想法。对评论 +1 哈哈
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-02
相关资源
最近更新 更多