代码之家  ›  专栏  ›  技术社区  ›  Bob Fincheimer

带有子级的ASP.NET自定义/用户控件

  •  10
  • Bob Fincheimer  · 技术社区  · 14 年前

    例如,我希望控件具有以下标记:

    <div runat="server" id="div">
        <label runat="server" id="label"></label>
        <div class="field">
            <!-- INSERT CHILDREN HERE -->
        </div>
    </div>
    

    当我想在页面上使用它时,我只是:

    <ctr:MyUserControl runat="server" ID="myControl">
        <span>This is a child</span>
        <div runat="server" id="myChild">And another <b>child</b>
    </ctr:MyUserControl>
    

    编辑------

    它可以是一个模板控件,只要它允许我引用页面上的子控件。

    3 回复  |  直到 14 年前
        1
  •  7
  •   Community CDub    7 年前

    不久前我也问过类似的问题。看到了吗 here .

    我相信您将不得不使用ITemplate作为内部财产:

    [PersistenceMode(PersistenceMode.InnerProperty)]
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
    [TemplateInstance(TemplateInstance.Single)]
    public ITemplate Content
    {
        get
        {
            return _content;
        }
        set
        {
            _content = value;
        }
    }
    private ITemplate _content;
    

    然后重写控件的CreateChildControls方法:

    protected override void CreateChildControls()
    {
       if (this.Content != null)
       {
          this.Controls.Clear();
          this.Content.InstantiateIn(this);
       }
       base.CreateChildControls();
    }
    

    ITemplate 您可以将它与现有的标记相结合,并在 Content

        2
  •  0
  •   Roman    14 年前

    另一种方法是查看面板控件的源代码(例如使用Reflector)。看起来它只是覆盖了 RenderBeginTag RenderEndTag 方法(其中包括添加属性等),并将其余的呈现推迟到 WebControl 班级。

        3
  •  0
  •   tkestowicz    11 年前

    我知道答案有点老,但我有一个问题,这里没有提到。

    我已经尝试过这个解决方案,如果内容是默认的aspx控件或普通的html标记,它会很好地工作。当我把一个自定义的web控件放在里面时,我遇到了一个问题 NullReferenceException OnInit 方法(在自定义web控件代码后面)调用 EnsureChildControls() 但是子控件仍然没有实例化。你有什么想法或建议吗?

            this._pnlButtons.Controls.Add( _lbtnOkHidden );
            this._pnlButtons.Controls.Add( _lgbtnOk );
    
            this._pnlPopup.Controls.Add( _pnlHeader );
            this._pnlPopup.Controls.Add( _pnlContent );
            this._pnlPopup.Controls.Add( _pnlButtons );
    
            if ( this.Content != null )
                this.Content.InstantiateIn( _pnlContent );
    
            this._updatePanel.ContentTemplateContainer.Controls.Add( _lbShowPopup );
            this._updatePanel.ContentTemplateContainer.Controls.Add( _lbtnShowPopupHidden );
            this._updatePanel.ContentTemplateContainer.Controls.Add( _pnlPopup );
            this._updatePanel.ContentTemplateContainer.Controls.Add( _modalExtender );
    
            this.Controls.Add(_updatePanel);
            base.CreateChildControls();