none
运用C#泛型方法,设计一个功能函数,在窗体动态地添加控件 RRS feed

  • 问题

  • 我设计了一个泛型函数,动态批量地向窗体添加控件,

    当我调用AddSubMenu<Button>("SubMenu", strName)

    希望正常运行效果如下


    现在遇到一些问题:

    遇到的问题,大概是,泛型<T>参数,虽然限制了WHERE,限定的control,,但不排除有些控件是没有FlatStyle属性的,所有报错。。

    其中一个办法是,用typeof(T) == typeof(ButtonTouch),判断输入的<T>参数属于哪种控件,再根据具体控件写代码,

    如下图

    但这样,我感觉又要写好多代码,感觉好像失去了泛型的作用,虽然也可以省掉不少代码。

    请问还有别的解决办法吗?

    2018年2月1日 15:56

答案

  • 您的代码没有问题,对于有些控件是没有FlatStyle属性的,可以用反射检测一下这个类型有没有此属性,没有则不赋值。

    public static bool HasProperty(this object obj, string propertyName) { return obj.GetType().GetProperty(propertyName) != null;

    }

    https://stackoverflow.com/questions/15341028/check-if-a-property-exist-in-a-class

    如果上面的方法返回false,则表示控件是没有FlatStyle属性,跳过赋值语句。

    同样道理,赋值也需要改成反射以通过编译:

    https://stackoverflow.com/questions/619767/set-object-property-using-reflection

    Yes, you can use Type.InvokeMember():

    using System.Reflection;
    MyObject obj = new MyObject();
    obj.GetType().InvokeMember("Name",
        BindingFlags.Instance | BindingFlags.Public | BindingFlags.SetProperty,
        Type.DefaultBinder, obj, "Value");

    This will throw an exception if obj doesn't have a property called Name, or it can't be set.

    Another approach is to get the metadata for the property, and then set it. This will allow you to check for the existence of the property, and verify that it can be set:

    using System.Reflection;
    MyObject obj = new MyObject();
    PropertyInfo prop = obj.GetType().GetProperty("Name", BindingFlags.Public | BindingFlags.Instance);
    if(null != prop && prop.CanWrite)
    {
        prop.SetValue(obj, "Value", null);
    }


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

    • 已标记为答案 Hank1983 2018年2月2日 6:05
    2018年2月2日 0:47