我在使用LoadControl( type, Params )时遇到了问题。让我解释一下..。
我有一个超级简单的用户控件(ascx)
<%@ Control Language="C#" AutoEventWireup="True" Inherits="ErrorDisplay" Codebehind="ErrorDisplay.ascx.cs" EnableViewState="false" %>
<asp:Label runat="server" ID="lblTitle" />
<asp:Label runat="server" ID="lblDescription" />后面有代码( c# ):
public partial class ErrorDisplay : System.Web.UI.UserControl
{
private Message _ErrorMessage;
public ErrorDisplay()
{
}
public ErrorDisplay(Message ErrorMessage)
{
_ErrorMessage = ErrorMessage;
}
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
if (_ErrorMessage != null)
{
lblTitle.Text = _ErrorMessage.Message;
lblDescription.Text = _ErrorMessage.Description;
}
}
}在我的web应用程序的其他地方,我使用以下代码向页面添加用户控件的实例:
divValidationIssues.Controls.Add(LoadControl(typeof(ErrorDisplay), new object[] { MessageDetails })); 我使用重载版本的LoadControl,因为我希望将消息参数传递给构造函数。所有这些似乎都正常。
但是,当OnPreRender()在ErrorDisplay用户控件上触发时,lblTitle和lblDescription变量都是null,尽管它们有一个等价的标记。消息变量已正确填充。
有人能解释一下为什么会发生这种事吗?
谢谢
编辑:
为了清楚起见,我还要补充一下,通过编程将用户控件添加到页面的代码是响应按下按钮运行的,因此“宿主页”已经通过Init、Page_Load进行了改进,现在正在处理事件处理程序。
我不能在较早的asp生命周期阶段添加用户控件,因为它们是为了响应按钮单击事件而创建的。
发布于 2008-10-27 18:41:45
我也尝试过以下代码--这会产生相同的结果(即lblTitle和lblDescription都为null)
protected void Page_Load(object sender, EventArgs e)
{
if (_ErrorMessage != null)
{
lblTitle.Text = _ErrorMessage.Message;
lblDescription.Text = _ErrorMessage.Description;
}
}我的理解是,LoadControl函数将它正在加载的控件带到包含它的页面的当前“状态”。因此,Init、Page_Load等都是作为LoadControl调用的一部分运行的。
有趣的是,这个(未回答的) asp.net论坛帖子展示了与我所经历的同样的问题。
MSDN论坛帖子
另外-来自MSDN:
当将控件加载到容器控件中时,容器会引发添加的控件的所有事件,直到它赶上当前事件为止。但是,添加的控件没有赶上回发数据处理。要使添加的控件参与回发数据处理(包括验证),必须在Init事件中而不是在Load事件中添加该控件。
因此,LoadControl不应该正确地削弱控件吗?
编辑:
好吧,我在这里回答我自己的问题..。
我找到了一个我链接到上面这里的论坛帖子的应答版本
本质上,答案是LoadControl( type, params )不能推断“页面infront”ascx来解析,因此它不会费心地将任何控件初始化。当您使用LoadControl( "ascx path" )版本时,它会被赋予页面infront,从而完成所有的解析和限制。
因此,总之,我需要修改代码,它正在弱化控件,并将其分割成单独的部分。也就是说。
Control ErrorCntrl = LoadControl("ErrorDisplay.ascx");
ErrorCntrl.ID = SomeID;
(ErrorCntrl as ErrorDisplay).SetErrorMessage = MessageDetail;
divErrorContainer.Controls.Add(ErrorCntrl);应该能正常工作..。它不像我以前的尝试那么整洁,但至少它会起作用。
我仍然对改善上述情况的建议持开放态度。
干杯
发布于 2008-10-27 18:17:18
同意米切尔的观点,您应该能够在控制代码本身中放置一个page_load,这将在控件完全可用之后触发。
发布于 2008-10-27 21:49:41
在运行构造函数并将控件添加到页面之后,总是会添加自己的load事件并调用它,但是它与您的控件并没有太大的不同,尽管出于样式的原因,我可能会选择它。
很高兴你找到了你的问题的答案!
https://stackoverflow.com/questions/240850
复制相似问题