ASP.NET的OnClick不是射击Repeater.ItemTemplate,有一个自定义的控制自定义、有一个、不是、NET

2023-09-06 13:11:39 作者:凉了时光病了心脏

标题有点拗口,但我有点坚持在这个问题上。

Title is a bit of a mouthful, but I'm a bit stuck on this issue.

我有一个搜索结果页面有一个自定义的控制,有一个转发。该 ItemTemplate中中的中继器是占位符这样我就可以建立一个特定格式的项目;更具体地讲,我有'病'了进来的形式 Disease1字符串| disease2 |。disease3 ,需要给出的链接每一种疾病

I have a search result page with has a custom control that has a Repeater. The ItemTemplate in the repeater is a PlaceHolder so I can construct the Item in a particular format; 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.

现在一些code:

下面是在 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>

背后的code: 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);
        }
    }
}

(披露,我有这个想法从this问题)

执行setValue调用在DiseaseStates属性的 SearchResultItem 依次调用下面的方法来建立链接,设置文本和事件:

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:

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>

起初,我尝试设置点击的事件,但是,这并不在所有的工作。然后,我将 CommandArgument 的CommandName 但是这似乎并没有这样的伎俩。我想通了命令事件可能需要进行设置,但同样,没有运气。我要指出,当一个链接被点击的 Repeater1_ItemCreated 在 SearchResultControl.ascx.cs 被调用。但是,因为在没有数据 e.Item.DataItem 为空,我输的结果。

Initially I tried setting the Click event, but that doesn't work at all. I then set the CommandArgument and CommandName but that didn't seem to do the trick. I figured the Command event might need to be set, but again, no luck. I should note that when a link is clicked the Repeater1_ItemCreated in SearchResultControl.ascx.cs is called. But since there is no data in e.Item.DataItem is null and I lose the results.

在的一个questions对于同样的问题,有人提出, OnItemCommand 添加,但即使这样不会被调用。

In one of the questions regarding the same issue, it was suggested that the OnItemCommand be added, but even that doesn't get called.

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

I also read A Stumper of an ASP.NET Question and A Stumper of an ASP.NET Question: SOLVED!, to no avail.

我能可能是做错了什么?所有正确的事件进行连接似乎那里,我检查的IsPostBack 并没有做的DataBind()了。 blaaargharaggh 的

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. blaaargharaggh

帮助总是很大AP preciate。

Help is always greatly appreciate.

推荐答案

我相信你遇到了这种问题,因为的LinkBut​​ton 控件重新在页面为时已晚生命周期。你要记住,当页面回发,控制技术上不存在了,因此事件处理程序不能被解雇。

I believe you're running into this issue because the LinkButton controls are recreated too late in the page lifecycle. 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.

如果您可以重新创建的LinkBut​​ton 控制地方的的Page_Load 事件之前达到,如的OnInit 为例,则应当一切正常。

If you can recreate the LinkButton controls somewhere before the Page_Load event is reached, like OnInit for example, everything should work fine.

对于简单的网页上面通常工作得很好,但有些情况下,在的OnInit 重新控制需要大量的开销,如存储柜或数组中的ViewState这样你可以跟踪那些需要回发后重新创建控件。在这种情况下,我建议采取一看 DynamicControlsPlaceHolder 由丹尼斯·鲍尔。这种控制能够坚持动态控制,而不需要任何addtional code,这是pretty的真棒的。

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. In these situations I would suggest taking a look at the DynamicControlsPlaceHolder by Denis Bauer. This control is capable of persisting dynamic controls without any addtional code required, which is pretty awesome.

下面有一个链接到最新版本: http://www.denisbauer.com/ASPNETControls/DynamicControlsPlaceholder.aspx

Here's a link to the latest version: http://www.denisbauer.com/ASPNETControls/DynamicControlsPlaceholder.aspx