我们说我有一个Order
类,它具有OrderName,OrderNum等属性......
然后使用此类中的项目列表填充ComboBox
,让我说我这样做:
comboBox1.DisplayMember = "OrderName";
comboBox1.ValueMember = "OrderNum";
comboBox1.DataSource = list.ToArray<Order>();
所以在这里我很难编码代码中的那些字段的名称,例如&#34; OrderName&#34;。有没有更好的方法来做这个而不是硬编码字段的名称?它需要某种依赖注入技巧吗?你有什么建议?
答案 0 :(得分:3)
如果可能,您可以按照@JesseCSlicer提到的那样继续,但如果您无法更改业务类,那么您可以采用这种方法:
基于此SO answer,我们可以编写自己的帮助器:
public static class PropHelper<T>
{
public static string PropName<R>(Expression<Func<T,R>> exp)
{
var mem = exp.Body as MemberExpression;
if(mem != null) return mem.Member.Name;
throw new ArgumentException("Invlaid Property Name");
}
}
并使用它:
comboBox1.DisplayMember = PropHelper<Order>.PropName(o => o.OrderName);
comboBox1.ValueMember = PropHelper<Order>.PropName(o => o.OrderNum);
comboBox1.DataSource = list.ToArray<Order>();
答案 1 :(得分:2)
下面是我在几个ASP.NET应用程序中使用的修改过的类。我在你的样本中分配它的方式是这样的:
var orders = model.GetOrders(...);
comboBox1.DisplayMember = OrderQueryResults.DisplayMember;
comboBox1.ValueMember = OrderQueryResults.ValueMember;
comboBox1.DataSource = orders.Results;
类别:
public sealed class OrderQueryResults : IOrderQueryResults
{
private const string DisplayName = "OrderName";
private const string ValueName = "OrderNum";
private readonly IEnumerable<IOrderQueryResult> results;
private readonly object extra;
private OrderQueryResults(IEnumerable<IOrderQueryResult> results, object extra)
{
this.results = results;
this.extra = extra;
}
public string DisplayMember
{
get
{
return DisplayName;
}
}
public string ValueMember
{
get
{
return ValueName;
}
}
public IEnumerable<IOrderQueryResult> Results
{
get
{
return this.results;
}
}
public object Extra
{
get
{
return this.extra;
}
}
public static IOrderQueryResults Create(IEnumerable<IOrderQueryResult> results, object extra)
{
if (results == null)
{
throw new ArgumentNullException("results");
}
return new OrderQueryResults(results.ToList(), extra);
}
}
答案 2 :(得分:2)
这些只是Order
的属性,对吧?所以你可以使用const
- 这比代码中的文字要好得多 - 但如果你愿意,你当然可以在运行时更改它们。你只需要知道它们是什么。
在您的类中,“OrderName”和“OrderNum”只是表示属性名称的字符串,因此如果您的Order
类中碰巧有其他属性,则可以获取这些属性的名称和例如,从某些用户操作中分配它们。
如果您愿意,可以使用反射来检查Order
类。类似的东西:
Type theType =(typeof(Order));
// Get the public properties.
PropertyInfo[] thePropertyInfo =
theType.GetProperties(BindingFlags.Public|BindingFlags.Instance);
要获取该PropertyInfo数组中任何特定属性的名称,您可以这样:
thePropertyInfo[i].Name;
会给你对象中第i个属性的名称。
那么,你可以说,将这些属性放入某个列表中,该列表本身绑定到控件 - 如ComboBox
,然后在运行时选择DisplayMember
和{{1}将被使用,然后只需设置它们,绑定将自动更新。
答案 3 :(得分:0)
最好使用置于Order类中的const字符串,并在绑定数据源时随处使用这些常量。