问题描述
protectedvoidPage_Load(objectsender,EventArgse) { CheckBoxListchk=newCheckBoxList(); if(!IsPostBack) { chk.Items.Add("Hello"); } form1.Controls.Add(chk); } 在Page上扔个Button,以便可以PostBack。运行后Postback的结果,“Hello”item没被保留。 改为: protectedvoidPage_Load(objectsender,EventArgse) { CheckBoxListchk=newCheckBoxList(); form1.Controls.Add(chk); if(!IsPostBack) { chk.Items.Add("Hello"); } } 或者: protectedvoidPage_Load(objectsender,EventArgse) { CheckBoxListchk=newCheckBoxList(); (chk.ItemsasIStateManager).TrackViewState(); if(!IsPostBack) { chk.Items.Add("Hello"); } form1.Controls.Add(chk); }为什么改写后的第一种写法就可以保持状态了?
解决方案
解决方案二:
没人?有没有人来
解决方案三:
因为这种ASP.NET本身是无状态的,每次请求时服务器根本不知道客户端上次是怎么样子的,动态添加的必须在Page_Load事件里面每次都要执行
解决方案四:
然后ASP.NET会根据ViewState进行各种数据恢复
解决方案五:
引用2楼starfd的回复:
因为这种ASP.NET本身是无状态的,每次请求时服务器根本不知道客户端上次是怎么样子的,动态添加的必须在Page_Load事件里面每次都要执行
这个我知道,但是两种方法就在一个form1.Controls.Add(chk)这句话放的位置的问题,为什么放在ispostback的后面就不行,我在 CheckBoxListchk=newCheckBoxList(); form1.Controls.Add(chk);两句话里面加了一句stringa=“aa”;貌似也是可以保持状态的
解决方案六:
asp.net要回填ViewState状态数据,就需要在控件树同一个位置找到ID相同的控件,然后才能填入ViewState,并且准备在Load结束之后触发相关xxxxChanged事件。如果找不到控件,那么就不填入,自然随后也就不会触发事件。这是asp.net的原理,没什么好奇怪的。你在vs的设计器上拖入到设计页面的控件,被自动生成的代码在页面的Init阶段写入了类似你的第一段那样的代码。因为它们不是动态加入的,不需要判断其它的Viewstate、Coolie、QueryString等等,因此可以在Init阶段加入。而你写的,通常需要判断各种参数,因此不能在页面对象的Init时动态产生,而应该在Page_Load过程中才动态产生。asp.net对于会在你使用Controls.Add新的子控件的时候,将页面回发得到的ViewState、PostData数据回填到你动态产生的控件内,这样你的动态产生的chk在Load结束之后,不但有了动态变化的属性值,而且会随后自动触发有关的xxxxChanged之类的事件。基本上,现在的asp.net程序员只学asp.net必备知识的20%甚至更少,而各种社会培训班只教asp.net组件设计的原理知识的10%都不到。因此我认为asp.net从生态和教育角度看其实已经“完了”,不会有什么发展了,它的复杂的一整套机制其实90%以上都被人忘记了。为了以后少发生类似的尴尬,可以考虑回避这些问题,绝不用asp.net进行UI处理。一切都用前端开发来完成!
解决方案七:
引用5楼sp1234的回复:
asp.net要回填ViewState状态数据,就需要在控件树同一个位置找到ID相同的控件,然后才能填入ViewState,并且准备在Load结束之后触发相关xxxxChanged事件。如果找不到控件,那么就不填入,自然随后也就不会触发事件。这是asp.net的原理,没什么好奇怪的。你在vs的设计器上拖入到设计页面的控件,被自动生成的代码在页面的Init阶段写入了类似你的第一段那样的代码。因为它们不是动态加入的,不需要判断其它的Viewstate、Coolie、QueryString等等,因此可以在Init阶段加入。而你写的,通常需要判断各种参数,因此不能在页面对象的Init时动态产生,而应该在Page_Load过程中才动态产生。asp.net对于会在你使用Controls.Add新的子控件的时候,将页面回发得到的ViewState、PostData数据回填到你动态产生的控件内,这样你的动态产生的chk在Load结束之后,不但有了动态变化的属性值,而且会随后自动触发有关的xxxxChanged之类的事件。基本上,现在的asp.net程序员只学asp.net必备知识的20%甚至更少,而各种社会培训班只教asp.net组件设计的原理知识的10%都不到。因此我认为asp.net从生态和教育角度看其实已经“完了”,不会有什么发展了,它的复杂的一整套机制其实90%以上都被人忘记了。为了以后少发生类似的尴尬,可以考虑回避这些问题,绝不用asp.net进行UI处理。一切都用前端开发来完成!
请问“asp.net对于会在你使用Controls.Add新的子控件的时候,将页面回发得到的ViewState、PostData数据回填到你动态产生的控件内”这句话,第一种写法不是也调用了controls.Add添加新的子控件,这样的话通过在pageload里面也应该是能通过id找到控件,把ViewState,数据回填到控件里面去的?为什么没有添进去。还有这个例子是在看TrackViewState()与视图状态保存一个作者举例出来的,但是确实是看不懂
解决方案八:
这种比较高端了别在Page_Load事件里写,要在它之前的事件写,比如Page_Init,或者比这个事件更早的页面事件多年之前我看书上老外是那样写的,我也没理解
解决方案九:
我今天找到了下,原来是第一种写法是ViewState在首次页面加载的时候,没有把chk的项的值加到ViewState里面去,第二种方法写的话,在saveviewstate的方法的时候就加进去了,如图
解决方案十:
突然理解了,原来是第一种方法没用是因为,在声明一个checkbox的时候,在pageload里面加了checkbox的项,但是没有调用Controls.Add方法,所以这时候,没有调用TrackViewState()这个方法,所以就没有把chk标记为Dirty,所以在第一次请求的时候对chk的任何的更改都不会保存到ViewState上,所以在saveviewstate是,是没有把chk的项的值存储到viewstate里面,这也是导致为什么第一次加载页面的时候viewstate里面没有值的原因,当然在回发的时候,在pageload的时候创建chk的时候,虽然调用了Controls.Add但是由于ViewState里面没有前面添加的值,所以导致chk的值没有还原。不知道我理解的对不对,请大家指正下