首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

VB.NET 字符串動態調用控件屬性:Controls 集合與反射兩種方案實現權限設計

     編輯:程式設計綜合問答

需求場景

將 `Form1.ColorToolStripMenuItem.Visible = False` 等代碼左側作為字符串存入數據庫,運行時讀取字符串動態設置控件屬性。

方案一:Controls 集合索引器(最簡單,適用同一窗體)

' 數據庫存儲字符串: "ColorToolStripMenuItem" 或 "Button3"
Dim ctrlName As String = reader.GetString("ControlName")  ' 讀取 "ColorToolStripMenuItem"

' 當前窗體查找
Dim ctrl As Control = Me.Controls(ctrlName)
If ctrl IsNot Nothing Then
    ctrl.Visible = False
Else
    ' 可能在容器中(Panel/GroupBox/ToolStrip),需遞歸查找
    ctrl = FindControlRecursive(Me, ctrlName)
End If

' 遞歸查找輔助函數
Function FindControlRecursive(parent As Control, name As String) As Control
    If parent.Name = name Then Return parent
    For Each c As Control In parent.Controls
        Dim found = FindControlRecursive(c, name)
        If found IsNot Nothing Then Return found
    Next
    Return Nothing
End Function

方案二:反射獲取字段/屬性(跨窗體、靜態類型安全)

' 字符串格式: "Form1.ColorToolStripMenuItem" 或 "Form2.Button3"
Dim fullName As String = reader.GetString("FullControlPath")  
Dim parts = fullName.Split("."c)
Dim formName = parts(0)      ' "Form1"
Dim ctrlName = parts(1)      ' "ColorToolStripMenuItem"

' 獲取窗體類型 (假設在同一程序集)
Dim formType = Assembly.GetExecutingAssembly().GetTypes() _
    .FirstOrDefault(Function(t) t.Name = formName)

If formType IsNot Nothing Then
    ' 獲取靜態實例字段 (WinForms 默認實例)
    Dim formInstance = formType.GetField(formName, 
        Reflection.BindingFlags.Static Or Reflection.BindingFlags.Public) _
        .GetValue(Nothing)
    
    If formInstance IsNot Nothing Then
        Dim ctrlField = formType.GetField(ctrlName, 
            Reflection.BindingFlags.Instance Or Reflection.BindingFlags.Public Or Reflection.BindingFlags.NonPublic)
        Dim ctrl = ctrlField.GetValue(formInstance)
        If ctrl IsNot Nothing Then
            ctrl.GetType().GetProperty("Visible").SetValue(ctrl, False)
        End If
    End If
End If

方案對比與選型建議

維度Controls 集合反射
性能極快 (O(1) 索引)較慢 (元數據查找)
跨窗體需傳遞 Form 實例天然支援類名定位
容器嵌套需遞歸查找同樣需遞歸或完整路徑
類型安全運行時發現錯誤可編譯期驗證字段名
推薦場景同窗體、簡單權限控制插件架構、跨模塊、配置驅動

權限設計表結構建議

CREATE TABLE UiPermission (
    Id INT PRIMARY KEY,
    RoleId INT NOT NULL,
    FormName NVARCHAR(100) NOT NULL,      -- "Form1"
    ControlName NVARCHAR(100) NOT NULL,   -- "ColorToolStripMenuItem"
    PropertyName NVARCHAR(50) NOT NULL,   -- "Visible"
    PropertyValue NVARCHAR(50) NOT NULL,  -- "False"
    CONSTRAINT UQ_Role_Control UNIQUE (RoleId, FormName, ControlName, PropertyName)
);

總結

VB.NET 動態字符串操作控件:**同窗體用 `Controls[\"name\"]` + 遞歸查找最簡捷;跨窗體/插件化用反射獲取 Field/Property**。建議數據庫存儲 `FormName.ControlName` 完整路徑,運行時解析並通過反射或 Controls 集合應用屬性值,實現靈活的權限/顯示控制。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved