禁用所有文本框字段的快速方法使用编辑按钮解锁

quick way to disable all textboxfields unlock with edit button

Vb.net 是否有快速禁用表单中所有可编辑字段(文本框、复选框等)的方法? 我试图保护数据不被“意外”覆盖。我的用户必须单击编辑按钮才能“解锁”字段并使它们可编辑,并且用户必须按下保存按钮才能更新数据库并再次锁定字段。

到目前为止,我只找到了一个手动输入来使每个文本框和复选框(大约 30 个在表单的不同选项卡中)只读值为 true 并在我单击我的编辑按钮时禁用它们。 关于如何做到这一点的任何建议?我可以更快地做一个“for each”吗?我将如何制定代码? 我找到了一篇 2007 年的文章,其中包含以下片段:

For Each control As Control In Me.Controls

If TypeOf (control) Is TextBox Then

CType(control, TextBox).ReadOnly = True

End If
Next

但我一次性需要所有类型的字段。

感谢您就此问题提出任何建议。我是初学者。

试试这个:

For Each control As Control In Me.Controls
  Try 
    CType(control, TypeOf(control)).ReadOnly = True
  Catch 
    ' Do nothing
  End Try
Next

这将禁用直接添加到 TabControl1 中的 TabPage 的每个 TextBox 和每个 CheckBox:

For each tp As TabPage In TabControl1.TabPages
    For Each tb In tp.Controls.OfType(Of TextBox)()
        tb.Enabled = False
    Next

    For Each cb In tp.Controls.OfType(Of CheckBox)()
        cb.Enabled = False
    Next
Next

参照this question

如果将其放入名为 ControlExt.vb 的模块中:

Imports System.Runtime.CompilerServices
Module ControlExt

<Extension()>
Public Function GetAllChildren(Of T As Control)(parentControl As Control) As IEnumerable(Of T)
    Dim controls = parentControl.Controls.Cast(Of Control)
    Return controls.SelectMany(Of Control)(Function(ctrl) _
        GetAllChildren(Of T)(ctrl)) _
        .Concat(controls) _
        .Where(Function(ctrl) ctrl.GetType() = GetType(T)) _
    .Cast(Of T)
End Function

End Module

然后你可以在 class:



Class WhateverForm

  Private _allTextboxes as List(Of TextBox)

  Public Sub New() 'in the constructor

    InitializeComponent()

    _allTextboxes = Me.GetAllChildren(Of TextBox).ToList()
  End Sub

这意味着您表单上的所有文本框,无论它们位于何处(在子面板的任何子面板内、组框的标签页内等),现在都在一个列表中。您可以在编辑按钮单击处理程序中执行此操作:

_allTextboxes.ForEach(Sub(b) b.ReadOnly = False)

当然,在“保存”按钮中执行推论 ReadOnly = True。您不必将其限制为文本框; GetAllChildren 可以找到任何东西 - 也许你也想锁定复选框 - 有另一个列表 _allCheckboxesGetAllChildren(Of CheckBox)ForEachEnabled =

我要指出的是,ReadOnly 和 Enabled 略有不同,并且作为 UX 指针,如果您要使内容在 UI 中变灰(或者在ReadOnly),那么你应该有一些东西来解释为什么这个选项是灰色的 out/how 来启用它。用户不会立即意识到他们必须单击“启用”,如果您不希望技术支持呼叫“我正在单击名称框,我可以看到光标在闪烁,但当我键入时什么也没有发生!”然后用“查看模式:要启用此数据的编辑,请单击[编辑]”等来推动他们

感谢 GetAllChildren 功能。我想我会分享它的延续,这样你就可以根据标签锁定所有常用控件。

Public Sub LockControls(ByVal frm_Form As Form,
                        ByVal bln_Lock As Boolean,
                        ByVal str_TAG As String)

    Dim allTextboxes As List(Of TextBox)
    Dim allComboBoxes As List(Of ComboBox)
    Dim allDateTimePickers As List(Of DateTimePicker)
    Dim allDataGrids As List(Of DataGridView)
    Dim allCheckBoxes As List(Of CheckBox)
    Dim allListBoxes As List(Of ListBox)
    Dim allButtons As List(Of Button)

    Dim blnEnable As Boolean
    Dim blnReadonly As Boolean

    If bln_Lock Then ' we need to lock controls
        blnEnable = False
        blnReadonly = True
    Else
        blnEnable = True
        blnReadonly = False
    End If

    allTextboxes = frm_Form.GetAllChildren(Of TextBox).ToList
    For Each CTL In allTextboxes
        If ContainsTag(CTL.Tag, str_TAG) Then
            CTL.ReadOnly = blnReadonly
        End If
    Next

    allComboBoxes = frm_Form.GetAllChildren(Of ComboBox).ToList
    For Each CTL In allComboBoxes
        If ContainsTag(CTL.Tag, str_TAG) Then
            CTL.Enabled = blnEnable
        End If
    Next

    allCheckBoxes = frm_Form.GetAllChildren(Of CheckBox).ToList
    For Each CTL In allCheckBoxes
        If ContainsTag(CTL.Tag, str_TAG) Then
            CTL.Enabled = blnEnable
        End If
    Next

    allButtons = frm_Form.GetAllChildren(Of Button).ToList
    For Each CTL In allButtons
        If ContainsTag(CTL.Tag, str_TAG) Then
            CTL.Enabled = blnEnable
        End If
    Next

    allDateTimePickers = frm_Form.GetAllChildren(Of DateTimePicker).ToList
    For Each CTL In allDateTimePickers
        If ContainsTag(CTL.Tag, str_TAG) Then
            CTL.Enabled = blnEnable
        End If
    Next

    allDataGrids = frm_Form.GetAllChildren(Of DataGridView).ToList
    For Each CTL In allDataGrids
        If ContainsTag(CTL.Tag, str_TAG) Then
            CTL.ReadOnly = blnReadonly
        End If
    Next

    allListBoxes = frm_Form.GetAllChildren(Of ListBox).ToList
    For Each CTL In allListBoxes
        If ContainsTag(CTL.Tag, str_TAG) Then
            CTL.Enabled = blnEnable
        End If
    Next

End Sub

Private Function ContainsTag(fulltag As String, searchTag As String) As Boolean
    Dim found As Boolean
    Dim tags As String() = Nz(fulltag, "").Split(New Char() {","c})

    For Each tag In tags
        If tag = searchTag Then
            found = True
        End If
    Next

    Return found
End Function

Public Function Nz(ByVal Value As Object, Optional ByVal DefaultVal As Object = "") As Object
    If Value Is Nothing OrElse IsDBNull(Value) Then
        Return DefaultVal
    Else
        Return Value
    End If
End Function