首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# 統一 UI 控制項與實體物件雙向綁定:反射 + 命名慣例

     編輯:關於C#

WinForms/WebForms 開發中,大量重複的「控制項 ←→ 實體屬性」賦值程式碼不僅冗長,還易出錯。本文提出一套基於命名慣例(控制項 ID = 前綴 + 屬性名)與反射的通用綁定機制,並透過介面統一存取 WinForms/WebForms 控制項,實現 UI 與後端邏輯解耦。

核心設計

  1. 命名規則:txtName ↔ User.Name、drpRole ↔ User.Role。前綴對應表:TextBox=txt、DropDownList=drp、ComboBox=cmb、Hidden=hdn、CheckBox=chk。
  2. 統一介面 IControl:封裝 RealCtl、GetCtlID()、GetSubCtls(),分別實作 WebControl、WinControl 結構體。
  3. 遞迴遍歷與型別過濾:利用 Tuple 定義需處理的控制項型別,Iterator 方法遞迴走訪控制項樹並過濾。
  4. 反射賦值/取值:SetCtlsVal<T>(Control, T entity)、GetCtlsVal<T>(Control, T entity),核心邏輯:entity.GetType().GetProperty(propName).GetValue/SetValue。

關鍵程式碼片段

// 介面與實作
interface IControl { object RealCtl { get; } string GetCtlID(); IEnumerable GetSubCtls(); }
struct WebControl : IControl { /* 封裝 System.Web.UI.Control */ }
struct WinControl : IControl { /* 封裝 System.Windows.Forms.Control */ }

// 遞迴迭代器(簡化版)
IEnumerable Iterate(IControl root, Tuple allowedTypes)
{
    foreach (var ctl in root.GetSubCtls())
    {
        if (!allowedTypes.HasType(ctl.RealCtl))
            foreach (var sub in Iterate(ctl, allowedTypes)) yield return sub;
        else yield return ctl;
    }
}

// 實體 → 控制項(WebForms 範例)
public static void SetCtlsVal(Control root, T entity)
{
    var allowed = Tuple.Create(typeof(TextBox), typeof(DropDownList), typeof(HiddenField));
    foreach (var ctl in Iterate(new WebControl(root), allowed))
    {
        string propName = ParseCtlID(ctl.GetCtlID(), GetCtlType(ctl.RealCtl));
        object val = typeof(T).GetProperty(propName)?.GetValue(entity);
        if (val == null) continue;

        switch (ctl.RealCtl)
        {
            case TextBox tb: tb.Text = val.ToString(); break;
            case DropDownList ddl: ddl.SelectedValue = val.ToString(); break;
            case HiddenField hf: hf.Value = val.ToString(); break;
        }
    }
}

Controller 模式解耦 UI


class LoginController
{
    private Form _view; private User _user = new User();
    public LoginController(Form view) { _view = view; }

    public bool ValidateInput()
    {
        ControlHelper.GetCtlsVal(_view, _user); // UI → 實體
        return !string.IsNullOrEmpty(_user.Name) && !string.IsNullOrEmpty(_user.Pwd);
    }
}

Controller 不依賴具體控制項型別,只操作實體物件,單元測試極易撰寫。

擴充應用

  • 統一清空表單:遍歷所有 TextBox 設 Text = ""。
  • 統一設定唯讀/樣式:依實體屬性 [ReadOnly] 屬性自動鎖定控制項。
  • 支援巢狀容器:Panel、GroupBox、UserControl 透過 GetSubCtls() 遞迴處理。
  • 整合驗證屬性:[Required]、[StringLength] 於綁定時自動檢查。

優缺點權衡

優點缺點/注意
消除大量樣板碼依賴命名慣例,團隊需嚴格遵守
UI/邏輯解耦,利測試反射效能較差(可快取 PropertyInfo)
支援 WinForms/WebForms 同一套邏輯複雜控制項(Grid、TreeView)需另行處理
易擴充驗證、樣式、本地化動態產生控制項需確保命名正確

此模式在中型專案極具實用價值,將「機械性綁定」交給機器,開發者專注於業務邏輯。

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