ASP.NET OnClick不在具有自定义控件的Repeater.ItemTemplate中触发

Emm*_*l F 3 .net c# asp.net repeater

标题有点拗口,但我对这个问题有点困惑.

我有一个搜索结果页面,其中包含一个自定义控件Repeater.所述ItemTemplate在转发器是一个PlaceHolder,所以我可以构建项以特定的格式; 更具体地说,我有一系列"疾病",其形式Disease1|disease2|disease3和需要为每种疾病提供联系.

现在有些代码:

以下是SearchResultControl.ascx

<asp:Panel ID="SearchResultPanel" runat="server" ScrollBars="Auto">
    <asp:Repeater ID="Repeater1" runat="server" 
        onitemcreated="Repeater1_ItemCreated" 
        onitemcommand="Repeater1_ItemCommand">
        <ItemTemplate>
            <asp:PlaceHolder ID="ItemTemplatePlaceHolder" runat="server">
            </asp:PlaceHolder>
        </ItemTemplate>
        <SeparatorTemplate>
        <tr>
        <td colspan="6"><hr /></td>
        </tr>
        </SeparatorTemplate>
    </asp:Repeater>
</asp:Panel>
Run Code Online (Sandbox Code Playgroud)

后面的代码:SearchResultControl.ascx.cs

protected void Repeater1_ItemCreated(object sender, RepeaterItemEventArgs e)
{
    if (e.Item.DataItem != null)
    {
        PlaceHolder placeHolder = e.Item.FindControl("ItemTemplatePlaceHolder") as PlaceHolder;
        Control searchResultItem = Page.LoadControl("SearchResultItem.ascx");

        DataRow row = (e.Item.DataItem as DataRowView).Row;

        if (row != null)
        {
            string diseaseState = row["DiseaseStates"] as string;
            searchResultItem.GetType().GetProperty("DiseaseStates").SetValue(searchResultItem, diseaseState, null);

            placeHolder.Controls.Add(searchResultItem);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

(完全披露,我从这个问题得到了这个想法)

SetValue调用SearchResultItem中的DiseaseStates属性,该属性又调用以下方法来构建链接,设置文本和事件:

private void BuildDiseaseStateLabels(string diseaseStates)
{
    PlaceHolder placeHolder = FindControl("DiseaseStatePlaceHolder") as PlaceHolder;
    string[] diseaseStateSplit = diseaseStates.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries);

    int count = diseaseStateSplit.Length;
    foreach (string diseaseState in diseaseStateSplit)
    {
        LinkButton diseaseStateLink = new LinkButton();
        diseaseStateLink.Text = diseaseState;
        //diseaseStateLink.Click += new EventHandler(OnDiseaseStateLinkClick);
        diseaseStateLink.CommandArgument = "<%# Eval(\"PatientID\")+ \";\" + Eval(\"PatientStatus\")+ \";\" + Eval(\"Age\")+ \";\" + Eval(\"DiseaseStates\")%>";
        diseaseStateLink.CommandName = "OnDiseaseStateLinkClick";
        //diseaseStateLink.Command += new CommandEventHandler(OnDiseaseStateLinkClick);

        placeHolder.Controls.Add(diseaseStateLink);

        if (count != 0)
        {
            Label splitLabel = new Label();
            splitLabel.Text = "|";
            placeHolder.Controls.Add(splitLabel);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这是SearchResultItem的布局

<div id="SearchResultItemDiv" class="MainSearchResultItem">
    <asp:PlaceHolder ID="DiseaseStatePlaceHolder" runat="server">
    </asp:PlaceHolder>
</div>
Run Code Online (Sandbox Code Playgroud)

最初我尝试设置Click事件,但这根本不起作用.然后我设置了CommandArgument,CommandName但似乎没有做到这一点.我认为Command事件可能需要设置,但再次,没有运气.我应该注意,当单击一个链接时Repeater1_ItemCreated,会调用SearchResultControl.ascx.cs.但由于没有数据e.Item.DataItem是null,我失去了结果.

在的一个问题,关于同一问题,有人建议,OnItemCommand可以加入,但即使这样不会被调用.

我也看了一个ASP.NET问题的难倒的一个ASP.NET问题的难倒的:解决了!,无济于事.

我怎么可能做错了?所有正确的事件连接似乎都在那里,我正在检查IsPostBack而不是再做DataBind()一次.blaaargharaggh

帮助总是非常感激.

Jam*_*son 5

我相信你遇到了这个问题,因为LinkButton控件在页面生命周期中被重新创建得太晚了.您必须记住,当页面回发时,控件在技术上不再存在,因此无法触发事件处理程序.

如果你可以LinkButtonPage_Load事件到达之前的某个地方重新创建控件OnInit,例如,一切都应该可以正常工作.

对于简单页面,上述通常非常有效,但在某些情况下,重新创建控件OnInit需要大量开销,例如在ViewState中存储计数器或数组,以便您可以跟踪在回发后需要重新创建的控件.在这些情况下,我建议看看DynamicControlsPlaceHolderDenis Bauer.此控件能够持久保存动态控件,无需任何附加代码,这非常棒.

这是最新版本的链接:http:
//www.denisbauer.com/ASPNETControls/DynamicControlsPlaceholder.aspx