在中继器控件中,是否有某种方法在页面呈现之前解除某些项目的绑定?中继器控制 - 取消特定项目的绑定
当前我们有一组物品被绑定到一个转发器,如果该物品不是当前语言的一部分,我们会隐藏该物品。
我希望能够对中继器进行计数并获得有效的数字。计数不包括隐藏的项目。
是否有可能去绑定特定项目或许在ItemDataBound
事件?
更新
对于我们结合集合中的每个项目,我们的ItemDataBound
有关项目的详细信息,如语言等,这期间检查数据库正在阻止我们过滤绑定绑定它之前的数据。
在中继器控件中,是否有某种方法在页面呈现之前解除某些项目的绑定?中继器控制 - 取消特定项目的绑定
当前我们有一组物品被绑定到一个转发器,如果该物品不是当前语言的一部分,我们会隐藏该物品。
我希望能够对中继器进行计数并获得有效的数字。计数不包括隐藏的项目。
是否有可能去绑定特定项目或许在ItemDataBound
事件?
更新
对于我们结合集合中的每个项目,我们的ItemDataBound
有关项目的详细信息,如语言等,这期间检查数据库正在阻止我们过滤绑定绑定它之前的数据。
我同意其他答案 - 最好的解决方案(对于性能和代码清晰度)是重新设计页面,以便您可以在数据绑定之前筛选出无效输入项。
大多数数据源不允许我们在ASP.NET迭代它们时删除它们的项目。例如,如果绑定到一个简单的通用List<T>
,并且在迭代它时删除了一个项目,则该列表将抛出一个InvalidOperationException
。
在其他情况下,ASP.NET实际上会迭代数据源的副本。如果绑定到DataTable
,则ASP.NET会使用内容的副本(默认DataView),而不是自己迭代源行 - 您可以在迭代时从基础数据源移除项目,但不影响数据绑定操作。
如果事先过滤项目确实不是一个选项,您目前的解决方案是好的:只需隐藏项目!如果你需要获得最重要的是正确的计数,跟踪无效项目的数量在你的ItemDataBound处理程序,并公开为页面级属性:
if (IsInvalid(args.Item.DataItem)) {
this.invalidItemCount++;
// code to hide the current item
}
如果这些隐藏项目中没有特定需要,则更合适的解决方案可以是过滤绑定集合。喜欢的东西
items.Where(i => i.IsInLanguage(currentLanguage));
更新:
至于我,我想用这个办法:
var items = db.
Where(i => i.IsInLanguage(currentLanguage)).
Where(i => i.SomeField == anotherFilterParameter);
repeater.DataSource = items;
repeater.DataBind();
因此,所有过滤事先
应用这将减少廿四数旅行到数据库,以及更好的性能
我会更新我的OQ,但基本上,我们不知道哪些项目设置为可见等直到ItemDataBound事件。每个项目都有一个ID,然后我们到数据库获取额外的细节。 – 2010-02-08 14:37:42
ItemDataBound会发生什么,使过滤成为可能?您目前的语言是否仅在当时可用? – 2010-02-08 14:39:07
是的。基本上我们有一些称为“页面”ID的集合,并且在绑定每个项目时,我们转到数据库,查明它是否是当前语言的一部分,如果不是,则隐藏该项目。 – 2010-02-08 14:40:21
为什么不过滤呃绑定之前的数据源。因此,假如你使用的是一些自定义对象:
myRepeater.DataSource=repository.getItems().Where(item=>item.Language==CurrentLanguage);
如果你不需要他们不摆在首位约束力。
更新
如果这是在所有可能你应该probally拉从DB前期该信息。这些清单很大吗?如果在列表中每个项目敲击一次数据库都会显示为性能问题。
答案是很容易的,你只需设置Visible
财产到false
的项目,它不会被渲染。在这个例子中,我从给产品清单只提供给新客户的项目,如果当前用户的购买历史:
void rpt_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (!userHasPurchaseHistory) { return; }
// filter out products only allowed for new members
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
System.Data.Common.DbDataRecord rec = (System.Data.Common.DbDataRecord)e.Item.DataItem;
if (rec != null)
{
bool newMemberOnly = Convert.ToBoolean(rec["NewMemberOnly"]);
if (newMemberOnly) { e.Item.Visible = false; }
}
}
}
注意上面的数据绑定到一个IDataReader
,您可能需要投e.Item.DataItem
根据你绑定到不同的对象。
另请注意,我绝对不会在绑定时执行另一个数据库查找,您不应该在循环中访问数据库,但只要您绑定的数据有一些可以检查的内容以决定是否要显示它在ItemDataBound
中过滤没有任何问题。如果您正在进行任何类型的分页,这可能会造成问题,因为这会导致呈现不一致的页面大小。
我很想重新设计页面的工作方式,但我们使用EPiServer作为CMS,据我所知,目前方式是我能找到的最好的方式。我目前正在追踪你的最后一次泄露,暴露一个Count属性并将其变为有效项目。可能必须坚持这一点。谢谢回复 :) – 2010-02-08 15:48:53