【问题标题】:FindControl in Custom ITemplate自定义 ITemplate 中的 FindControl
【发布时间】:2012-06-02 22:37:19
【问题描述】:

我有一个使用简单 ITemplate 的自定义 UserControl:

<asp:Panel runat="server" ID="pnlExpander" CssClass="expander">
    <asp:HyperLink runat="server" ID="lnkExpand" Text="More Options" NavigateUrl="#" CssClass="lnkExpand"/>
    <asp:Panel runat="server" ID="pnlContent" CssClass="expanderContent" style="display: none">
        <asp:PlaceHolder runat="server" ID="plcContent"/>
    </asp:Panel>
</asp:Panel>

模板使用两个简单的属性呈现:

public class Expander {
    private ITemplate _contentTemplate;
        public ITemplate ContentTemplate {
            get { return _contentTemplate; }
            set { _contentTemplate = value; }
    }
    protected override void OnPreRender(EventArgs e) {
            if (ContentTemplate != null) {
                ContentTemplate.InstantiateIn(plcContent);
            }
    }

一切都正确显示,但我无法在模板中使用 FindControl。我从 VS intellisense 获得了对我的组合框的引用,但是当我实际加载页面时,它是 null 的编译错误。

要在模板中找到组合框,我正在使用:

var cboFilterCriticality = AspNetUtils.FindControlRecursive(optionsExpander,"cboFilterCriticality") as DropDownList;

实际的模板在页面上是这样的:

<l49:Expander runat="server" ID="optionsExpander">
    <ContentTemplate>
        ... other controls
            <asp:DropDownList ID="cboFilterCriticality" runat="server" ValidationGroup="filterGrid" DataTextField="Key" DataValueField="Value" />
    </ContentTemplate>
</l49:Expander>

【问题讨论】:

  • 好问题。似乎它应该工作,但我遇到了同样的问题。如果我查看监视窗口中的控件集合,我可以看到控件。你总是可以覆盖 FindControl 方法。
  • FindControlRecursive 就是这样做的,递归地遍历树来寻找我的控制,但无济于事。

标签: c# asp.net .net templates itemplate


【解决方案1】:

我通过更改使用 ITemplate 的 UserControl 解决了这个问题。出于某种原因,它在OnPreRender 中调用了InstantiateIn,这显然为时已晚,无法在页面中呈现任何可供Page_Load 拾取的内容 - 请参阅Page LifeCycle and UserControls (half way down)。我在 UserControl 中将InstantiateIn 移动到OnInit,问题自行解决了。

【讨论】:

    【解决方案2】:

    Asp.net 的 WebForm 页面:

    <asp:Panel runat="server" ID="pnlExpander" CssClass="expander">
        <asp:HyperLink runat="server" ID="lnkExpand" Text="More Options" NavigateUrl="#" CssClass="lnkExpand"/>
        <asp:Panel runat="server" ID="pnlContent" CssClass="expanderContent" style="display: none">
            <asp:PlaceHolder runat="server" ID="plcContent"/>
        </asp:Panel>
    </asp:Panel>
    

    定义 Expander 类如下:

    public class Expander { 
        public ITemplate ContentTemplate {get ;set;}
        public HtmlGenericControl ContentTemplateContainer{get;set;}
        protected override void OnInit(EventArgs e) {
            this.ContentTemplateContainer = new HtmlGenericControl("div");
            if (ContentTemplate != null) {
                ContentTemplate.InstantiateIn(container);
            }
            plcContent.Controls.Add(container);
    
        }
    }
    

    在页面的 OnInit 中:

    public override void OnInit(EventArgs e){
        base.OnInit(e);
        ViewState["ContentTemplateContainerID"] =  ContentTemplateContainer.ClientID;
    }
    

    最后在 Javascript 中:

    var containerID = ViewState("ContentTemplateContainerID");
    var elID = $get(containerID)[0].id;
    var expander = $find(elID);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-19
      • 2021-05-04
      • 2011-01-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多