2010-08-23 4 views
3

Это меня озадачило. Я пытаюсь найти флажок в динамически загружаемом шаблоне ретранслятора asp.net. Шаблон работает отлично, и привязка данных прекрасна, и все отображается нормально, но я не могу найти элемент управления! Есть идеи?Невозможно найти управление в 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

Любая причина, по которой вы не применяете метод OnDataBinding для CheckBox?

Пример:

<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

, который, похоже, работает с первой привязкой, но при событии postback checkbox он теряет его - возможно, потому, что это динамически загруженный шаблон. – Dkong

+0

@ Dkong не уверен, что динамическая часть должна иметь значение. У вас 'ViewState' выключен для' Repeater'? Помните, что на обратной стороне связанный код исчезнет, ​​если вы снова вернетесь (не проверяете на '! IsPostBack') или' ViewState', чтобы у вас была повторная пересылка с каждым запросом. – Kelsey

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 вызывает ItemDataBound() до того, как оно будет вызвано в последующих ItemTemplates, и поскольку элемент управления интереса не содержится в заголовке, вы ничего не получаете с помощью 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