在Repeater中设置控件的复杂成员

时间:2011-10-05 20:20:25

标签: asp.net repeater

TL; DR

我的Repeater中的Control需要特殊的实例化才能有用。如何为转发器构造的每个控件执行此特殊实例化?

设置

我有三个班级:

ComplexData 即可。

包含许多不同类型的公共成员,例如:

  • int favorite_integer
  • 食物what_you_had_for_breakfast_this_morning
  • string capital_of_alaska
  • PhaseOfMoon when_magic_runes_will_reveal_themelves_on_the_mysterious_artifact
等等等等

ComplexDataDisplay

用于以美学方式呈现ComplexData实例的控件。公开单个公共成员ComplexMember DataToDisplay。当用户设置DataToDisplay时,控件中的标签将使用适当的数据填充自己。

MultiComplexDataDisplay

使用Repeater在一行中显示多个ComplexDataDisplays的控件。它包含private List<ComplexData> datasToDisplay,它是转发器的数据源。它提供了两个公共方法addComplexData(ComplexData)emptyAllData(),让用户可以操作datasToDisplay。

问题

在数据绑定过程中,我不知道如何设置每个ComplexDataDisplay的DataToDisplay成员。

看起来转发器中的控件通常从前端填充,例如

<asp:Repeater runat="server" id="linkRepeater">
    <a href="<%# getUrl(Container.DataItem) %>"> <%# getDescription(Container.DataItem) %> </a>
</asp:Repeater>

据我了解,在数据绑定期间,转发器实例化每个锚元素,使用任何数据源来设置href和描述。

我尝试复制此行为只会导致出现空白页:

<asp:Repeater runat="server" id="displayRepeater">
    <ComplexDataDisplay id="dataDisplay" DataToDisplay="<%# Container.DataItem %>" runat="server"
</asp:Repeater>

我能想到的另一件事就是修改ComplexDataDisplay,以便它为ComplexData的每个成员都有一个公共成员。然后在转发器中我可以做到:

<asp:Repeater runat="server" id="displayRepeater">
    <ComplexDataDisplay id="dataDisplay" runat="server"
        favorite_integer="<%# get_favorite_integer(Container.DataItem) %>"
        what_you_had_for_breakfast_this_morning="<# get_what_you_had_for_breakfast_this_morning(Container.DataItem) %>"
        <%--etc etc etc--%>
    />
</asp:Repeater>

这似乎非常不受欢迎,因为对于ComplexData的每个成员,我必须在ComplexDataDisplay中编写相应的公共成员,并在MultiComplexDataDisplay中编写get_whatever(DataItem)方法。最重要的是,我甚至不知道它是否会起作用,因为ComplexData的一半成员是复杂的数据类型,这可能会或可能不会以这种方式设置。

我正在寻找答案

以下其中一项:

  • 直接回答TLDR部分提出的问题 - 在数据绑定期间为转发器中的每个控件执行特殊实例化的方法,或者在事后不久迭代它们的方法。
  • 关于如何最好地重构代码的建议,以便不再需要特殊实例化来显示我的许多复杂数据。我愿意添加/更新/删除除ComplexData之外的任何类,因为我有义务按原样维护其接口。
  • 与我的问题相关的最佳做法/参考/文档,它将指导我自己寻找解决方案。

1 个答案:

答案 0 :(得分:3)

你可以绑定ItemDataBound内的子控件,我无法跟踪哪些对象被绑定,所以在需要的地方替换:

<asp:Repeater runat="server" id="displayRepeater" OnItemDataBound="displayRepeater_ItemDataBound">
    <uc1:ComplexDataDisplay id="dataDisplay" runat="server" />
</asp:Repeater>


 protected void displayRepeater_ItemDataBound(Object Sender, RepeaterItemEventArgs e) 
 {
      // Execute the following logic for Items and Alternating Items.
      if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem) 
      {
         //get object bound to row
         ComplexData c = (ComplexData)e.Item.DataItem;
         //find the child control to bind
         ComplexDataDisplay cds = (ComplexDataDisplay)e.Item.FindControl("dataDisplay");
         //set properties or any other complex things you need to do
         cds.DataToDisplay = c.ComplexMember;
         cds.DataBind(); // if this control has repeaters, it's ItemDataBound will fire, repeat this process untill all your controls are bound properly
      }
   }