1

我正在我的 WindowsForm 应用程序中创建一个搜索表单:

public partial class SearchForm<T>()
{
   ....
}

我想在运行时根据T属性类型创建一些控件,例如如果TOrder

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;

我的问题是

  1. 我怎样才能得到一个<T>类型的所有属性?

  2. 我怎样才能动态地创建它predicate(动态地相互附加条件)?

4

2 回答 2

1

1) Get infofmation about Properties via reflection, use PropertyType to filter by type

PropertyInfo[] properties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
return properties.Where(p => p.PropertyType == typeof(string));

2) As the return type of your predicate is bool, the simple way to get the desired result is:

public Func<T, bool> AllTrue<T>(IEnumerable<Func<T, bool>> predicates)
{
    return t => predicates.All(p => p(t));
}
于 2013-06-16T08:26:50.850 回答
1

要获取类型的属性,您可以依赖反射。请参阅如何获取类的属性列表?

从那里您可以使用表达式树来构建动态谓词。请参阅如何动态创建 Expression<Func<MyClass, bool>> 谓词?

但我建议采用更简单(但涉及更多打字)的方法。

有一个应该由你的所有Ts 实现的接口。就像是:

 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.
      }  
   }

这提供了更多的灵活性。您可以直接将谓词附加到每个s中的类,而不是动态构建谓词。这是我们在您的项目中使用的东西。ParamInfoT

于 2013-06-16T08:16:45.953 回答