简体   繁体   English

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

[英]ASP.NET OnClick not firing in Repeater.ItemTemplate that has a custom control

Title is a bit of a mouthful, but I'm a bit stuck on this issue. 标题有点拗口,但我对这个问题有点困惑。

I have a search result page with has a custom control that has a Repeater . 我有一个搜索结果页面,其中包含一个具有Repeater的自定义控件。 The ItemTemplate in the repeater is a PlaceHolder so I can construct the Item in a particular format; 转发器中的ItemTemplatePlaceHolder因此我可以以特定格式构造Item; more specifically, I have a string of 'diseases' that come in the form of Disease1|disease2|disease3 and need to be given links for each disease. 更具体地说,我有“病”是进来的形式的字符串Disease1|disease2|disease3和需要给予每种疾病的联系。

Now for some code: 现在有些代码:

The following is the SearchResultControl.ascx 以下是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>

The code behind: SearchResultControl.ascx.cs 后面的代码: 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);
        }
    }
}

(Full disclosure, I got this idea from this question ) (完全披露,我从这个问题得到了这个想法)

The SetValue calls the DiseaseStates property in SearchResultItem which in turn calls the following method to build the links, set the text, and the events: 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);
        }
    }
}

This is the layout for the SearchResultItem 这是SearchResultItem的布局

<div id="SearchResultItemDiv" class="MainSearchResultItem">
    <asp:PlaceHolder ID="DiseaseStatePlaceHolder" runat="server">
    </asp:PlaceHolder>
</div>

Initially I tried setting the Click event, but that doesn't work at all. 最初我尝试设置Click事件,但这根本不起作用。 I then set the CommandArgument and CommandName but that didn't seem to do the trick. 然后我设置CommandArgumentCommandName但似乎没有做到这一点。 I figured the Command event might need to be set, but again, no luck. 我认为Command事件可能需要设置,但再次,没有运气。 I should note that when a link is clicked the Repeater1_ItemCreated in SearchResultControl.ascx.cs is called. 我应该注意,当单击一个链接时,将调用SearchResultControl.ascx.cs中Repeater1_ItemCreated But since there is no data in e.Item.DataItem is null and I lose the results. 但由于e.Item.DataItem没有数据为空,我丢失了结果。

In one of the questions regarding the same issue, it was suggested that the OnItemCommand be added, but even that doesn't get called. 在的一个问题,关于同一问题,有人建议OnItemCommand被添加,但即使这样不会被调用。

I also read A Stumper of an ASP.NET Question and A Stumper of an ASP.NET Question: SOLVED! 我还阅读了一个ASP.NET问题 的Stumper和一个ASP.NET问题的问题:解决了! , to no avail. ,无济于事。

What could I possibly be doing wrong? 我怎么可能做错了? All of the correct event hookups seem there, I'm checking for IsPostBack and not doing DataBind() again. 所有正确的事件连接似乎都在那里,我正在检查IsPostBack并且没有再次执行DataBind() blaaargharaggh blaaargharaggh

Help is always greatly appreciate. 帮助总是非常感激。

I believe you're running into this issue because the LinkButton controls are recreated too late in the page lifecycle. 我相信你遇到了这个问题,因为LinkButton控件在页面生命周期中太晚了。 You have to remember that when the page is posted back, the control technically does not exist anymore, so the event handler cannot be fired. 您必须记住,当页面回发时,控件在技术上不再存在,因此无法触发事件处理程序。

If you can recreate the LinkButton controls somewhere before the Page_Load event is reached, like OnInit for example, everything should work fine. 如果你可以在到达Page_Load事件之前的某个地方重新创建LinkButton控件,比如OnInit ,那么一切都应该可以正常工作。

For simple pages the above usually works very well, but there are circumstances where recreating controls during OnInit requires a lot of overhead, such as storing counters or arrays in ViewState so you can keep track of the controls that need to be recreated after postback. 对于简单页面,上述通常非常有效,但在某些情况下,在OnInit期间重新创建控件需要大量开销,例如在ViewState中存储计数器或数组,以便您可以跟踪回发后需要重新创建的控件。 In these situations I would suggest taking a look at the DynamicControlsPlaceHolder by Denis Bauer. 在这些情况下,我建议看看Denis Bauer的DynamicControlsPlaceHolder This control is capable of persisting dynamic controls without any addtional code required, which is pretty awesome. 此控件能够持久保存动态控件,无需任何附加代码,这非常棒。

Here's a link to the latest version: 这是最新版本的链接:
http://www.denisbauer.com/ASPNETControls/DynamicControlsPlaceholder.aspx http://www.denisbauer.com/ASPNETControls/DynamicControlsPlaceholder.aspx

The problem might be that you're not doing the DataBind() again. 问题可能是您没有再次执行DataBind()

Because you're building the buttons on the fly, when the page post backs, the buttons haven't been created and are unable to work out which click event it should be firing. 因为您正在构建按钮,当页面回发时,按钮尚未创建,并且无法确定应该触发的单击事件。

Try getting rid of the IsPostBack check, so each time the page loads, you're re-build the repeater . 尝试摆脱IsPostBack检查,因此每次页面加载时,您都会重新构建repeater

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM