代码之家  ›  专栏  ›  技术社区  ›  Jamie Dixon

转发器控制-取消特定项目的绑定

  •  7
  • Jamie Dixon  · 技术社区  · 15 年前

    在转发器控件中,是否有一种在呈现页面之前取消绑定某些项的方法?

    当前,我们有一个项目集合绑定到中继器,如果该项目不是当前语言的一部分,我们将隐藏该项目。

    我希望能够对中继器进行计数,并取回一个有效的数字。不包括隐藏项的计数。

    是否可以在 ItemDataBound 事件?

    更新

    对于要绑定的集合中的每个项,我们在 项目数据库 有关该项的进一步信息,如语言等,这将阻止我们在绑定前筛选绑定数据。

    4 回复  |  直到 12 年前
        1
  •  2
  •   Jeff Sternal    15 年前

    我同意其他答案-最好的解决方案(对于性能和代码清晰性而言)是重新设计页面,以便筛选出无效条目。 之前 数据绑定。

    大多数数据源不允许我们在ASP.NET迭代它们时删除它们的项。例如,如果绑定到一个简单的泛型 List<T> ,并且在迭代时移除一个项,该列表将 InvalidOperationException .

    在其他情况下,ASP.NET实际上迭代数据源的副本。如果你绑定到 DataTable ,ASP.NET使用内容的副本(默认数据视图),而不是迭代源行本身-您可以在迭代时从基础数据源中移除项,但不会影响数据绑定操作。

    如果预先过滤项目确实不是一个选项,那么您当前的解决方案很好:只需隐藏项目!如果需要获取正确的计数,请跟踪itemDatabound处理程序中的无效项数,并将其公开为页级属性:

    if (IsInvalid(args.Item.DataItem)) {
        this.invalidItemCount++;
        // code to hide the current item
    }
    
        2
  •  3
  •   dh.    15 年前

    如果这些隐藏项中没有特定的需求,则更合适的解决方案可能是筛选绑定的集合。类似的东西

    items.Where(i => i.IsInLanguage(currentLanguage));
    

    更新:

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

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

    所以所有的过滤都是预先应用的

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

        3
  •  2
  •   JoshBerke    15 年前

    为什么不在绑定前过滤数据源呢?因此,假设您正在使用一些自定义对象:

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

    如果你不需要它们,首先不要把它们捆起来。

    更新

    如果有可能的话,你应该事先从数据库中提取信息。这些单子很大吗?如果是这样,对列表中的每个项目点击一次DB,就会显示为性能问题。

        4
  •  2
  •   atxe AlianaWolf    12 年前

    答案很简单,你只要设定 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 . 如果您正在进行任何类型的分页,可能会出现问题,因为这样会导致呈现的页面大小不一致。