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

C# 反射新用法:動態生成 UI 實現未知類型數據綁定

     編輯:關於C#

場景

UI 綁定通常需預知實體屬性。若數據源類型結構未知(如動態插件、用戶自定義實體),傳統綁定失效。反射可動態發現屬性並生成 UI。

核心思路

  1. 定義 DisplayAttribute 標記屬性顯示名
  2. 反射獲取所有公共實例屬性
  3. 動態構建 Grid:每屬性一行,左列顯示名,右列顯示值
  4. 特殊處理:Color 類型作為行背景色;DateTime/double 格式化
  5. 將生成的 FrameworkElement 列表作為 ListBox.ItemsSource

關鍵代碼

public class ObjectsConvertToUIFrmws {
    public IList BuildUIList(IList objs) {
        return objs.Cast().Select(BuildUICore).ToList();
    }

    private FrameworkElement BuildUICore(object obj) {
        if (obj == null) return null;
        var props = obj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
        var grid = new Grid();
        grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
        grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });

        for (int i = 0; i < props.Length; i++) {
            grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
            var prop = props[i];
            var attrs = prop.GetCustomAttributes(typeof(DisplayAttribute), false);
            var val = prop.GetValue(obj);

            if (val is Color color) {
                grid.Background = new SolidColorBrush(color);
                continue;
            }

            var lblName = new TextBlock {
                Text = attrs.Length > 0 ? ((DisplayAttribute)attrs[0]).Name : "未知字段"
            };
            Grid.SetRow(lblName, i); Grid.SetColumn(lblName, 0);
            grid.Children.Add(lblName);

            var lblVal = new TextBlock();
            if (val is DateTime dt) lblVal.Text = dt.ToString("yyyy-MM-dd HH:mm:ss");
            else if (val is double d) lblVal.Text = d.ToString("N3");
            else lblVal.Text = val?.ToString() ?? "";
            Grid.SetRow(lblVal, i); Grid.SetColumn(lblVal, 1);
            grid.Children.Add(lblVal);
        }
        return grid;
    }
}

測試實體

public class TestDataItem {
    [Display(Name = "名字:")] public string Name { get; set; }
    [Display(Name = "年齡:")] public int Age { get; set; }
    [Display(Name = "城市:")] public string City { get; set; }
    public Color BackGround { get; set; } // 無需 Display,作為背景色
}

使用

var list = new List {
    new() { Name = "abc", Age = 12, City = "大連", BackGround = Colors.Yellow },
    new() { Name = "def", Age = 20, City = "上海", BackGround = Colors.Pink },
    new() { Name = "gao", Age = 60, City = "珠海", BackGround = Colors.SkyBlue }
};
var converter = new ObjectsConvertToUIFrmws();
lbList.ItemsSource = converter.BuildUIList(list);

效果

ListBox 動態顯示三行數據,每行背景色不同,屬性名本地化

優缺點

  • ✅ 完全動態,無需預知類型
  • ✅ 顯示名本地化,用戶友好
  • ✅ 類型感知格式化 (日期/數字/顏色)
  • ⚠️ 僅適用簡單扁平屬性,複雜巢狀對象需遞歸擴展
  • ⚠️ 性能不如靜態綁定,適合數據量小、結構動態場景
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved