2010-08-23 90 views
3

這讓我難住。我正試圖在動態加載的asp.net Repeater模板中找到一個複選框。該模板工作正常,數據綁定是好的,一切都很好,但我找不到控制!有任何想法嗎?無法找到控制在asp.net中繼器控制

這是中繼器代碼(我有一個類似的備用模板用不同的風格):

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="template-tasks- 

incomplete.ascx.cs" Inherits="controls_template_tasks_incomplete" %> 
<ItemTemplate> 
    <div class="task"> 
     <div class="date"><asp:CheckBox ID="chkIsComplete" runat="server" 
       AutoPostBack="True" /><%# DataBinder.Eval(((RepeaterItem)Container).DataItem, "DateCreated")%></div> 
     <div class="description"><%# DataBinder.Eval(((RepeaterItem)Container).DataItem, "TaskDescription")%></div> 
    </div>      
</ItemTemplate> 

這是我如何加載模板(正常工作)

rptTasks.ItemTemplate = LoadTemplate("~/controls/template-tasks-incomplete.ascx"); 
     rptTasks.AlternatingItemTemplate = LoadTemplate("~/controls/template-tasks-incomplete-alt.ascx"); 

...最後這是我如何嘗試找到複選框(但一直保持爲空)

protected void rptTasks_ItemDataBound(object sender, RepeaterItemEventArgs e) 
{ 
    if (e.Item.ItemType == ListItemType.AlternatingItem || e.Item.ItemType == ListItemType.Item) 
    { 
     CheckBox chkBoxIsComplete = (CheckBox)e.Item.FindControl("chkIsComplete"); 

     if (chkBoxIsComplete != null) 
     { 
      int taskID = (int)DataBinder.Eval(e.Item.DataItem, "TaskID"); 
     } 
    } 
} 

I c只是認爲複選框被深埋在層次結構的某個地方,但我不確定如何訪問它,因爲我認爲FindControl會這樣做。

這是系統產生的HTML:

<ItemTemplate> 
<div class="task"> 
    <div class="date"><input id="ctl00_ContentPlaceHolder1_rptTasks_ctl00_ctl00_chkIsComplete" type="checkbox" name="ctl00$ContentPlaceHolder1$rptTasks$ctl00$ctl00$chkIsComplete" onclick="javascript:setTimeout('__doPostBack(\'ctl00$ContentPlaceHolder1$rptTasks$ctl00$ctl00$chkIsComplete\',\'\')', 0)" />23/08/2010 11:53:00 PM</div> 
    <div class="description">test task</div> 
</div>      

回答

0

你或許應該查看生成的HTML,看看究竟在何處的控制。除非你遍歷所有的控件和他們的子控件,否則你最終會找到它。

1

爲什麼不實施CheckBoxOnDataBinding方法的任何原因?

例子:

<asp:CheckBox ID="chkIsComplete" runat="server" 
    AutoPostBack="True" OnDataBinding="chkIsComplete_DataBinding" /> 

然後在你的代碼隱藏你訪問它:

protected void chkIsComplete_DataBinding(object sender, System.EventArgs e) 
{ 
    CheckBox chk = (CheckBox)(sender); 
    int taskID = (int)(Eval("TaskID")); 
    // do whatever it is you need to do... you can use Eval to get any record value 
    // of the current row and your sender is the actually control itself. 
} 

該代碼將運行勢必複選框,每一個數據,所以你可以做任何事是你需要做的,而不是有關心尋找控制。通常這是進行數據綁定的最佳方式,因爲它將您的代碼範圍限制在控制級別,因此您不必一直搜索所有內容並在記錄級別對搜索名稱進行硬編碼。

+0

似乎在第一個綁定上工作,但在複選框回發事件它丟失它 - 也許是因爲它是一個動態加載的模板。 – Dkong 2010-08-23 18:25:29

+0

@Dkong不確定動態部分是否重要。你有'ViewState'關閉'Repeater'嗎?請記住,如果您再次重新綁定(不檢查「!IsPostBack」)或關閉「ViewState」,綁定代碼將會消失,因此每次請求都會重新綁定。 – Kelsey 2010-08-23 20:57:39

2

我有這樣的擴展方法,我的工具包的一部分:

/// <summary> 
    /// find the control with the given ID, recursively below the root 
    /// </summary> 
    public static Control FindControlRecursive(this ControlCollection root, string id) 
    { 
     foreach (Control control in root) 
     { 
      if (control != null && id.Equals(control.ID, StringComparison.InvariantCultureIgnoreCase)) 
      { 
       return control; 
      } 
      else 
      { 
       Control result = FindControlRecursive(control.Controls, id); 
       if (result != null) 
       { 
        return result; 
       } 
      } 
     } 

     return null; 
    } 

用法:

CheckBox chkBoxIsComplete = (CheckBox)e.Item.Controls.FindControlRecursive("chkIsComplete"); 
0

我從來沒有使用設定的模板代碼隱藏過,但似乎如果您生成的HTML包含像您指示的<ItemTemplate>行,在那裏有些工作不正常。

0

您是否使用了頁眉/頁腳模板?如果你是,你需要檢查被調用的ItemDataBound()的模板類型。 ItemDataBound()將在每個模板上被調用,包括頁眉和頁腳。 HeaderTemplate的存在會在後續ItemTemplates被調用之前觸發ItemDataBound(),並且由於感興趣的控件未包含在標題中,因此FindControl()不會包含任何內容。通過僅調用FindControl(),其中名爲ItemDataBound()的項目類型是Item/AlternatingItem,您可以防止返回null/Nothing枉費您的控制權。

<asp:Repeater ID="rpt" runat="server" OnItemDataBound="rpt_ItemDataBound"> 

<HeaderTemplate><table><tr><td>Header</td></tr></HeaderTemplate> 

<ItemTemplate><tr><td><asp:button id="Button" runat="server"/></td></tr></ItemTemplate> 

<FooterTemplate><tr><td>Footer</td></tr></table></FooterTemplate> 

</asp:Repeater> 

Protected Sub rpt_ItemDataBound(sender As Object, e As System.Web.UI.WebControls.RepeaterItemEventArgs) 
    If (e.Item.ItemType = ListItemType.Item) Or (e.Item.ItemType = ListItemType.AlternatingItem) Then 
     Dim Button As Button = CType(e.Item.FindControl("Button"), Button) 
    End If 
End Sub