asp.net 动态创建TextBox控件及状态数据如何加载_实用技巧

接着上文Asp.net TextBox的TextChanged事件你真的清楚吗? 这里我们来说说状态数据时如何加载的。
虽然在Control中有调用状态转存的方法,但是这里有一个判断条件 if (_controlState >= ControlState.ViewStateLoaded) 一般的get请求这里的条件是不满足的。

复制代码 代码如下:

internal enum ControlState
{
Constructed,
FrameworkInitialized,
ChildrenInitialized,
Initialized,
ViewStateLoaded,
Loaded,
PreRendered
}

我们知道在page的ProcessRequest中this.ControlState = ControlState.FrameworkInitialized;ProcessRequestMain方法中在Init后有调用this.InitRecursive(null);在这个方法里面有这么一句_controlState = ControlState.Initialized;,在LoadAllState()方法中有这么一句 base.LoadViewStateRecursive(second.Second);,而LoadViewStateRecursive中又有_controlState = ControlState.ViewStateLoaded这句带代码,所以我们在Page_load中动态条件控件时, if (_controlState >= ControlState.ViewStateLoaded)条件成立,如图:

所以在运行this.form1.Controls.Add(txt);这句以前,txt的值为demo1,

如图

但是运行以后之就发生变化了:

当然这里的txt.Text值也是我上次post过来的旧值,新值是在控件的LoadPostData方法中重新绑定。在默认的LoadViewStateRecursive方法中有一个很重要的判断

复制代码 代码如下:

internal void LoadViewStateRecursive(object savedState) {
// nothing to do if we have no state
if (savedState == null || flags[disableViewState])
return;

。。。。。。。

_controlState = ControlState.ViewStateLoaded
}

大家看到我上面是一个CustTextBoxt : TextBox控件,如果我们直接添加TextBox控件的话,那么着这里的txt.Text一直都是demo1,可见控件动态添加的时候是否加载状态数据与状态数据的保存有关。而状态数据的保存主要就是SaveViewState完成的,这里我第一次post的时候SaveViewState返回数据:

所以第二次能取到上次post过来的数据。

其中与SaveViewState有关的方法主要有:

复制代码 代码如下:

public class TextBox : WebControl, IPostBackDataHandler, IEditableTextControl {
protected override object SaveViewState() {
if (SaveTextViewState == false) {
ViewState.SetItemDirty("Text", false);
}
return base.SaveViewState();
}
private bool SaveTextViewState {
get {
//

// Must be saved when
// 1. There is a registered event handler for SelectedIndexChanged
// 2. Control is not enabled or visible, because the browser's post data will not include this control
// 3. The instance is a derived instance, which might be overriding the OnTextChanged method

if (TextMode == TextBoxMode.Password) {
return false;
}

if ((Events[EventTextChanged] != null) ||
(IsEnabled == false) ||
(Visible == false) ||
(ReadOnly) ||
(this.GetType() != typeof(TextBox))) {
return true;
}

return false;
}
}

}
public class WebControl : Control, IAttributeAccessor {
protected override object SaveViewState() {
Pair myState = null;

// Save values cached out of view state
if (_webControlFlags[disabledDirty]) {
ViewState["Enabled"] = !flags[isWebControlDisabled];
}

if (ControlStyleCreated) {
// the style shares the StateBag of its owner WebControl
// call SaveViewState to let style participate in state management
ControlStyle.SaveViewState();
}

object baseState = base.SaveViewState();
object aState = null;
if (attrState != null) {
aState = attrState.SaveViewState();
}

if (baseState != null || aState != null) {
myState = new Pair(baseState, aState);
}
return myState;
}
}
public class Control : IComponent, IParserAccessor, IUrlResolutionService, IDataBindingsAccessor, IControlBuilderAccessor, IControlDesignerAccessor, IExpressionsAccessor {
protected virtual object SaveViewState() {
// Save values cached out of view state
if (flags[visibleDirty]) {
ViewState["Visible"] = !flags[invisible];
}
if (flags[validateRequestModeDirty]) {
ViewState["ValidateRequestMode"] = (int)ValidateRequestMode;
}
if (_viewState != null)
return _viewState.SaveViewState();

return null;
}
}
public sealed class StateBag : IStateManager, IDictionary {
internal object SaveViewState() {
ArrayList data = null;
if (bag.Count != 0) {
IDictionaryEnumerator e = bag.GetEnumerator();
while (e.MoveNext()) {
StateItem item = (StateItem)(e.Value);
if (item.IsDirty) {
if (data == null) {
data = new ArrayList();
}
#if OBJECTSTATEFORMATTER
data.Add(new IndexedString((string)e.Key));
#else
data.Add(e.Key);
#endif
data.Add(item.Value);
}
}
}

return data;
}
}

到这里我们知道保存状态信息主要是在StateBag 的SaveViewState方法中,这里有一个检查  if (item.IsDirty) ,在TextBox的SaveViewState方法中有一个判断

复制代码 代码如下:

if (SaveTextViewState == false) {
ViewState.SetItemDirty("Text", false);
}

与它的SaveTextViewState 属性有关。

那么我们可以总结一下:动态创建的控件默认是在被添加的时候加载器状态数据,如果是静态添加的数据那就是LoadAllState来处理状态数据的加载。状态数据的加载与控件的SaveViewState密切相关,如果该方法的返回值为null既没有状态信息,那也不需要加载什么状态信息了。

时间: 2024-08-01 16:07:45

asp.net 动态创建TextBox控件及状态数据如何加载_实用技巧的相关文章

ASP.NET中的Menu控件的应用及XmlDataSource的了解_实用技巧

以前一直以为菜单都是通过sitemap制作的,最近看到项目中的方法是使用XmlDataSource榜定的. Menusite.xlm文件: 复制代码 代码如下: <?xmlversion="1.0"encoding="utf-8"?> <Menusvalue=""> <TopMenuid="100"value=""ImageUrl="~/App_Themes/Publ

asp.net(C#)中给控件添加客户端js事件的方法_实用技巧

放在服务器端,也可以用ajax来实现,不刷页面.但我觉得有更直接更简单方法,用一个js事件是可以实现的. 但,DropDownList不偈Button等控件提供了一些像"OnClientClick"前台事件,只有服务端事件. 想到,所有C#页面代码,最终都是生成HTML,js事件也是最终运在浏览器中,以Html为基础的.服务端控件最终生成的HTML控件有什么js事件,我们应该就能在aspx中给它添加相应的事件. DropDownList 生成的Htm是元素<Select>是

.net控件dropdownlist动态绑定数据具体过程分解_实用技巧

一.在页面初始化时候将集合绑定到DropDownList 复制代码 代码如下: public void Page_Load(Object src.EventArgs e) { ArrayList arrValue = new ArrayList(); arrValue.add("kk"); arrValue.add("dd"); arrValue.add("aa"); arrValue.add("cc"); //将数组绑定到D

分析10个ASP.NET控件最有用的属性详解_实用技巧

1.ClientIDMode 渲染ASP.NET控件时会自动生成一个ID,当我们在客户端脚本中引用它们时,却会制造不少麻烦,虽然它是命名容器和ID的简单串联,但仍然无法预测生成的ID范围. ASP.NET 4.0使用ClientIDMode属性解决了这个问题,它允许你控制生成这些ID的方法,ClientIDMode有四个可选择的值:AutoID,Static,Predictable和Inherit.下面是这四个值的含义解释: AutoID – 和4.0以前的版本保持一致,自动生成ID. Stat

vs.net控件updatePanel实现无刷新的方法_实用技巧

页面部分 复制代码 代码如下: <asp:ScriptManager ID="ScriptManager1" runat="server">    </asp:ScriptManager>    <h2>        使用VS控件updatePanel实现无刷新    </h2>    <p>         <asp:UpdatePanel ID="UpdatePanel1"

web用户控件调用.aspx页面里的方法_实用技巧

现在把此web用户控件添加到一.aspx页面中.要实现单击用户控件中的button控件把搜索出来的结果数据绑定到.aspx页面的gridview控件上去,如何实现呢? 如果gridview控件是放在.ascx文件中的话,那我们直接把搜索出来的数据绑定到它上面就行了.但现在gridview是放在.aspx文件里,也就是说web用户控件要如何才能访问母页面的控件,把数据绑定到母页面的控件上去? 解决方法: 1.先在.aspx页面的后台文件.aspx.cs中添加一个绑定数据的方法,代码如下: 复制代码

ASP.NET 广告控件AdRotator的使用方法与实例_实用技巧

adRotator.aspx,在ASP.NET页面中创建一个AdRotator服务器控件,将广告XML文件连接到这个控件.使用以下服务器控件标记来完成 复制代码 代码如下: <asp:AdRotator ID="AdRotator1" runat="server" AdvertisementFile="~/XMLFile.xml" /> 生成广告的代码 复制代码 代码如下: adRotator.aspx.csusing System;

Asp.Net数据控件引用AspNetPager.dll分页实现代码_实用技巧

1.也许讲解有点初级,希望高手不要"喷"我,因为我知道并不是每一个人都是高手,我也怕高手们说我装13,小生不才: 2.如有什么不对的地方,还希望大家指出,一定虚心学习: 3.本文属于作者原创,尊重他人劳动成果,转载请注明作者,谢谢. 下面开讲: 第一步:首先是下载一个AspNetPager.dll 下载地址 AspNetPager.rar第二步:在项目的bin文件夹下引用AspNetPager.dll 如图: 第三步:在工具箱添加AspNetPager控件,如图: 接下来再如图: 这样

asp.net GridView控件中实现全选的解决方案_实用技巧

第一种:利用客户端控件实现 JS: 复制代码 代码如下: <script type="text/javascript"> function checkAll() { var checklist=document.getElementsByTagName("input"); for(var i=0;i<checklist.length;i++) { if(checklist[i].type=="checkbox") { check