中继器控制 - 取消特定项目的绑定

时间:2010-02-08 14:30:57

标签: asp.net binding repeater

在转发器控件中,是否有一种方法可以在呈现页面之前对某些项目进行解除绑定?

目前我们有一系列项目被绑定到转发器,如果​​该项目不是当前语言的一部分,我们会隐藏该项目。

我希望能够对转发器进行计数并获得有效数字。计数不包括隐藏项目。

是否可以在ItemDataBound事件中对特定项目进行解除绑定?

更新

对于我们绑定的集合中的每个项目,我们在ItemDataBound期间检查数据库以获取有关该项目的更多信息,例如语言等。这当前阻止我们在绑定数据之前过滤绑定数据

4 个答案:

答案 0 :(得分:3)

如果这些隐藏项目中没有特定需要,更合适的解决方案可能是过滤绑定集合。像

这样的东西
items.Where(i => i.IsInLanguage(currentLanguage));

更新

至于我,我会用这种方法:

var items = db.
      Where(i => i.IsInLanguage(currentLanguage)).
      Where(i => i.SomeField == anotherFilterParameter);

repeater.DataSource = items;
repeater.DataBind();

所以预先应用所有过滤

这将减少数据库的往返次数,从而提高性能

答案 1 :(得分:2)

为什么不在绑定之前过滤数据源。所以假设你使用的是一些自定义对象:

myRepeater.DataSource=repository.getItems().Where(item=>item.Language==CurrentLanguage);

如果您不需要它们,请不要首先绑定它们。

<强>更新

如果可能的话,你应该从数据库中提前获取该信息。这些清单大吗?如果是这样,对列表中的每个项目按一次db将显示为性能问题。

答案 2 :(得分:2)

我同意其他人的答案 - 最佳解决方案(性能和代码清晰度)是重新设计页面,以便您可以在数据绑定之前过滤中的无效条目。

大多数数据源不允许我们在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
}

答案 3 :(得分:2)

答案非常简单,您只需在项目上将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中过滤没有任何问题。如果您正在进行任何类型的分页,则可能会出现问题,因为这会导致呈现不一致的页面大小。