2011-06-03 120 views
2

我有一个页面,其中列出了几家酒店,并且为每个酒店列出了用户选择的每个日期的价格。嵌套中继器 - 从子中继器访问父节点中的控制器

我的HTML看起来像这样:

<table> 
<asp:Repeater ID="rptrHotels" runat="server"> 
    <ItemTemplate> 
     <tr><td><%# Eval("HotelName") %></td></tr> 
     <tr> 
      <asp:Repeater ID="rptrHotelRates" runat="server" DataSource='<%# GetHotelRates(Container.DataItem) %>'> 
       <ItemTemplate> 
        <td> 
         <span class="date"><%# Eval("Date") %></span> 
         <span class="price">$<%# Eval("Price") %></span> 
        </td> 
       </ItemTemplate> 
      </asp:Repeater> 
      <td> 
       <span class="date">Total</span> 
       <span class="price">$<asp:Literal ID="litTotal" runat="server" /></span> 
      </td> 
     </tr>     
    </ItemTemplate> 
</asp:Repeater> 
</table> 

我的后台代码:

protected void Page_Load(object sender, EventArgs e) 
{ 
    if (!Page.IsPostBack) 
    { 
     DateTime startDate = Request.QueryString["StartDate"]; 
     DateTime endDate = Request.QueryString["EndDate"]; 

     List<Hotel> hotels = GetHotels(startDate, endDate); 
     rptrHotels.DataSource = hotels; 
     rptrHotels.DataBind(); 
    } 
} 


protected List<Rate> GetHotelRates(object item) 
{ 
    DateTime startDate = Request.QueryString["StartDate"]; 
    DateTime endDate = Request.QueryString["EndDate"]; 
    Hotel hotel = (Hotel)item; 

    List<Rate> rates = GetRates(hotel, startDate, endDate); 

    decimal total = (from r in rates 
        select r.Price).Sum(); 

    return rates; 
} 

在我GetHotelRates()函数,我总结了所有的速度越来越总价价格。但我需要以某种方式将该值放在litTotal中,该值位于子转发器之外,但位于父转发器之内。

我该怎么做?

+0

你明白了吗? – ashelvey 2011-06-05 20:33:27

回答

5

在你的项目绑定事件做这样的事情:

((Literal)((Repeater)sender).Parent.FindControl("litTotal")).Text; 

你可能需要做父另投它得到一个中继器,但我不知道。

+0

我的GetHotelRates()函数中没有'object sender'变量。我需要做些什么来补充? – Steven 2011-06-03 21:09:32

+0

如果你有一个ItemDataBind事件,你只会得到。基本上,每当一个物品被数据绑定时,就会使用上面的那一行代码。 – 2011-06-03 23:26:05

+0

我从来没有想到我可以将发件人作为容器中继器! +1代码的一大堆。 – seanxe 2012-04-13 15:33:50

0

你总是可以尝试一些NamingContainer.Parent.Parent ....的FindControl(夸张)的魔法,但一个更清洁的方式做到这一点是只创建一个单独的方法来获取您的总:

protected decimal GetHotelTotal(object item) 
{ 
    Hotel hotel = (Hotel)item; 

    List<Rate> rates = GetRates(hotel, startDate, endDate); 

    decimal total = (from r in rates 
       select r.Price).Sum(); 
    return total; 
} 

并在你的文字中称呼:

<asp:Literal ID="litTotal" runat="server" Text="<%# GetHotelTotal(Container.DataItem) %>" /> 
+0

当然,如果运行GetRates的代价很高,您可能需要考虑稍微有点不同的设计,既可以保留呼叫的价值,也可以使其成为Hotel对象的一部分,因此它已经存在。 – ashelvey 2011-06-03 20:49:39

+0

我想我其实更喜欢第二种方法..我会添加一个属性列表 HotelRates到您的GetRates填充的酒店。然后,您不必在DataBinding时间混淆这一点,并且您已准备好将所有东西都干净地使用。 – ashelvey 2011-06-03 20:51:51