【问题标题】:ASP.NET OnClick not firing in Repeater.ItemTemplate that has a custom controlASP.NET OnClick 未在具有自定义控件的 Repeater.ItemTemplate 中触发
【发布时间】:2011-09-29 21:39:09
【问题描述】:

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

我有一个搜索结果页面,其中有一个自定义控件,该控件具有 Repeater。转发器中的ItemTemplatePlaceHolder,因此我可以以特定格式构造项目;更具体地说,我有一串以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.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 question得到这个想法)

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);
        }
    }
}

这是 SearchResultItem

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

最初我尝试设置Click 事件,但这根本不起作用。然后我设置了CommandArgumentCommandName,但这似乎没有奏效。我认为可能需要设置 Command 事件,但同样没有运气。我应该注意,当点击链接时,SearchResultControl.ascx.cs 中的Repeater1_ItemCreated 会被调用。但由于e.Item.DataItem 中没有数据,所以我丢失了结果。

在关于同一问题的questions 之一中,建议添加OnItemCommand,但即使这样也不会被调用。

我还阅读了A Stumper of an ASP.NET QuestionA Stumper of an ASP.NET Question: SOLVED!,但无济于事。

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

非常感谢您的帮助。

【问题讨论】:

标签: c# .net asp.net repeater


【解决方案1】:

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

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

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

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

【讨论】:

  • 哦...有道理。我按照您的建议将 DataSource 的设置移动到 OnInit 中,这似乎可行。谢谢您的帮助。我很感激。
  • 很高兴你能成功。您也应该在某个时候查看DynamicControlsPlaceHolder!这是救命稻草。
【解决方案2】:

问题可能是您不再使用DataBind()

因为您正在动态构建按钮,所以当页面回发时,尚未创建按钮并且无法确定应该触发哪个点击事件。

尝试摆脱IsPostBack 检查,这样每次页面加载时,您都会重新构建repeater

【讨论】:

  • 我不认为这是问题所在。
猜你喜欢
  • 1970-01-01
  • 2018-05-31
  • 1970-01-01
  • 1970-01-01
  • 2013-04-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-12
相关资源
最近更新 更多