Vb.net 有没有办法创建一个全局函数来清除文本框?

Vb.net 有没有办法创建一个全局函数来清除文本框?,vb.net,winforms,Vb.net,Winforms,我想知道是否有任何方法可以创建一个带有全局函数/方法/子类的类 调用它将清除表单中的一些文本框。如何处理不同数量的文本框 每种形式都有吗 当前代码仅清除预定义的两个框。多谢各位 Public Class ClearElements Public Sub CLEAR_TEXT(ByVal text1 As TextBox, ByVal text2 As TextBox) text1.Clear() text2.Clear() End Sub En

我想知道是否有任何方法可以创建一个带有全局函数/方法/子类的类 调用它将清除表单中的一些文本框。如何处理不同数量的文本框 每种形式都有吗

当前代码仅清除预定义的两个框。多谢各位

Public Class ClearElements

    Public Sub CLEAR_TEXT(ByVal text1 As TextBox, ByVal text2 As TextBox)
        text1.Clear()
        text2.Clear()
    End Sub

End Class
我们有:


您可以递归地遍历表单中的所有控件,如果type=Textbox,则清除它

但随后情节变得更加复杂:

我以前做过。它将清除表单中的所有框。我所说的情况是,有些箱子必须保持原样,有些必须清理

这里的解决方案分为两部分。首先,按照建议创建递归方法,如下所示:

Public Sub ClearText(root As Control)
    For Each ctrl As Control In Root.Controls
        If TypeOf ctrl Is TextBox Then ctrl.Text = String.Empty
        ClearText(ctrl)
    Next ctrl
End Sub
CountTextBoxesAndClear("Form1", Nothing, 9, 13)
CountTextBoxesAndClear("Form1", Nothing, ObjToInt(TextBox9), ObjToInt(TextBox13))
或者这个:

Public Sub ClearText(root As IEnumerable(Of Control))
    For Each ctrl As Control In root
        If TypeOf ctrl Is TextBox Then ctrl.Text = String.Empty
        ClearText(ctrl.Controls)
    Next ctrl
End Sub
其次,在表单上,为需要清除的文本框控件使用诸如
面板
组框
FlowLayoutPanel等容器。关键是你需要清除的所有文本框控件,以及你想保留的所有控件,都应该在同一个公共容器中。完成后,您可以将容器传递给上述方法之一。如果这会影响布局,您可以在表单的不同区域使用少量容器来存放控件集,并只调用该函数几次

请记住,
Panel
控件的样式可以使父窗体上完全没有可见的工件,并且完全用于逻辑分组。上述方法的第二个版本还允许您创建所关心的控件(或控件容器)的数组或列表


另一种控制方法是从TextBox继承自定义控件。你甚至不需要改变任何事情。重要的是控件现在与常规文本框的类型不同,因此递归方法可以针对新控件类型而不是文本框。

有很多方法可以做到这一点

您可以将文本框添加到列表中,并清除列表中的每个项目

Private ReadOnly someOfTheTextBoxes As New List(Of TextBox)

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    someOfTheTextBoxes.Add(TextBox1)
    someOfTheTextBoxes.Add(TextBox2)
End Sub

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    For Each t In someOfTheTextBoxes
        t.Clear()
    Next
End Sub
还是用这个方法

Public Sub CLEAR_TEXT(textboxes As IEnumerable(Of TextBox))
    For Each t In textboxes
        t.Clear()
    Next
End Sub
然后用你的文本框列表来调用它

Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
    CLEAR_TEXT(someOfTheTextBoxes)
End Sub
或者在现场制作一个阵列并将其传递进来

Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
    CLEAR_TEXT({TextBox1, TextBox2})
End Sub
如果您对递归感兴趣,这里有一些扩展可以帮助您

Module Extensions
    <Runtime.CompilerServices.Extension>
    Public Function ChildControls(parent As Control) As IEnumerable(Of Control)
        Return ChildControls(Of Control)(parent)
    End Function
    <Runtime.CompilerServices.Extension>
    Public Function ChildControls(Of TControl As Control)(parent As Control) As IEnumerable(Of TControl)
        Dim result As New List(Of TControl)
        For Each ctrl As Control In parent.Controls
            If TypeOf ctrl Is TControl Then result.Add(CType(ctrl, TControl))
            result.AddRange(ctrl.ChildControls(Of TControl)())
        Next
        Return result
    End Function
    <Runtime.CompilerServices.Extension>
    Public Function ForEach(Of TSource)(source As IEnumerable(Of TSource), action As Action(Of TSource)) As IEnumerable(Of TSource)
        For Each item As TSource In source
            action(item)
        Next item
        Return source
    End Function

    <Runtime.CompilerServices.Extension>
    Public Function ForEach(Of TSource)(source As IEnumerable(Of TSource), action As Action(Of TSource, Integer)) As IEnumerable(Of TSource)
        For i As Integer = 0 To source.Count() - 1
            action(source.ElementAt(i), i)
        Next
        Return source
    End Function
End Module
或者你名单上的每一个

someOfTheTextBoxes.ForEach(Sub(t) t.Clear())

在某些情况下,我正在使用

首先是要知道你需要什么文本框或任何组件。 第二是要知道文本框(或任何其他组件)是否位于表单(根)内部或其他组件(如面板、groupoxes、tabPages)内部,以及它们是否位于其他组件内部

示例1:表单–分组框(x)–选项卡控件(y)–选项卡页面(z)–文本框(n)

示例2:表单---文本框(x)

示例3:表单–GroupBoox(x)–面板(y)–文本框(n)

等等

您可能需要创建一些指定的子函数/函数来完成更详细的工作。有两件事很重要:

  • 组件的路径(请参见前面的示例)

  • 组件的编号。如果您遵循示例3,可能是这样的:

  • 表格1–组框2–面板1–文本框3

    重要提示:这些是组件的名称,必须枚举所有组件

    做你要做的事情的简单方法是:

    Public Sub CountTextBoxesAndClear(ByVal FormName As String, Optional ByVal myObject As Object = Nothing)
        Dim ArrayTextBoxName() As String
        Dim myTextBox As New TextBox
        Dim nTBOX As Integer
    
        'Path of component
        If myObject = Nothing Then myObject = My.Application.OpenForms.Item(FormName)
        'Bucle
        For i As Integer = 0 To myObject.Controls.Count - 1
            If myObject.Controls(i).GetType Is GetType(TextBox) Then
                'Counting
                nTBOX += 1
                'Redim array
                ReDim Preserve ArrayTextBoxName(nTBOX)
                'Get Component
                ArrayTextBoxName(nTBOX) = "TextBox" & nTBOX
                'Get Path
                myTextBox = myObject.Controls.Item(ArrayTextBoxName(nTBOX))
                'myTextBox = myObject.Controls.Item("TextBox" & nTBOX) '<< the same of above line
                Try
                    'Clear TextBoxes
                    myTextBox.Clear()
                Catch ex As NullReferenceException
                    'A TextBox is Null, no error message
                End Try
            End If
        Next
    End Sub
    
    如果文本框位于名为Panel1的面板中:

    CountTextBoxesAndClear("Form1", Panel1)
    
    您必须拥有文本框的总数,但只能清除(或执行任何操作)名为TextBox[x]的文本框

    Try/Catch管理错误,因为TextBox3不存在。但是,正确的方法是Textbox1、TextBox2、Textbox3、Textbox4、另一个Textbox1、另一个TextBox2,并在子/函数中设置限制

    例如:

    Public Sub CountTextBoxesAndClear(ByVal FormName As String, Optional ByVal myObject As Object = Nothing, Optional byval start as integer = 0, Optional byval finish as integer = 0)
        […tracatra…]
        For i As Integer = start To finish
            […tratra…]
        Next
    End Sub
    
    以下是如何称呼:

    CountTextBoxesAndClear("Form1", Nothing, 1, 4)
    
    现在,您可以研究一下如何创建sub/函数来了解组件的正确路径,并获取文本框、标签、组合框、复选框的内容和属性

    其他信息:

    如果您使用的是VisualStudio,您知道,如果更改组件的名称,所有代码都会自动更改。如果将开始/完成变量用作数字,这将是一个大问题,因为当需要添加/删除或移动位置时,必须手动更改函数中的所有开始/完成值,例如:

    CountTextBoxesAndClear("Form1", Nothing, 8, 12)
    
    现在,您需要在八个位置添加一个新的文本框,然后移动一个。你的潜艇看起来像这样:

    Public Sub ClearText(root As Control)
        For Each ctrl As Control In Root.Controls
            If TypeOf ctrl Is TextBox Then ctrl.Text = String.Empty
            ClearText(ctrl)
        Next ctrl
    End Sub
    
    CountTextBoxesAndClear("Form1", Nothing, 9, 13)
    
    CountTextBoxesAndClear("Form1", Nothing, ObjToInt(TextBox9), ObjToInt(TextBox13))
    
    您可以创建一个将组件名称转换为整数的简单函数(此函数仅适用于两位数字(0到99):

    您的sub可以这样写:

    Public Sub ClearText(root As Control)
        For Each ctrl As Control In Root.Controls
            If TypeOf ctrl Is TextBox Then ctrl.Text = String.Empty
            ClearText(ctrl)
        Next ctrl
    End Sub
    
    CountTextBoxesAndClear("Form1", Nothing, 9, 13)
    
    CountTextBoxesAndClear("Form1", Nothing, ObjToInt(TextBox9), ObjToInt(TextBox13))
    

    谢谢你的精彩解决方案

    我最终用ParamArray解决了这个问题

     Public Sub CLEAR_TEXTBOXES(ParamArray arr_textboxes() As TextBox)
        For Each textbox As TextBox In arr_textboxes
            textbox.Clear()
        Next
    End Sub
    
    然后我用我想要的任何文本框调用类

    CLS_CLEAR_TEXTBOX.CLEAR_TEXTBOXES(TextBox1, TextBox2, Textbox7)
    

    这是一种更短的方法。
    使用ParamArray和Linq

    Public Sub CLEAR_TEXT(参数数组文本为TextBox())
    text.ToList().ForEach(Sub(s)s.Clear())
    端接头
    
    您可以递归地遍历表单中的所有控件,如果type=Textbox,则清除它。我以前已经这样做过。它会清除表单中的所有框。我指的是一些框必须保持不变,而另一些框必须清除。您需要测试每个文本框是否满足任何条件,以确定是否需要那么我想清除它。哪些条件有些被清除,有些不被清除?看看然后:
    Me.genderantcontrols().OfType(Of TextBox.ToList().ForEach(Sub(x)x.clear())
    使用会使代码更干净。例如,看一看。@RezaAghaei Yield也会工作,但它不仅仅是更干净的代码,代码的工作方式也会有所不同,即控件不会立即迭代,而是在随后的LINQ调用中迭代。我可以看到它如何更好地符合IEnumerable的精神。或者,您可以在en中获得数字带有一行代码的控件名的d:
    返回Integer.Parse(IntObject.name.Reverse().TakeWhile(Function(c)Integer.TryParse(c)).Reverse())
    ,它将接受任何