【问题标题】:asp:dropdownlist is null on page_loadasp:dropdownlist 在 page_load 上为空
【发布时间】:2012-03-08 15:39:18
【问题描述】:

我有一个 ascx 控件;

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="LanguageSelect.ascx.cs" Inherits="MyNamespace.LanguageSelect" %>

后面有代码:

protected void Page_Load(object sender, EventArgs e)
        {
            Languages = GetSiteLanguagesService();
            if (Languages.Count > 1)
            {

                //null reference exception here!! languageDropdown is null!
                LanguageDropdown.Visible = true;
                LanguageDropdown.DataTextField = "DisplayName";
                LanguageDropdown.DataValueField = "LangUrl";
                LanguageDropdown.DataSource = Languages ;
                LanguageDropdown.DataBind();
            }
        }

在另一个控件中:

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="SomePage.ascx.cs" Inherits="myNamespace.SomePage" %>
<div id="main" role="main"> 
    <myTag:LanguageSelect id="langSelect" runat="server" />
    <div class="section columns"> 
        <div class="main-column"> ....

使用调试器,我点击了LanguageSelect 的page_load,但下拉列表为空!如果我在标记中添加下拉控件,我认为它应该始终存在,在这种情况下,它的行为就像它只是一个动态控件..

现在,控件 SomePage 正在 html 中呈现,但 myTag 中的这个控件根本没有被呈现,如果我将下拉列表包装在 div 中也没关系,div 不会被呈现要么!!

如果我将断点放在SomePage page_load 中,lan​​gSelect 控件将在那里(不为空),但它本身有一个空 LanguageDropdown

【问题讨论】:

  • 您的 UserControl 是否动态添加到页面中?我问是因为人们有时会忘记他们必须通过Page.LoadControl 创建它的实例而不是使用构造函数。旁注:使用页面事件来隐式初始化 UserControl 几乎总是一个坏主意。相反,控制器(通常是页面)应该直接初始化控件(例如,通过调用方法 BindDataInit)。否则可能会导致生命周期问题和不可预测的行为。
  • @TimSchmelter 不,它不是动态添加的,嗯...如果控件作为标记添加,这意味着不是动态的吗?

标签: c# asp.net visual-studio-2010 .net-4.0 drop-down-menu


【解决方案1】:
  1. 您的 UserControl 是否动态添加到页面中?我问是因为人们有时会忘记他们必须通过 Page.LoadControl 创建它的实例,而不是使用构造函数。
  2. 您是否在页面中注册了 UserControl?

例如:

<%@ Register TagPrefix="uc1" TagName="Lang" Src="controls/LanguageSelect.ascx" %>

旁注:使用页面事件来隐式初始化UserControl 几乎总是一个坏主意。相反,控制器(通常是页面)应该直接初始化控件(通过调用像BindDataInit 这样的方法)。 否则可能会导致生命周期问题或严重错误。

【讨论】:

  • 好吧,用户控件本身就是一个站点核心子布局
  • 麻烦的是,控件是否是动态的(并且不是)甚至都没有关系,因为如果我分配 LanguageDropdown 并尝试将其添加到页面中,我会收到错误因为我无法在加载、初始化、渲染事件上修改页面
【解决方案2】:

尝试删除自动生成的“.ascx.designer.cs”文件并重新生成。为此,请按照以下步骤操作:

  • 删除.ascx.*.designer.cs
  • 右键单击 ascx 文件并选择“转换为 Web 应用程序”

现在重新创建了 Designer.cs 文件。看看现在能不能行。

【讨论】:

  • 没用,无论如何,designer.cs 似乎与标记同步
【解决方案3】:

它可能会尝试将您的 UserControl (.ascx) 加载为 CustomControl(没有 .ascx)。检查您的页面和 web.config pages/controls 部分是否引用了 LanguageSelect 的命名空间而不是 .ascx 路径。

【讨论】:

    【解决方案4】:

    终于找到了问题所在;当控件嵌入到其他控件中时,ASP.NET 假定您将覆盖呈现(它不会自动呈现子控件)

    我不得不对 Page_Load 进行以下更改,基本上是分配控件:

    protected void Page_Load(object sender, EventArgs e)
            {
                Languages = GetSiteLanguagesService();
                if (Languages.Count > 1)
                {
    
                    LanguageDropdown = new DropDownList(); //allocate the control
                    LanguageDropdown.Visible = true;
                    LanguageDropdown.DataTextField = "DisplayName";
                    LanguageDropdown.DataValueField = "LangUrl";
                    LanguageDropdown.DataSource = Languages ;
                    LanguageDropdown.DataBind();
                }
            }
    

    然后,为 OnRender 处理程序添加一个覆盖:

    protected override void Render(HtmlTextWriter writer)
            {
                base.Render(writer);
                LanguageDropdown.RenderControl(writer);
            }
    

    在此之后,控件完美呈现!

    【讨论】:

    • 我认为您应该说“当控件继承自另一个控件时”而不是“当控件嵌入另一个控件时”。它们是完全不同的两件事。
    • @rperson 我不明白; LangSelect 不继承自 SomePage,它嵌入其中
    猜你喜欢
    • 1970-01-01
    • 2015-01-22
    • 2016-04-13
    • 1970-01-01
    • 2016-01-12
    • 2017-02-11
    • 1970-01-01
    • 1970-01-01
    • 2016-02-24
    相关资源
    最近更新 更多