none
如何批量生成与属性对应的界面控件? RRS feed

  • 问题

  • public class ViewModel : INotifyPropertyChanged { private int x;

    [Category("X方向位置参数")]
         [DisplayName("X坐标")]
         [Description("X坐标(km)")]

    public int X { get { return x; } set { x = value; NotifyPropertyChanged("X"); NotifyPropertyChanged("Y"); } } private int y;

    [Category("Y方向位置参数")]
         [DisplayName("Y坐标")]
         [Description("Y坐标(km)")]

    public int Y { get { return y; } set { y = value; NotifyPropertyChanged("Y"); NotifyPropertyChanged("X"); } } }

    ViewModel中有X、Y、Z等总共34个属性,这些属性的类型有int,float,枚举……每个属性都有对应的类别[Category] [DisplayName][Description]三个Attribute,为了把这些属性暴露给用户,目前的做法是:

    按照Category的名称设置Expander,把相同Category的属性显示到同一个Expander里面;(xaml硬编码)

    每一个属性,先用一个TextBlock显示DispalyName,并把Description设置为ToolTip,然后根据VM属性的类型,设置TextBox(float、int)、ComboBox(枚举)。 (xaml硬编码)

    这些过程可以通过xaml编码来实现,但是代码量很大,不知道有没有其它更便捷更优雅的方式实现这一功能?

    其它的疑问:

    1. 怎么在xaml中提取属性的Attribute并 绑定到界面元素?(必须有数据校验错误显示)

    2. 怎么自动按照Category生成界面上的Expander?


    2018年3月7日 1:34

答案

  • 1  提取属性的Attribute

    using System; public class ExampleAttribute : Attribute { private string stringVal; public ExampleAttribute() { stringVal = "This is the default string."; } public string StringValue { get { return stringVal; } set { stringVal = value; } } } [Example(StringValue="This is a string.")] class Class1 { public static void Main() { System.Reflection.MemberInfo info = typeof(Class1); foreach (object attrib in info.GetCustomAttributes(true)) { Console.WriteLine(attrib); } } }

    sing System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Linq.Expressions;
    
    namespace ConsoleApplication1
    {
        public class DatabaseFieldAttribute : Attribute
        {
            public string Name { get; set; }
    
            public DatabaseFieldAttribute(string name)
            {
                this.Name = name;
            }
        }
    
        public static class MyClassExtensions
        {
            public static string DbField<T>(this T obj, Expression<Func<T, string>> value)
            {
                var memberExpression = value.Body as MemberExpression;
                var attr = memberExpression.Member.GetCustomAttributes(typeof(DatabaseFieldAttribute), true);
                return ((DatabaseFieldAttribute)attr[0]).Name;
            }
        }
    
        class Program
        {
            static void Main(string[] args)
            {
                var p = new Program();
                Console.WriteLine("DbField = '{0}'", p.DbField(v => v.Title));
    
            }
            [DatabaseField("title")]
            public string Title { get; set; }
    
        }
    }

    2 绑定到界面元素

    将提取的attribute构建为collection或object,将它绑定于控件中。

    3 怎么自动按照Category生成

    将提取的category分组,

    //category是atrribute,List<>是属性集合

    Dictionary<string,List<string>> dic;

    依据这个集合创建Expander


    专注于.NET ERP/CRM开发框架,C/S架构,SQL Server + ORM(LLBL Gen Pro) + Infragistics WinForms

    2018年3月8日 0:58

全部回复

  • 1  提取属性的Attribute

    using System; public class ExampleAttribute : Attribute { private string stringVal; public ExampleAttribute() { stringVal = "This is the default string."; } public string StringValue { get { return stringVal; } set { stringVal = value; } } } [Example(StringValue="This is a string.")] class Class1 { public static void Main() { System.Reflection.MemberInfo info = typeof(Class1); foreach (object attrib in info.GetCustomAttributes(true)) { Console.WriteLine(attrib); } } }

    sing System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Linq.Expressions;
    
    namespace ConsoleApplication1
    {
        public class DatabaseFieldAttribute : Attribute
        {
            public string Name { get; set; }
    
            public DatabaseFieldAttribute(string name)
            {
                this.Name = name;
            }
        }
    
        public static class MyClassExtensions
        {
            public static string DbField<T>(this T obj, Expression<Func<T, string>> value)
            {
                var memberExpression = value.Body as MemberExpression;
                var attr = memberExpression.Member.GetCustomAttributes(typeof(DatabaseFieldAttribute), true);
                return ((DatabaseFieldAttribute)attr[0]).Name;
            }
        }
    
        class Program
        {
            static void Main(string[] args)
            {
                var p = new Program();
                Console.WriteLine("DbField = '{0}'", p.DbField(v => v.Title));
    
            }
            [DatabaseField("title")]
            public string Title { get; set; }
    
        }
    }

    2 绑定到界面元素

    将提取的attribute构建为collection或object,将它绑定于控件中。

    3 怎么自动按照Category生成

    将提取的category分组,

    //category是atrribute,List<>是属性集合

    Dictionary<string,List<string>> dic;

    依据这个集合创建Expander


    专注于.NET ERP/CRM开发框架,C/S架构,SQL Server + ORM(LLBL Gen Pro) + Infragistics WinForms

    2018年3月8日 0:58
  • 非常感谢!
    2018年3月8日 1:34