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
事件,但这根本不起作用。然后我设置了CommandArgument
和CommandName
,但这似乎没有奏效。我想Command
事件可能需要设置,但还是没有运气。我应该注意到,当单击链接时,将调用 searchresultcontrol . asx .cs中的Repeater1_ItemCreated
。但是由于没有数据在e.Item.DataItem
是空的,我失去了结果。
在关于同一问题的一个问题中,有人建议添加OnItemCommand
,但即使这样也没有被调用。
我也读过一个ASP的Stumper。. NET问题与ASP的难题。NET问题:解决了!,但无济于事。
我可能做错了什么?所有正确的事件连接似乎都在那里,我正在检查IsPostBack
而不是再次做DataBind()
。 blaaargharaggh
帮助总是很感激的。
我相信你会遇到这个问题,因为LinkButton
控件在页面生命周期中重新创建得太晚了。您必须记住,当页面被发回时,控件在技术上已经不存在了,因此事件处理程序不能被触发。
如果您可以在到达Page_Load
事件之前重新创建LinkButton
控件,例如OnInit
,那么一切都应该正常工作。
对于简单的页面,上面的方法通常工作得很好,但是有些情况下,在OnInit
期间重新创建控件需要很多开销,例如在ViewState中存储计数器或数组,以便您可以跟踪回发后需要重新创建的控件。在这些情况下,我建议你看看Denis Bauer的DynamicControlsPlaceHolder
。这个控件能够持久化动态控件,而不需要任何额外的代码,这是非常棒的。
这是最新版本的链接:
http://www.denisbauer.com/ASPNETControls/DynamicControlsPlaceholder.aspx
问题可能是你没有再做DataBind()
。
因为您是在动态地构建按钮,所以当页面返回时,按钮还没有创建,并且无法计算出应该触发哪个单击事件。
尝试去掉IsPostBack
检查,这样每次页面加载时,您都要重新构建repeater
。