ASP.NET-将事件处理程序添加到RenderContent调用中的Repeater内部的LinkBut​​ton中

时间:2020-03-06 14:37:02  来源:igfitidea点击:

我有一个Sharepoint WebPart,它加载了一个自定义的用户控件。用户控件包含一个Repeater,后者又包含几个LinkBut​​ton。

在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。