我正在WindowsForm应用程序中创建一个搜索表单:
public partial class SearchForm<T>()
{
....
}
我希望在运行时基于T
属性类型创建一些控件,
例如,如果T
是Order
:
public class Order
{
public string OrderNumber {get; set;}
public decimal OrderWeight {get; set;}
}
搜索表单将是这样的:
我希望string
属性有一个TextBox
,对于数字属性,有2 Control
(一个用于From,另一个用于To)
我还希望将用户选择的条件放在predicate
变量中:
Func<T, bool> predicate;
例如
predicate = t => t.OrderNumber.Contains("ORDER-01") &&
t.OrderWeight >= 100 &&
t.OrderWeight <= 200;
我的问题是
如何获取<T>
类型的所有属性?
如何动态创建此predicate
(将条件附加到
彼此动态地)?
答案 0 :(得分:1)
要获取类型的属性,您可以依赖反射。见How to get the list of properties of a class?
从那里你可以使用表达式树来构建动态谓词。见How do I dynamically create an Expression<Func<MyClass, bool>> predicate?
但我建议采用更简单(但涉及更多打字)的方法。
有一个应由所有T
实现的界面。类似的东西:
public interface Searchable
{
IEnumerable<ParamInfo> Params { get; }
Func<string, decimal, decimal, bool> Predicate { get; }
}
和ParamInfo
班级:
public class ParamInfo
{
public string LabelText { get; private set; }
public Type EditControl { get; private set; }
public Type DataType { get; private set; }
public object DefaultValue { get; private set; }
public bool Required { get; private set; }
//etc. basically a good info class the decides how to draw gui
}
您的搜索表单可以
public partial class SearchForm<T> where T : Searchable
{
....
}
和poco:
public class Order : Searchable
{
public string OrderNumber {get; set;}
public decimal OrderWeight {get; set;}
public IEnumerable<ParamInfo> Params
{
get
{
return new List<ParamInfo>
{
new ParamInfo(typeof(TextBox), typeof(string), "Enter value", true),
new ParamInfo(typeof(TextBox), typeof(decimal), 0, true),
new ParamInfo(typeof(TextBox), typeof(decimal), 0, true)
}
}
}
public Func<string, decimal, decimal, bool> Predicate
{
get
{
return (s, d1, d2) => OrderNumber.Contains(s)
&& OrderWeight >= d1
&& OrderWeight <= d2; //and so on, u get the idea.
}
}
这提供了更多的灵活性。您可以直接将谓词附加到每个ParamInfo
中的T
类,而不是动态构建谓词 。这是我们在您的项目中使用的东西。
答案 1 :(得分:1)
1)通过反射获取有关Properties的信息,使用PropertyType按类型
进行过滤PropertyInfo[] properties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
return properties.Where(p => p.PropertyType == typeof(string));
2)由于predicate
的返回类型为bool
,获得所需结果的简单方法是:
public Func<T, bool> AllTrue<T>(IEnumerable<Func<T, bool>> predicates)
{
return t => predicates.All(p => p(t));
}