Невозможно найти управление в контроллере asp.net Repeater - PullRequest
3 голосов
/ 23 августа 2010

Это поставило меня в тупик.Я пытаюсь найти флажок в динамически загружаемом шаблоне ретранслятора 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");
        }
    }
}

Я могу только думать, что флажок скрыт глубже вгде-то иерархия, но я не уверен, как получить к нему доступ, поскольку я думал, что 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>                    

Ответы [ 5 ]

2 голосов
/ 24 августа 2010

У меня есть этот метод расширения как часть моего инструментария:

    /// <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");
1 голос
/ 23 августа 2010

Любая причина, по которой вы не реализуете 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 голосов
/ 28 августа 2013

Вы используете шаблоны верхнего / нижнего колонтитула вообще?Если да, вам нужно проверить тип шаблона, который вызывается ItemDataBound ().ItemDataBound () будет вызываться для каждого шаблона, включая верхний и нижний колонтитулы.Наличие HeaderTemplate вызовет ItemDataBound () перед его вызовом на последующих ItemTemplates, и поскольку интересующий элемент управления не содержится в заголовке, вы ничего не получите с FindControl ().Вызывая FindControl () только в том случае, если тип элемента, который вызвал ItemDataBound (), является Item / AlternatingItem, вы предотвращаете возвращение значения null / Nothing в тщетном поиске элемента управления.

0 голосов
/ 24 августа 2010

Я никогда раньше не устанавливал шаблон в code-behind, но кажется, что если ваш сгенерированный HTML содержит строку <ItemTemplate>, как вы указали, что-то там не работает должным образом.

0 голосов
/ 23 августа 2010

Вам, вероятно, следует просмотреть сгенерированный html, чтобы точно определить, где находится элемент управления.За исключением того, что если вы выполните итерацию по всем элементам управления и их дочерним элементам управления, вы в конечном итоге найдете его.

...