ASP.. NET OnClick在中继器中不发射.具有自定义控件的ItemTemplate

本文关键字:自定义控件 ItemTemplate 发射 OnClick NET 中继器 ASP | 更新日期: 2023-09-27 18:10:16

标题有点拗口,但我在这个问题上有点卡住了。

我有一个搜索结果页面,有一个自定义控件,有一个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>

背后的代码: searchresultcontrol . asx .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);
        }
    }
}

(坦白说,我是从这个问题得到这个想法的)

SetValue调用SearchResultItem中的疾病属性,该属性反过来调用以下方法来构建链接、设置文本和事件:

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);
        }
    }
}
这是SearchResultItem 的布局
<div id="SearchResultItemDiv" class="MainSearchResultItem">
    <asp:PlaceHolder ID="DiseaseStatePlaceHolder" runat="server">
    </asp:PlaceHolder>
</div>

最初我尝试设置Click事件,但这根本不起作用。然后我设置了CommandArgumentCommandName,但这似乎没有奏效。我想Command事件可能需要设置,但还是没有运气。我应该注意到,当单击链接时,将调用 searchresultcontrol . asx .cs中的Repeater1_ItemCreated。但是由于没有数据在e.Item.DataItem是空的,我失去了结果。

在关于同一问题的一个问题中,有人建议添加OnItemCommand,但即使这样也没有被调用。

我也读过一个ASP的Stumper。. NET问题与ASP的难题。NET问题:解决了!,但无济于事。

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

帮助总是很感激的。

ASP.. NET OnClick在中继器中不发射.具有自定义控件的ItemTemplate

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

如果您可以在到达Page_Load事件之前重新创建LinkButton控件,例如OnInit,那么一切都应该正常工作。

对于简单的页面,上面的方法通常工作得很好,但是有些情况下,在OnInit期间重新创建控件需要很多开销,例如在ViewState中存储计数器或数组,以便您可以跟踪回发后需要重新创建的控件。在这些情况下,我建议你看看Denis Bauer的DynamicControlsPlaceHolder。这个控件能够持久化动态控件,而不需要任何额外的代码,这是非常棒的。

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

问题可能是你没有再做DataBind()

因为您是在动态地构建按钮,所以当页面返回时,按钮还没有创建,并且无法计算出应该触发哪个单击事件。

尝试去掉IsPostBack检查,这样每次页面加载时,您都要重新构建repeater