我使用EF实体实例将数据绑定到许多FormView控件,但我不得不诉诸于这个荒谬的组合,以实现我想要的东西,而不使用EntityDataSource控件:
propertyHeaderSection.DataSource = new List<PropertyDetailsModel> { _propertyDetails };
我怀疑我将不得不从FormView中派生我自己的控件,并使它能够接受几乎POCO作为数据源。我从哪里开始呢?
这是我的实现,有点像patmortech的想法,但我也发现,BaseDataBoundControl上的ValidateDataSource方法是什么抛出异常在运行时,如果你的数据源是不可枚举的。
public class CustomFormView : System.Web.UI.WebControls.FormView
{
public override object DataSource
{
get
{
if (!(base.DataSource is IEnumerable))
return new[] {base.DataSource};
return base.DataSource;
}
set
{
base.DataSource = value;
}
}
// This method complains at run time, if the datasource is not
// IListSource, IDataSource or IEnumerbale
protected override void ValidateDataSource(object dataSource)
{
//base.ValidateDataSource(dataSource);
}
}
编辑:考虑到这个建议,我已经对我检查分配的数据源是否是可枚举的方式做了一些改变。我还设法创建了一个示例应用程序(VS 2010解决方案)来演示这些变化。该应用程序可从http://raghurana.com/blog/wp-content/attachments/FormViewDataProblem.zip
下载。简而言之,这就是我要检查的,以确保现有的数据源已经可以枚举或不:
public static bool CanEnumerate( this object obj )
{
if (obj == null) return false;
Type t = obj.GetType();
return t.IsArray ||
t.Implements(typeof (IEnumerable).FullName) ||
t.Implements(typeof (IListSource).FullName) ||
t.Implements(typeof (IDataSource).FullName);
}
如果这不是理想的功能,请随意提出更多的修改建议。欢呼。
不确定这是世界上最好的主意,但这就是如何从FormView派生出允许单个对象数据源值的方法。它基本上执行与ValidateDataSource内部相同的检查,然后如果项不是有效类型,则为其创建列表包装器。
public class SingleObjectFormView : System.Web.UI.WebControls.FormView
{
public override object DataSource
{
get
{
return base.DataSource;
}
set
{
//will check if it's an expected list type, and if not,
//will put it into a list
if (! (value == null || value is System.Collections.IEnumerable || value is System.ComponentModel.IListSource || value is System.Web.UI.IDataSource) )
{
value = new List<object> { value };
}
base.DataSource = value;
}
}
}