Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/257.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Asp.NET自定义服务器控件事件处理程序在第二次回发时未触发_C#_Asp.net_Postback_Sitecore_Custom Server Controls - Fatal编程技术网

C# Asp.NET自定义服务器控件事件处理程序在第二次回发时未触发

C# Asp.NET自定义服务器控件事件处理程序在第二次回发时未触发,c#,asp.net,postback,sitecore,custom-server-controls,C#,Asp.net,Postback,Sitecore,Custom Server Controls,我正在Asp.NET(.NET 3.5)中开发一个自定义服务器控件,它继承CompositeControl类。在我的控件中,我重写了CreateChildControls()方法来生成html和Asp.NET服务器控件的混合。添加的一些Asp.NET控件是LinkButtons(每个控件都将其命令事件处理程序设置为我控件中的方法)。我发现,第一次单击其中一个LinkButton时,会触发回发,并正确地触发事件处理程序方法。在此事件处理程序中,显式调用CreateChildControls()方法

我正在Asp.NET(.NET 3.5)中开发一个自定义服务器控件,它继承CompositeControl类。在我的控件中,我重写了
CreateChildControls()
方法来生成html和Asp.NET服务器控件的混合。添加的一些Asp.NET控件是
LinkButton
s(每个控件都将其
命令
事件处理程序设置为我控件中的方法)。我发现,第一次单击其中一个LinkButton时,会触发回发,并正确地触发事件处理程序方法。在此事件处理程序中,显式调用CreateChildControls()方法来重新生成控件以响应回发。然后,我发现后续单击
LinkButton
s回发无法引发事件处理程序方法

我假设我在回发时处理控件重新生成的方式一定是错误的,但我不知道该怎么办-我知道在第一次回发时CreateChildControls()被调用了两次,这可能并不理想,但因为CreateChildControls是在引发任何事件之前调用的,我看不出有什么办法

我的控件类的简化版本如下所示:

public class SearchResults : CompositeControl
{
    private int PageIndex = 0;

    protected override void CreateChildControls()
    {
            //do stuff here e.g.
            LinkButton prevLink = new LinkButton();
            prevLink.Text = "< Prev";
            prevLink.CommandArgument = (PageIndex - 1).ToString();
            prevLink.Command += new CommandEventHandler(PagerLinkCommand);
            this.Controls.Add(prevLink);
    }

    protected void PagerLinkCommand(object sender, CommandEventArgs e)
    {
        PageIndex = int.Parse(e.CommandArgument.ToString());
        CreateChildControls();
    }
}
  <typesThatShouldNotBeExpanded>
    <type>System.Web.UI.WebControls.Repeater</type>
    <type>System.Web.UI.WebControls.DataList</type>
    <type>System.Web.UI.WebControls.GridView</type>
    <type>MyNamespace.MyCustomControl</type> <!-- This is the bit I added -->
  </typesThatShouldNotBeExpanded>
公共类搜索结果:CompositeControl
{
私有int-PageIndex=0;
受保护的覆盖无效CreateChildControls()
{
//在这里做事。
LinkButton prevLink=新建LinkButton();
prevLink.Text=“
编辑 这里的问题是由于控件在Sitecore站点中使用,而我忘记在web.config文件中使用
条目注册控件类型。此条目用于防止服务器控件的事件被Sitecore弄乱-这可能会导致标准服务器控件(如ListView、GridView和Repeater等)出现类似问题。My web.config的修改如下所示:

public class SearchResults : CompositeControl
{
    private int PageIndex = 0;

    protected override void CreateChildControls()
    {
            //do stuff here e.g.
            LinkButton prevLink = new LinkButton();
            prevLink.Text = "< Prev";
            prevLink.CommandArgument = (PageIndex - 1).ToString();
            prevLink.Command += new CommandEventHandler(PagerLinkCommand);
            this.Controls.Add(prevLink);
    }

    protected void PagerLinkCommand(object sender, CommandEventArgs e)
    {
        PageIndex = int.Parse(e.CommandArgument.ToString());
        CreateChildControls();
    }
}
  <typesThatShouldNotBeExpanded>
    <type>System.Web.UI.WebControls.Repeater</type>
    <type>System.Web.UI.WebControls.DataList</type>
    <type>System.Web.UI.WebControls.GridView</type>
    <type>MyNamespace.MyCustomControl</type> <!-- This is the bit I added -->
  </typesThatShouldNotBeExpanded>

System.Web.UI.WebControl.Repeater
System.Web.UI.WebControl.DataList
System.Web.UI.WebControl.GridView
MyNamespace.MyCustomControl

要获得正确的控件树,请覆盖Controls属性并调用EnsureChildControls,同时在PagerLink命令中调用EnsureChildControls而不是CreateChildControls

    /// <summary>
    /// Gets controls.
    /// </summary>
    public override ControlCollection Controls
    {
        get
        {
            EnsureChildControls();
            return base.Controls;
        }
    }

    /// <summary>
    /// Create child controls.
    /// </summary>
    protected override void CreateChildControls()
    {
        this.Controls.Clear();
        //do stuff here e.g.
        LinkButton prevLink = new LinkButton();
        prevLink.Text = "< Prev";
        prevLink.CommandArgument = (PageIndex - 1).ToString();
        prevLink.Command += new CommandEventHandler(PagerLinkCommand);
        this.Controls.Add(prevLink);
    }

    protected void PagerLinkCommand(object sender, CommandEventArgs e)
    {
      PageIndex = int.Parse(e.CommandArgument.ToString());
      EnsureChildControls();
    }        
//
///获取控件。
/// 
公共覆盖控件集合控件
{
得到
{
ensureChildControl();
返回基控件;
}
}
/// 
///创建子控件。
/// 
受保护的覆盖无效CreateChildControls()
{
this.Controls.Clear();
//在这里做事。
LinkButton prevLink=新建LinkButton();
prevLink.Text=“
根据我的经验,这种问题通常是由于没有为动态生成的控件分配ID造成的

LinkButton prevLink = new LinkButton();
prevLink.ID = "prevLink";

抱歉。。。这不是一个完整的答案,但调试建议太长,无法发表评论:

在浏览器中,为初始加载、回发加载和第二次回发保存页面的HTML副本。然后使用您喜欢的比较工具比较文件。消除明显的差异,如搜索结果等。这可以帮助您查明控件ID、缺少控件等的任何问题

成功动态创建控件的两个绝对关键是
1) 在页面生命周期的正确时间创建它们

2) 在回发时重新创建完全相同的控件层次结构(包括ID)

此行为的原因不在于服务器控件本身,而是与Sitecore相关。为了使Sitecore不干扰服务器控制回发,有必要在web.config文件的
类型下添加一个不应扩展的条目,如下所示

<typesThatShouldNotBeExpanded>
  <type>System.Web.UI.WebControls.Repeater</type>
  <type>System.Web.UI.WebControls.DataList</type>
  <type>System.Web.UI.WebControls.GridView</type>
  <type>MyNamespace.MyCustomControl</type> <!-- This is the bit I added -->
</typesThatShouldNotBeExpanded>

System.Web.UI.WebControl.Repeater
System.Web.UI.WebControl.DataList
System.Web.UI.WebControl.GridView
MyNamespace.MyCustomControl

基类应该为您调用CreateChildControls()-尝试删除它。不幸的是,这样做似乎不起作用。CreateChildControls()现在不会在PagerLinkCommand()之后被调用。不要忘记在CreateChildControls()中对base.CreateChildControls()的调用。您对CreateChildControls()方法中生成的所有控件都这样做了吗?特别是链接按钮嵌套的控件。我发现这篇文章很有帮助: