准备技术:
1.Asp.net常规开发技术;
2.了解控件开发的呈现、属性状态简单原理。
内容:
数据回传就是说客户端将数据回交给服务器,然后asp.net模型将会将处理后的数据回传到表单中去。如果开发的控件需要回传的话,就必须要去继承于IPostBackDataHandler接口。 继承IPostBackDataHandler之后我们一般需要去重写两个方法:
1.LoadPostData().方法返回一个bool值,表示该控件的值是否发生改变(需要我们去判断);
2.RaisPostDataChangeEvent().此方法是在LoadPostData方法返回true的时候去执行的。
一、LoadPostData方法
此方法的原型:LoadPostData(string postDataKey,System.Collections.Specialized.NameValueCollection postCollection)
参数postDataKey就是回传控件的UniqueID,在客户端表现为name属性。postCollection就是回传的数据值的结合。所以我们可以通过postCollection[postDataKey]来获取本控制回传的值,所以我们就可以来比较原来控件的值跟回传的值,从而来确定LoadPostData方法返回true还是false。
要注意的一点是,我们回传时需要name属性,所以如果我们定义的控件要支持数据回传的话,就必须要去添加属性name。
二、RaisePostDataChangeEvent()方法
RaisePostDataChangeEvent方法一般是在LoadPostData返回True的是否才去执行。一般我们在此方法中去触发一些事件,如:TextChanged。
三、实例
下面就来模仿写一个TextBox控件,当然现在只是去实现数据回传功能。
首先我们实现控件的一些属性,现在我们就让其有Text属性:
[PersistenceMode(PersistenceMode.EncodedInnerDefaultProperty),
DefaultValue(""),
Category("Behavior"),
Description("文本内容")]
public string Text
{
get
{
return this.ViewState["Text"] == null ? String.Empty : (string)this.ViewState["Text"];
}
set
{
this.ViewState["Text"] = value;
}
}
然后我们把控件呈现,控件是继承于WebControl的。
protected override HtmlTextWriterTag TagKey
{
get
{
return HtmlTextWriterTag.Input;
}
}
protected override void AddAttributesToRender(HtmlTextWriter writer)
{
base.AddAttributesToRender(writer);
if (Page != null)
{
Page.VerifyRenderingInServerForm(this);
}
writer.AddAttribute(HtmlTextWriterAttribute.Type, "text");
writer.AddAttribute(HtmlTextWriterAttribute.Name, this.UniqueID);
if (!Enabled)
{
writer.AddAttribute(HtmlTextWriterAttribute.Disabled, "disabled");
}
writer.AddAttribute(HtmlTextWriterAttribute.Value, this.Text);
}
protected override void AddParsedSubObject(object obj)
{
if (!(obj is Literal))
return;
base.AddParsedSubObject(obj);
}
这里要注意的是一定要注册其前台"name"属性。最后我们看如何让控件支持数据回传:
public bool LoadPostData(string postKey, system.Collections.Specialized.NameValueCollection valueCollection)
{
string postData = valueCollection[postKey].ToString();
string strText = this.Text;
if (strText.Equals(postData, StringComparison.Ordinal))
return false;
this.Text = postData;
return true;
}
public void RaisePostDataChangedEvent()
{
EventHandler handler = (EventHandler)Events[_objEvent];
if (handler != null)
{
handler(this, EventArgs.Empty);
}
}
其实原理很简单,就是判断回传过来的数据是否跟原来相等,不相等返回true,则执行RaisePostDataChangeEvent方法。控件的全部代码如下:
using system;
using system.Collections.Generic;
using system.ComponentModel;
using system.Text;
using system.Web;
using system.Web.UI;
using system.Web.UI.WebControls;
namespace HenllyeeControls
{
[DefaultProperty("Text"),
ParseChildren(true,"Text"),
DefaultEvent("TextChanged"),
ControlBuilder(typeof(HenllyeeTextBuider))]
public class HenllyeeText:WebControl,IPostBackDataHandler
{
Properties#region Properties
[PersistenceMode(PersistenceMode.EncodedInnerDefaultProperty),
DefaultValue(""),
Category("Behavior"),
Description("文本内容")]
public string Text
{
get
{
return this.ViewState["Text"] == null ? String.Empty : (string)this.ViewState["Text"];
}
set
{
this.ViewState["Text"] = value;
}
}
#endregion
Events#region Events
private static object _objEvent;
[Category("Action")]
public event EventHandler TextChanged
{
add
{
this.Events.AddHandler(_objEvent, value);
}
remove
{
this.Events.RemoveHandler(_objEvent, value);
}
}
#endregion
Render#region Render
protected override HtmlTextWriterTag TagKey
{
get
{
return HtmlTextWriterTag.Input;
}
}
protected override void AddAttributesToRender(HtmlTextWriter writer)
{
base.AddAttributesToRender(writer);
if (Page != null)
{
Page.VerifyRenderingInServerForm(this);
}
writer.AddAttribute(HtmlTextWriterAttribute.Type, "text");
writer.AddAttribute(HtmlTextWriterAttribute.Name, this.UniqueID);
if (!Enabled)
{
writer.AddAttribute(HtmlTextWriterAttribute.Disabled, "disabled");
}
writer.AddAttribute(HtmlTextWriterAttribute.Value, this.Text);
}
protected override void AddParsedSubObject(object obj)
{
if (!(obj is Literal))
return;
base.AddParsedSubObject(obj);
}
#endregion
IPostBackData#region IPostBackData
public bool LoadPostData(string postKey, system.Collections.Specialized.NameValueCollection valueCollection)
{
string postData = valueCollection[postKey].ToString();
string strText = this.Text;
if (strText.Equals(postData, StringComparison.Ordinal))
return false;
this.Text = postData;
return true;
}
public void RaisePostDataChangedEvent()
{
EventHandler handler = (EventHandler)Events[_objEvent];
if (handler != null)
{
handler(this, EventArgs.Empty);
}
}
#endregion
}
public class HenllyeeTextBuider : ControlBuilder
{
public override bool AllowWhitespaceLiterals()
{
return false;
}
public override bool HtmlDecodeLiterals()
{
return true;
}
}
}