to lostinetdotcom(思考=储存+选择+变异) “Value是通过客户端的<input type=hidden>来保持的。而客户端数据要在Load后才加载.” 这句话有问题,你可以自己做个试验,很简单做一个页面,在上面放上一个HtmlInputHidden,你可以设计时就给HtmlInputHidden一个值,也可以通过一个按钮点击事件给值,然后在Page_Load中设个断点来看,不管你怎么PostBack,HtmlInputHidden值都是维持的。
to lostinetdotcom(思考=储存+选择+变异) 我是试过的,我建议你去试一下,不要想当然
to lostinetdotcom(思考=储存+选择+变异) 你按照我上面说的这个简单的例子去试一下,ok?很简单做一个页面,在上面放上一个HtmlInputHidden,你可以设计时就给HtmlInputHidden一个值,也可以通过一个按钮点击事件给值,然后在Page_Load中设个断点来看,不管你怎么PostBack,HtmlInputHidden值都是维持的。
to lostinetdotcom(思考=储存+选择+变异) 问题是,我用一般的aspx页面测试,页面上的HtmlInputHidden值在Page_Load事件发生时就已经恢复,可是在用户控件ascx中的控件的HtmlInputHidden的值在用户控件的Page_Load事件就没有恢复(在程序中用代码载入的用户控件,直接在设计时拖到页面上的用户控件就没有次问题),奇怪不?
{
/// <summary>
/// 存放隐藏文本的TextBox
/// </summary>
private TextBox m_HideText=null;
/// <summary>
/// 隐藏文本
/// </summary>
[Bindable(true), Category("扩展属性"), Description("隐藏文本")]
public string HideText
{
get
{
this.EnsureChildControls();
return this.m_HideText.Text;
}
set
{
this.EnsureChildControls();
this.m_HideText.Text=value;
}
}
/// <summary>
/// 生成子控件
/// </summary>
protected override void CreateChildControls()
{
this.m_HideText=new TextBox();
this.m_HideText.ID=this.ID+"_HideText";
this.m_HideText.Style.Remove("DISPLAY");
this.m_HideText.Style.Add("DISPLAY","none");
this.Controls.Add(this.m_HideText);
}
/// <summary>
/// 将此控件呈现给指定的输出参数。
/// </summary>
/// <param name="output"> 要写出到的 HTML 编写器 </param>
protected override void Render(HtmlTextWriter output)
{
output.AddStyleAttribute("LEFT",this.Style["LEFT"]);
output.AddStyleAttribute("TOP",this.Style["TOP"]);
output.AddStyleAttribute("POSITION",this.Style["POSITION"]); this.Style.Remove("LEFT");
this.Style.Remove("TOP");
this.Style.Remove("POSITION"); output.RenderBeginTag(HtmlTextWriterTag.Div);
base.Render(output);
this.RenderChildren(output);
output.RenderEndTag();
} }
}
那么它的Value是不会自动保持的。
他的Value恢复的时候,是在ProcessPostData时做的。
而这个方法是在Load之后,RaiseChangedEvents和RaisePostBackEvent之前才做的
-------------------------------------
不要依赖Page.Load事件。
这个我有疑问,在我上面的测试中,HtmlInputHidden的Value在用户控件的Pageload中还没有被载入,可是在用户控件的PreRender事件的时候就被载入了,可见HtmlInputHidden的Value是被自动保持了,只是载入在Pageload的时候还没有发生。还有,你说的"ProcessPostData",在用户控件中没有这个事件或方法,不知道你说的是“LoadPostData ”还是“RaisePostDataChangedEvent”或者“RaisePostBackEvent”方法,我看msdn上的说明,LoadPostData 方法是用来出来PostBack数据的,在这个方法中各个实现了IPostBackDataHandler接口的控件会读取PostBack数据,并跟原先的值比较,判断是否有改变,若是有改变会返回一个true值,并将新值替换原值(请参看msdn中相关说明:ms-help://MS.VSCC/MS.MSDNVS.2052/cpguide/html/cpconcontrolexecutionlifecycle.htm)。LoadPostData 方法之后才是Page_Load事件,所以我觉得在Page_Load事件之前HtmlInputHidden的Value就应该恢复了,可是实际又不是这样,疑惑!
它在Load后调用。调用的是((IPostBackDataHandler)HtmlInputHidden).LoadPostData
在这个时候HtmlInputHidden的值才恢复.你在WebUserControl3 关联一下HtmlInputHidden的ServerChange一下不就成了。~~~
Value是通过客户端的<input type=hidden>来保持的。.
而客户端数据要在Load后才加载.
处理传入窗体数据,并相应地更新属性,这里就将PostBack的新值更新到相应控件了,并将PostBack的新值跟原先的值比较,判断是否有改变,若是有改变会返回一个true值,引发更改通知。
2、加载(Load 事件 ):
这个就不多说了,大家没有疑义
3、发送回发更改通知(RaisePostDataChangedEvent 方法 ):
根据第一步返回的值,引发更改事件。从上过程可以看出,LoadPostData是在Page_Load之前发生的,HtmlInputHidden的值才恢复在Page_Load之前就应改恢复了。
这句话有问题,你可以自己做个试验,很简单做一个页面,在上面放上一个HtmlInputHidden,你可以设计时就给HtmlInputHidden一个值,也可以通过一个按钮点击事件给值,然后在Page_Load中设个断点来看,不管你怎么PostBack,HtmlInputHidden值都是维持的。
ms-help://MS.VSCC/MS.MSDNVS.2052/cpguide/html/cpconcontrolexecutionlifecycle.htm一个页面的生命周期中的事件顺序(跟我们所说有关的事件顺序)如下:1、处理回发数据(LoadPostData 方法 ):
处理传入窗体数据,并相应地更新属性,这里就将PostBack的新值更新到相应控件了,并将PostBack的新值跟原先的值比较,判断是否有改变,若是有改变会返回一个true值,引发更改通知。
2、加载(Load 事件 ):
这个就不多说了,大家没有疑义
3、发送回发更改通知(RaisePostDataChangedEvent 方法 ):
根据第一步返回的值,引发更改事件。
我不和你争了。ms-help://MS.VSCC/MS.MSDNVS.2052/cpguide/html/cpconcontrolexecutionlifecycle.htm
我看过了。他是dotnet1.0版本的文档.在dotnet1.1上顺序已经改了。如果你自己不详细,自己用ildasm把两个版本的System.Web.dll打开来,
看System.Web.UI.Page::ProcessRequestMain好了。
我后来又看了一下。
的确我这里有错.
也终于明白了原因了。实际上.调用顺序是:
ProcessPostData
LoadRecursive
ProcessPostData也就是说,在Load前调用一次.在Load后继续调用一次.你那种情况,就是第一次ProcessPostData没有恢复Value所产生的.
而第二次ProcessPostData把Value恢复了。
就是第一次ProcessPostData恢复不成功.
而第二次却成功了。作成这个是因为:
private void Page_Load(object sender, System.EventArgs e)
{
WebUserControl3 myControl = (WebUserControl3)(Page.LoadControl("WebUserControl3.ascx"));
myControl.ID = "UserControl1";
PlaceHolder1.Controls.Add(myControl);
}
它是在Page.Load后才把WebUserControl3放上去的。
也就是说,第一次ProcessPostData时,WebUserControl3根本就没有建立.
就是第一次ProcessPostData恢复不成功.
而第二次却成功了。作成这个是因为:
private void Page_Load(object sender, System.EventArgs e)
{
WebUserControl3 myControl = (WebUserControl3)(Page.LoadControl("WebUserControl3.ascx"));
myControl.ID = "UserControl1";
PlaceHolder1.Controls.Add(myControl);
}
它是在Page.Load后才把WebUserControl3放上去的。
也就是说,第一次ProcessPostData时,WebUserControl3根本就没有建立.
WebForm1_Init <br>
Page_Load <br>
WebUserControl1_Init <br>
WebUserControl1_Load <br>
WebForm1_PreRender <br>
WebUserControl1_PreRender <br>
WebUserControl1_Unload <br>
WebForm1_Unload <br>在Page.Load后才把WebUserControl3放上去的,这个没错,WebUserControl3放上去之后就会开始WebUserControl3自己的生命周期的事件过程,在页面的Page_Load 后,会自此执行用户控件的Init和Load过程,而用户控件的自己的LoadPostData过程就在用户控件自己的Load事件之前的,就是说用户控件的PostData应该在用户控件的Page_Load事件之前完成的。
然后跟踪以下LoadPostData在什么时候运行不就知道了。(在WebUserControl1_Load之后)
http://expert.csdn.net/Expert/topic/1999/1999950.xml?temp=.8676111
其次,问题是你的回答并没有解决我的问题,没有通过试验,想当然的以为自己就是正确的,所以我请你自己动手按照我的描述做一下试验,试验的步骤看下面这个帖子会更清楚:http://expert.csdn.net/Expert/topic/1999/1999950.xml?temp=.8676111如果,你认为你是正确的,我老是跟你胡搅蛮缠的话,这个试验就不用做了,要是有兴趣的话,我想做一下也无妨。