一个用户控件的问题:控件生成一段html中包含一个文本框,在PostBack以后文本框的值就被冲掉了?请大家帮忙看下 呵呵,能不能用session或者cache或者cookie或者content这种缓存手动记忆啊。 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 谢谢楼上,缓存是肯定要的,在这里可以用ViewState比较合适现在主要问题是何时缓存,怎么缓存在具体的程序中可以同一个页面会有多个这样的用户控件,如果不处理好ViewSatae的Key的话,多个用户控件可能会使用了同一个key.欢迎大家给我提示或者相关的链接. EnableViewState的值设为False试试 让CreateChildControls()在页面加载的时候执行一次,以后postback就不执行,这样可不可以。 想要自定义控件实现PostBack的数据处理,自定义控件要实现IPostBackDataDataHandler接口 to hertcloud(重载∮DOTNET Joyes.com)我在调用这个用户控件的页面的Page_Load里这样写:if(!IsPostBack){ //初始化用户控件}这样好象没有作用,还是会把值冲掉。另外,因为这个控件在使用时通常是直接把他拉到页面上去的,好象没办法控制他的创建,请问有没有办法控制呢?to chg515(瞎玩) :在CreateChildControls()事件里写protected override void CreateChildControls(){ if(!IsPostBack) { base.CreateChildControls (); html="<INPUT TYPE=text ID='MyUC'>"; Literal l=new Literal(); l.Text=_Html; this.Controls.Add(l); } }这样写的话,postback后这个控件就没有生成了to pinglv(Amanda) :EnableViewState设为False也不行-------------------请问大家有没有使用过用户控件的LoadViewState()和SaveViewState()重载方法,我看了msdn,好象这两个方法跟我的问题有点关系,有人能贴下这两个方法的运行机制或相关的文章吗? to soldierB(eric):能描述下使用IPostBackDataHandler解决这个问题的过程吗?我刚查了一下msdn,觉得即使实现了IPostBackDataHandler,程序还是要执行CreateChildControls()方法,那么postback以后这个文本框的值还是被冲掉了 只有runat="server"的控件才能保持原值 to wuzhijie(阿杰) :请问你指的runat属性指的是用户控件,还是用户控件生成的文本框,用户控件本身是runat=server,如果指的是用户控件生成的文本框的话,那这样写protected override void CreateChildControls(){ base.CreateChildControls (); html="<INPUT TYPE=text ID='MyUC' runat=server >";//这里把文本框改成runat=server Literal l=new Literal(); l.Text=_Html; this.Controls.Add(l);}好象这样也是不行。 因为你的这个控件是在代码中产生的,所以重新加载的时候,这个控件是重新生成的,已经不是原来的那个了,所以值肯定是没有了啊你可以采用session或者什么别的方法给它重新赋值 分析了页面的ViewState的构成,我们再来看Control的ViewState的实现。ViewState是System.Web.UI.Control类实现的一个属性,这个属性的类型是System.Web.UI.StateBag,这个类就包含了ViewState数据结构的实现,实际上它的内部也就是个Hash表,通过Key值来保存和检索数据。 那么服务器控件是怎么实现保存状态的呢? 我们知道,所有的服务器控件都是从System.Web.UI.Control派生的,所以都拥有ViewState这个属性,在Control内部,定义了两个Protected的虚拟方法: protected virtual object SaveViewState() 和protected virtual void LoadViewState(object savedState) 这两个方法是给子控件派生用来保存和读取自己的ViewState的,比如我们有一个自己写的控件,往ViewState中保存了一个字符串,那么我们的方法大致像这样: protected virtual object SaveViewState() { object[] states = new object[2]; states[0] = base.SaveViewState(); //记得保存父控件的ViewState states[1] = "Hello,I'm timmy!"; //这里保存我们自己的 return states; //返回重新包装后的保存对象 } 获取的时候: protected override void LoadViewState(object savedState) //这里的savedState就是我们Save的时候return 的object数组 { object[] states = (object[])savedState; base.LoadViewState( states[0] ); //把父类的数据给他自己去解析 string myData = (string)states[1]; //获取我们自己的数据 } 我们可以按照自己的方式来保存,不一定非要像上面这样用数组,实际上我们可以用任何支持序列化的对象都可以,父类并不关心子类如何保存,我们只要在Save和Load的时候使用同样的方式,并且把正确的数据传递给父类方法就可以了。 另外,还有一个问题就是我们使用的Control的ViewState是Key-Value这样的键值对,那它是怎么保存的呢? 实际上很简单,System.UI.Web下面有一个类叫Pair,呵呵,这个和Triplet差不多,只是它里面只有两个对象。StateBag保存的时候,First会存放所有Key值的数组,Second则存放所有Value的数组。 执行CreateChildControls()的话,里面的html控件重新生成,不执行的话,不会生成控件。用ViewState也没有用,因为页面回传后CreateChildControls()重新执行,又重新生成了一个html控件 要postback保持数据首先你必须实现IPostBackDataHandler接口public class WebCustomControl1 : System.Web.UI.WebControls.WebControl,IPostBackDataHandler { public String YourValue { get { return (String) ViewState["Text"]; } set { ViewState["Text"] = value; } } protected override void CreateChildControls() { base.CreateChildControls (); string html="<INPUT TYPE=text name=" + this.UniqueID + " ID='MyUC' value='"+YourValue+"'>"; LiteralControl l=new LiteralControl(); l.Text =html; this.Controls.Add(l); } public bool LoadPostData(String postDataKey, NameValueCollection values) { YourValue = values[this.UniqueID]; return false; } public void RaisePostDataChangedEvent() { // IPostBackDataHandler 协定的一部分。如果曾经从 LoadPostData 方法返回真 // (表示需要引发更改通知),则被调用。由于 // 始终返回假,则此方法只是一个空操作。 } protected override void CreateChildControls(){ base.CreateChildControls (); html="<INPUT TYPE=text ID='MyUC' Name='MyUC' value='" + Request.Form["MyUC"].ToString + "'>"; Literal l=new Literal(); l.Text=_Html; this.Controls.Add(l);}这样总可以吧?应该先判断一下,第一次载入的时候设置input的value为空 不知道楼上的几位有没有测试过,我试了这几种办法,可是没有一种调通?to srz007(呵呵):在CreateChildControls的时候,Request.Form["MyUC"]已经为没有值了to 2002pine(我爱你江南的雪儿) 和 goody9807() :我使用了两位的方法,但是没有效果,当我把断点设在SaveViewState(),LoadViewState()和LoadPostData()里面时,发现postback的时候这三个函数里的断点都没触发下面是我的代码:--------------------------------------------------------------------public class UC_MyTestControl: System.Web.UI.UserControl,IPostBackDataHandler{ ...//这些是一些vs.net自动生成的代码 public String MyValue get { obj=ViewState["MyValue"]; return (obj == null)?String.Empty:obj.ToString(); } set { ViewState["MyValue"] = value; } protected override void CreateChildControls() { base.CreateChildControls (); html="<INPUT TYPE=text ID='MyUC' Name='MyUC' value='" + MyValue + "'>"; //这是srz007(呵呵)的方法,在调试的时候发现Request.Form是空的 // html="<INPUT TYPE=text ID='MyUC' Name='MyUC' value='" + // Request.Form["MyUC"].ToString + "'>"; Literal l=new Literal(); l.Text=_Html; this.Controls.Add(l); } #region IPostBackDataHandler 成员 public void RaisePostDataChangedEvent() { // TODO: 添加 UC_GetBankList.RaisePostDataChangedEvent 实现 } public bool LoadPostData(string postDataKey, System.Collections.Specialized.NameValueCollection postCollection) { MyValue=(string)postCollection["MyUC"];//断点 return false; } protected override object SaveViewState() { object[] objs=new object[3];//断点 objs[0]=base.SaveViewState(); objs[1]=Request.Form[MyUC]; return objs; } protected override void LoadViewState(object savedState) { Object[] objs=(Object[])savedState;//断点 base.LoadViewState (objs[0]); KeyWord=objs[1].ToString(); }}----------------------------另外,在CreateChildControls的时候获取this.UniqueID的时候,发现为空,是不是需要加某个Attributes? to zjsen(星愿)(个人观点,仅供参考.请自行验证):我的方法是经过测试,绝对没问题,你没试出效果,请你仔细看清我的代吗. to 2002pine(我爱你江南的雪儿) :那能不能贴出CreateChildControls()和IPostBackDataHandler接口的实现代码?或者请帮我看下上面的代码是不是有问题? 帮你up,当时我遇到这样的情况时,解决方法是用写.htc实现的实在不行你就把txt的内容写入一个隐藏的服务器label控件中然后读取如果按照写一个标准的自定义服务器控件来说的确应该实现IPostBackDataHandler接口,不过我在msdn里面没有察到,关注 2002pine(我爱你江南的雪儿) 给出的代码,希望能看到更多相关内容 html="<INPUT TYPE=text ID='MyUC' Name='MyUC' value='" + MyValue + "'>"; string html="<INPUT TYPE=text name=" + this.UniqueID + " ID='MyUC' value='"+YourValue+"'>"; webconfig 连接字符串加密和解密 js 绑定数据 语句拼接 VSS(2005)只有签出 没有签入(在线等) 如何在C#中给前台有规律的input赋值 dotnetcharting 画图 问题 chart控件的X轴为什么不能显示数据的? 怎么在服务器端弹出网页确认取消对话框并获取选择? 网页在后台下载文件,如何实时显示文件下载了多少 问一个关于VS2005 如何根据值获得listbox的索引? (急急急)请问高手们怎样将在简体net上做好的ASP.NET转为可以在繁体系统上运行 请问
现在主要问题是何时缓存,怎么缓存
在具体的程序中可以同一个页面会有多个这样的用户控件,如果不处理好ViewSatae的Key的话,多个用户控件可能会使用了同一个key.欢迎大家给我提示或者相关的链接.
我在调用这个用户控件的页面的Page_Load里这样写:
if(!IsPostBack)
{
//初始化用户控件
}
这样好象没有作用,还是会把值冲掉。另外,因为这个控件在使用时通常是直接把他拉到页面上去的,好象没办法控制他的创建,请问有没有办法控制呢?
to chg515(瞎玩) :
在CreateChildControls()事件里写
protected override void CreateChildControls()
{
if(!IsPostBack)
{
base.CreateChildControls ();
html="<INPUT TYPE=text ID='MyUC'>";
Literal l=new Literal();
l.Text=_Html;
this.Controls.Add(l);
}
}
这样写的话,postback后这个控件就没有生成了to pinglv(Amanda) :EnableViewState设为False也不行-------------------
请问大家有没有使用过用户控件的LoadViewState()和SaveViewState()重载方法,我看了msdn,好象这两个方法跟我的问题有点关系,有人能贴下这两个方法的运行机制或相关的文章吗?
能描述下使用IPostBackDataHandler解决这个问题的过程吗?
我刚查了一下msdn,觉得即使实现了IPostBackDataHandler,程序还是要执行CreateChildControls()方法,那么postback以后这个文本框的值还是被冲掉了
请问你指的runat属性指的是用户控件,还是用户控件生成的文本框,用户控件本身是runat=server,
如果指的是用户控件生成的文本框的话,那这样写
protected override void CreateChildControls()
{
base.CreateChildControls ();
html="<INPUT TYPE=text ID='MyUC' runat=server >";//这里把文本框改成runat=server
Literal l=new Literal();
l.Text=_Html;
this.Controls.Add(l);
}
好象这样也是不行。
那么服务器控件是怎么实现保存状态的呢?
我们知道,所有的服务器控件都是从System.Web.UI.Control派生的,所以都拥有ViewState这个属性,在Control内部,定义了两个Protected的虚拟方法:
protected virtual object SaveViewState()
和
protected virtual void LoadViewState(object savedState) 这两个方法是给子控件派生用来保存和读取自己的ViewState的,比如我们有一个自己写的控件,往ViewState中保存了一个字符串,那么我们的方法大致像这样:
protected virtual object SaveViewState()
{
object[] states = new object[2];
states[0] = base.SaveViewState(); //记得保存父控件的ViewState
states[1] = "Hello,I'm timmy!"; //这里保存我们自己的
return states; //返回重新包装后的保存对象
}
获取的时候:
protected override void LoadViewState(object savedState) //这里的savedState就是我们Save的时候return 的object数组
{
object[] states = (object[])savedState;
base.LoadViewState( states[0] ); //把父类的数据给他自己去解析
string myData = (string)states[1]; //获取我们自己的数据
}
我们可以按照自己的方式来保存,不一定非要像上面这样用数组,实际上我们可以用任何支持序列化的对象都可以,父类并不关心子类如何保存,我们只要在Save和Load的时候使用同样的方式,并且把正确的数据传递给父类方法就可以了。
另外,还有一个问题就是我们使用的Control的ViewState是Key-Value这样的键值对,那它是怎么保存的呢?
实际上很简单,System.UI.Web下面有一个类叫Pair,呵呵,这个和Triplet差不多,只是它里面只有两个对象。StateBag保存的时候,First会存放所有Key值的数组,Second则存放所有Value的数组。
用ViewState也没有用,因为页面回传后CreateChildControls()重新执行,又重新生成了一个html控件
首先你必须实现IPostBackDataHandler接口
public class WebCustomControl1 : System.Web.UI.WebControls.WebControl,IPostBackDataHandler
{
public String YourValue
{
get
{
return (String) ViewState["Text"];
}
set
{
ViewState["Text"] = value;
}
} protected override void CreateChildControls()
{
base.CreateChildControls ();
string html="<INPUT TYPE=text name=" + this.UniqueID + " ID='MyUC' value='"+YourValue+"'>";
LiteralControl l=new LiteralControl();
l.Text =html; this.Controls.Add(l);
} public bool LoadPostData(String postDataKey, NameValueCollection values)
{ YourValue = values[this.UniqueID];
return false;
}
public void RaisePostDataChangedEvent()
{ // IPostBackDataHandler 协定的一部分。如果曾经从 LoadPostData 方法返回真
// (表示需要引发更改通知),则被调用。由于
// 始终返回假,则此方法只是一个空操作。
}
{
base.CreateChildControls ();
html="<INPUT TYPE=text ID='MyUC' Name='MyUC' value='" + Request.Form["MyUC"].ToString + "'>";
Literal l=new Literal();
l.Text=_Html;
this.Controls.Add(l);
}
这样总可以吧?应该先判断一下,第一次载入的时候设置input的value为空
to srz007(呵呵):
在CreateChildControls的时候,Request.Form["MyUC"]已经为没有值了
to 2002pine(我爱你江南的雪儿) 和 goody9807() :
我使用了两位的方法,但是没有效果,当我把断点设在SaveViewState(),LoadViewState()和
LoadPostData()里面时,发现postback的时候这三个函数里的断点都没触发
下面是我的代码:
--------------------------------------------------------------------
public class UC_MyTestControl: System.Web.UI.UserControl,IPostBackDataHandler
{
...//这些是一些vs.net自动生成的代码
public String MyValue
get
{
obj=ViewState["MyValue"];
return (obj == null)?String.Empty:obj.ToString();
}
set
{
ViewState["MyValue"] = value;
}
protected override void CreateChildControls()
{
base.CreateChildControls ();
html="<INPUT TYPE=text ID='MyUC' Name='MyUC' value='" +
MyValue + "'>";
//这是srz007(呵呵)的方法,在调试的时候发现Request.Form是空的
// html="<INPUT TYPE=text ID='MyUC' Name='MyUC' value='" +
// Request.Form["MyUC"].ToString + "'>";
Literal l=new Literal();
l.Text=_Html;
this.Controls.Add(l);
}
#region IPostBackDataHandler 成员
public void RaisePostDataChangedEvent()
{
// TODO: 添加 UC_GetBankList.RaisePostDataChangedEvent 实现
}
public bool LoadPostData(string postDataKey,
System.Collections.Specialized.NameValueCollection postCollection)
{
MyValue=(string)postCollection["MyUC"];//断点 return false;
} protected override object SaveViewState()
{
object[] objs=new object[3];//断点
objs[0]=base.SaveViewState();
objs[1]=Request.Form[MyUC];
return objs;
}
protected override void LoadViewState(object savedState)
{
Object[] objs=(Object[])savedState;//断点
base.LoadViewState (objs[0]);
KeyWord=objs[1].ToString();
}
}
----------------------------
另外,在CreateChildControls的时候获取this.UniqueID的时候,发现为空,是不是需要加某个Attributes?
我的方法是经过测试,绝对没问题,你没试出效果,请你仔细看清我的代吗.
那能不能贴出CreateChildControls()和IPostBackDataHandler接口的实现代码?
或者请帮我看下上面的代码是不是有问题?
不过我在msdn里面没有察到,关注 2002pine(我爱你江南的雪儿) 给出的代码,希望能看到更多相关内容
MyValue + "'>";
string html="<INPUT TYPE=text name=" + this.UniqueID + " ID='MyUC' value='"+YourValue+"'>";