[英]Create a search form dynamically in run-time based on <T> properties
我正在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
(彼此動態附加條件)?
要獲取類型的屬性,您可以依靠反射。 請參閱如何獲取類的屬性列表?
從那里您可以使用表達式樹構建動態謂詞。 請參見如何動態創建Expression <Func <MyClass,bool >>謂詞?
但我建議您使用一種更簡單(但涉及更多類型)的方法。
有一個所有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.
}
}
這提供了更多的靈活性。 可以動態地將謂詞附加到每個T
的ParamInfo
類上,而不是動態地構建謂詞。 這是我們在您的項目中使用的東西。
1)通過反射獲取有關屬性的信息,使用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));
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.