ASP.NET-将事件处理程序添加到RenderContent调用中的Repeater内部的LinkButton中
我有一个Sharepoint WebPart,它加载了一个自定义的用户控件。用户控件包含一个Repeater,后者又包含几个LinkButton。
在Webpart的RenderContent调用中,我有一些代码来添加事件处理程序:
ArrayList nextPages = new ArrayList(); //populate nextPages .... AfterPageRepeater.DataSource = nextPages; AfterPageRepeater.DataBind(); foreach (Control oRepeaterControl in AfterPageRepeater.Controls) { if (oRepeaterControl is RepeaterItem) { if (oRepeaterControl.HasControls()) { foreach (Control oControl in oRepeaterControl.Controls) { if (oControl is LinkButton) { ((LinkButton)oControl).Click += new EventHandler(PageNavigateButton_Click); } } } } }
但是,永远不会调用函数PageNavigateButton_Click。我可以看到它被添加为调试器中的事件处理程序。
有任何想法吗?我很困惑如何做到这一点。
解决方案
我们需要确保在事件触发前将链接按钮重新添加到控件树和/或者将事件重新连接到控件。
文章@ 4guysfromrolla
我从未做过SharePoint WebPart,所以我不知道这是否适用。但是,如果这是一个普通的apsx页面,我想说的是,到渲染时,为时已晚。尝试在控件的Init或者PreInit事件中添加事件处理程序。
编辑:等等,我认为Dilli-O可能是正确的。请参阅http://www.ondotnet.com/pub/a/dotnet/2003/03/03/repeater.html末尾的"将按钮控件添加到中继器"部分。它在VB.NET中,但是我们可以轻松地在C#中执行相同的操作。
我们是否在遍历过程中尝试将CommandName和CommandArgument属性分配给每个按钮? Repeater控件支持ItemCommand事件,该事件将在命中具有CommandName属性的控件时引发。
从那里可以很容易地进行处理,因为CommandName和CommandArgument值被传递到事件中并且易于访问。
到调用RenderContent()时,框架已调用所有已注册的事件处理程序。我们需要在较早的方法中添加事件处理程序,例如OnLoad():
protected override void OnLoad(EventArge e) { base.OnLoad(e); EnsureChildControls(); var linkButtons = from c in AfterPageRepeater.Controls .OfType<RepeaterItem>() where c.HasControls() select c into ris from lb in ris.OfType<LinkButton>() select lb; foreach(var linkButton in linkButtons) { linkButton.Click += PageNavigateButton_Click } }
正如其他人指出的那样,我们在页面生命周期中添加事件处理程序太晚了。对于SharePoint WebParts,通常需要重写类的OnInit / CreateChildControls方法来处理活动。
我们需要Webpart来实现INamingContainer标记接口,框架使用它来允许回发返回到正确的控件...
而且,Webpart中的控件都需要具有ID。