关于Ext Extender
ExtExtenders是由Rodrigo Diniz开发的一组对Extjs 客户端控件的.net服务器端包装控件
由Extender可知道其运行必须ASP.NET AJAX框架的支持.
类似的项目有Coolite,但为什么我们更应该关注ExtExtenders呢? 开源,而且功能更加强大.
演示地址 http://www.extendersamples.qsh.eu/
项目主页 http://www.codeplex.com/ExtJsExtenderControl
开源软件的最大好处就是我们不仅能够利用它来为我们的工作带来方便,而且能够透过其源代码,学习作者的实现方法,
领悟其设计思路,加快我们进步的步伐,正所谓是站在巨人的肩膀上,好风凭借力.
一如往常的技术介绍文章,让我们从最简单的开始,Extjs的日历组件界面美观,功能也非常强大而且没有复杂的服务器端 - 客户端交互行为, 就让我们先拿它开刀吧

首先我们到Codeplex下载一份源代码,这里以版本31017作为示例.
解压好后,先看到GridControl目录下的几个文件: YUI.cs, YUI-ext.cs, ext-yui-adapter.cs .
可以看到这几个文件实现非常简单:就是一个静态类,标注了其需要使用的嵌入式资源.
[assembly: System.Web.UI.WebResource("ExtExtenders.yui.js", "text/javascript")]2
namespace ExtExtenders3
{4
/// <summary>5
/// Class to include the js file6
/// </summary> 7
public static class YUI8
{9
}10
}然后来到今天的主角Calendar,这个文件夹里分别有CalendarExtenderExtender.cs 和一个脚本文件CalendarExtenderBehavior.js(注意到整个项目里的js和css以及图片文件都设为了嵌入式文件)
看看CalendarExtenderExtender.cs 里到底实现了啥
1
[ToolboxBitmap(typeof(System.Web.UI.WebControls.Calendar))]2
public class ExtCalendar : TextBox, IScriptControl3
{4
private ScriptManager sm;5
private string _disabledDays;6
/// <summary>7
/// An array of days to disable, 0 based. For example, [0, 6] disables 8
/// Sunday and Saturday (defaults to null).9
/// </summary>10
public string disabledDays11
{12
get13
{14
return _disabledDays;15
}16
set17
{18
_disabledDays=value;19
}20
}21
private string _disabledDaysText;22
/// <summary>23
/// The message that appears when a date is disabled24
/// </summary>25
public string disabledDaysText26
{27
get28
{29
return _disabledDaysText;30
}31
set32
{33
_disabledDaysText=value;34
}35
}36
private string _disabledDates;37
/// <summary>38
/// An array of "dates" to disable, as strings. These strings will be used to build a dynamic regular expression so they are very powerful.39
/// Some examples: * ["03/08/2003", "09/16/2003"] would disable those exact dates40
/// * ["03/08", "09/16"] would disable those days for every year41
///* ["^03/08"] would only match the beginning (useful if you are using short years)42
///* ["03/../2006"] would disable every day in March 200643
///* ["^03"] would disable every day in every March44
///In order to support regular expressions, if you are using a date format that has "." in it, you will have to escape the dot when restricting dates. For example: ["03\\.08\\.03"].45
/// </summary>46
public string disabledDates47
{48
get49
{50
return _disabledDates;51
}52
set53
{54
_disabledDates=value;55
}56
}57
private string _disabledDatesText;58
/// <summary>59
/// The tooltip text to display when the date falls on a60
/// disabled date (defaults to 'Disabled')61
/// </summary>62
public string disabledDatesText63
{64
get65
{66
return _disabledDatesText;67
}68
set69
{70
_disabledDatesText=value;71
}72
}73
private string _format;74
/// <summary>75
/// The default date format string which can be overriden for localization support. 76
/// The format must be valid according to Date.parseDate (defaults to 'm/d/y').77
/// </summary>78
public string format79
{80
get81
{82
return _format;83
}84
set85
{86
_format=value;87
}88
}89

90
/// <summary>91
/// Raises the pre render event.92
/// </summary>93
/// <param name="e">The <see cref="T:System.EventArgs"/> instance containing the event data.</param>94
protected override void OnPreRender(EventArgs e)95
{96
base.OnPreRender(e);97
string resource = Page.ClientScript.GetWebResourceUrl(GetType(), "ExtExtenders.yui-ext.css");98
string csslink = "<link href='" + resource + "' rel='stylesheet' type='text/css' />";99
Page.Header.Controls.Add(new LiteralControl(csslink));100
ClientScriptManager man = Page.ClientScript;101
//render the yui-ext scripts102
man.RegisterClientScriptResource(typeof(YUI), "ExtExtenders.yui.js");103
man.RegisterClientScriptResource(typeof(YUI_ext), "ExtExtenders.yui-ext.js");104
man.RegisterClientScriptResource(typeof(ext_yui_adapter), "ExtExtenders.ext-yui-adapter.js");105
if (!this.DesignMode)106
{107
// Test for ScriptManager and register if it exists108
sm = ScriptManager.GetCurrent(Page);109

110
if (sm == null)111
throw new HttpException("A ScriptManager control must exist on the current page.");112

113
sm.RegisterScriptControl(this);114
}115
116
}117
/// <summary>118
/// Renders the control to the specified HTML writer.119
/// </summary>120
/// <param name="writer">The <see cref="T:System.Web.UI.HtmlTextWriter"></see> object that receives the control content.</param>121
protected override void Render(HtmlTextWriter writer)122
{ 123
base.Render(writer);124
if (!this.DesignMode)125
sm.RegisterScriptDescriptors(this);126
127
}128
129
IScriptControl Members173
}由声明可知,ExtCalendar直接继承了TextBox,且实现了IScriptControl.
让我们来看看IScriptControl的接口规范, msdn之
public interface IScriptControl2
{3
IEnumerable<ScriptDescriptor> GetScriptDescriptors();4
IEnumerable<ScriptReference> GetScriptReferences();5
}当一个类实现了IScriptControl,其需要分别实现两个方法.
GetScriptDescriptors()方法用来返回客户端元素是如何与该服务器端控件进行数据交互的Descriptor
GetScriptReferences()方法则告诉ScriptManager在程序运行时需要引入哪些script以及路径.
其后,ExtCalendar声明了一系列对应于Extjs库中Calendar客户端组件的属性. 并且重写了TextBox的OnPreRender方法注册了所需要的客户端资源.
这里需要注意的是,如果我们要使用中文版的ExtCalender的话,需要从Extjs的资源包中拷贝ext-lang-zh_CN.js到项目中设为嵌入式资源并且修改YUI.cs
在类声明上添加[assembly: System.Web.UI.WebResource("ExtExtenders.ext-lang-zh_CN.js", "text/javascript")]
接下来,看看作者是如何实现IScriptControl接口的 .
GetScriptReferences()很简单, 返回路径为ExtExtenders.calendar.CalendarBehaviorExtender.js的ScriptReference对象实例.
GetScriptDescriptors()呢 ?
由代码可知. 作者先新建了一个ScriptControlDescriptor对象实例,
然后把ExtCalendar的各个对应Extjs的客户端Calendar组件的属性添加上述的descriptror中,在控件的Render()事件中利用控件所处页面的ScriptManager注册这个descriptor,达到与客户端元素交互的目的.
来到客户端的实现
脚本代码的第2,3行分明声明了一个名为 ExtExtenders的命名空间以及该命名空间下的CalendarExtenderBehavior类. 在其后的原型声明中,initialize方法构造了一个客户端的Ext.form.DateField对象并且在页面呈现.
注意到js文件里有一系列get_XX, set_XX方法 它的作用就是按照get(set)_PropertyName的格式来传递服务器端ScriptDescriptor对象所具有的Property值.
最后一行, 作者把CalendarExtenderBehavior作为Sys.UI.Control的子类注册.
使用YuiGrid
首先下载一个ExtExtenders.dll的玩意,google上很多,就不具体说哪里下载了 /Files/guguangye/ExtExtenders.rar ,我也顺便提供一个我目前在用的版本。
首先把这个DLL添加到工具箱。

上述这些就是基本ExtExtenders基本控件了。
每用到一个再对该控件做一个详细介绍,今天先用了YUIGrid。
在使用ExtExtenders之前,首先要在web.config上做配置,否则会出现 未将对象引用实例的 黄页,这个是必须的。
OK,拖控件。在aspx文件中生成
如果只是用来测试,不手动绑定数据,记得在<cc1:YuiGrid>中设置AutoGenerateColumns=true,默认是false,所以不会显示数据。
可以放置一个ScriptManager和UpdatePanel作用是添加数据时达到局部刷新的效果。
在上述页面中,我把YuiGrid和两个textbox以及提交按钮放置在一个UpdatePanel中。
dataIndex代表绑定列名 hidden代表是否隐藏。
最后记得绑定对象,当然可以是泛型集合,dataset等等。

上面是整个效果图。
当然分页功能目前只是摆设,下次继续做分页功能和进一步对YuiGrid进行学习。
下面是生成的客户端代码,供参考


浙公网安备 33010602011771号