3

これは私を困惑させました。動的に読み込まれた asp.net Repeater テンプレートでチェックボックスを見つけようとしています。テンプレートは正常に機能し、データバインディングも正常に機能し、すべて正常に表示されますが、コントロールが見つかりません! 何か案は?

これはリピーター コードです (別のスタイルの代替テンプレート用に同様のものがあります)。

<%@ 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");

...そして最後に、これがチェックボックスを見つけようとする方法です(ただし、nullが表示され続けます)

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>                    

4

5 に答える 5

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");
于 2010-08-23T20:29:47.463 に答える
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.
}

このコードは、データにバインドされたチェックボックスごとに実行されるため、必要なことは何でも実行でき、コントロールを探す必要はありません。通常、これはデータ バインディングを行う最良の方法です。コードのスコープがコントロール レベルにまで及ぶため、常にすべてを検索し、レコード レベルで検索名をハードコードする必要がないからです。

于 2010-08-23T18:08:05.183 に答える
0

生成された html を表示して、コントロールがどこにあるかを正確に確認する必要があります。すべてのコントロールとその子コントロールを反復処理すると、最終的にそれを見つけることができます。

于 2010-08-23T17:56:39.687 に答える
0

これまでコード ビハインドでテンプレートの設定を使用したことはありませんが、生成された HTML に指定した<ItemTemplate>ような行が含まれている場合、そこで何かが正しく機能していないようです。

于 2010-08-23T20:44:22.923 に答える
0

ヘッダー/フッター テンプレートを使用していますか? その場合は、ItemDataBound() が呼び出されているテンプレートのタイプを確認する必要があります。ItemDataBound() は、ヘッダーとフッターを含むすべてのテンプレートで呼び出されます。HeaderTemplate が存在すると、後続の ItemTemplate で呼び出される前に ItemDataBound() がトリガーされます。目的のコントロールがヘッダーに含まれていないため、FindControl() では何も得られません。ItemDataBound() を呼び出したアイテム タイプが Item/AlternatingItem である場合にのみ FindControl() を呼び出すことで、コントロールの無駄な検索で 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
于 2013-08-27T23:46:35.537 に答える