本文介绍Ext.NET的基本概念,安装配置、布局以及容器,最后介绍了DirectEvents、DirectMethod、Listener,并提供了示例代码。
示例代码下载地址>>>>>
Ext.NET 是基于跨浏览器的 Sencha ExtJS 库和.NET Framework的一套支持ASP.NET AJAX的非开源Web控件,包含有丰富的Ajax运用,其前身是Coolite 。
Ext.NET使用一种自己的翻译机制,将ASPX页面中的EXT.NET标记代码翻译成EXTJS,浏览器中执行的还是EXTJS代码,类似于 Sencha GXT ,至于EXTJS的由来不清楚的话可以问度娘。
EXT.NET也对EXTJS做了一些自己的扩展。EXT.NET在2.3之前是开源的;在1.0之前叫做Coolite。
Ext.NET 最新版本是3.1,基于 EXTJS 5.1.0,与 EXT.NET 2.X 的主要区别是多了对平板设备的支持,当然,这主要是由于 Ext.NET 2.X 系列是基于 EXTJS 4.X,自从EXTJS 5.0 才有对平板设备的支持。
如下是EXT.NET官方 下载页面 给出的说明:
Ext.NET 3.1 | Ext.NET 2.5.3 | |
---|---|---|
Ext Js 版本 | Ext JS 5.1.0 | Ext JS 4.2.1 |
发布时间 | 2015-02-17 | 2014-11-05 |
.NET Framework要求 | .NET 4.0, 4.5 & 4.5.1 | .NET 3.5, 4.0 , 4.5 & 4.5.1 |
CPU | 32 & 64 bit | 32 & 64 bit |
Visual Studio | 2010, 2012 & 2013 | 2008, 2010, 2012 & 2013 |
桌面浏览器支持 | Chrome,Firefox,IE8+,Safari 6+,Opera 12+ | Chrome,Firefox,IE6+,Safari 6+,Opera 12+ |
平板浏览器支持 | Safari iOS6+,Chrome Android 4.1+,IE10+ Win8 | 不支持 |
2015年2季度或3季度发布Ext.NET 3.2.0 | 不再发布新版本 |
上面提到,Ext.NET是对ExtJS的.NET封装,那么为么不直接用ExtJS呢?
总之,减少了工作量,降低了学习成本;不过在实际的使用中,还是需要写一些简单的javascript代码。
关于ExtJS这里不多介绍,其提供的多种主题样式,尤其适用于企业应用开发,很少需要美工的介入,这一点对于小型团队来说,尤其缺少专业美工的情况下,颇为实用。
关于请参见 Sencha官方博客 ,其中有Extjs与AngularJS的比较。
官方的 Readme 以及 Visual Studio配置说明 已经说的很清楚了,两种方法: 自动配置 和 手动配置。
至于添加到VS工具箱拖拽控件至页面,基本没用,还是省省时间吧,Ext.NET基本没有对设计时可视化支持的,这也是入门较难的原因之一。
使用NuGet,新手推荐使用这种方式,因为—— 简单 。
方法如下:
工具
> 扩展和更新
,安装 NuGet程序包管理器
,通常,VS2013已经自动安装了,若没有,左侧点 联机
,右上方搜索框中输入 NuGet
,具体安装过程 参见此处 ,安装完成会需要重启VS。 VS中新建空Web项目,解决方案资源管理器中项目名称上 右键
> 管理NuGet程序包
,左侧点 联机
,右上方搜索框中输入 ext.net
,安装之。
耐心等待,Ext.NET的DLL也要好几十M的,经过无聊的等待后,开发环境自动配置好了,来看看NuGet都自动做了些什么:
Web.Config
文件。 我们手动要做的无非就这几个事情。
下图是Ext.NET3.1.0的依赖关系:
也就意味着手动配置的话需要为项目添加这些依赖项的引用。
自动添加的 APP_Readme
目录和 Ext.Net.Default.aspx
(测试页面)可以删除。
Web.Config
文件。 至于如何手动配置,请参见前面提到的 Readme 以及 Visual Studio配置说明 。
<extnet />
配置说明 默认的配置如下
<extnet theme="Crisp" licenseKey="** Ext.NET LICENSE KEY HERE **" initScriptMode="Linked" />
Readme 文件中有详尽的 <extnet/>
属性配置说明,下面列出几个比较常用的:
Release
、 Debug
、 Development
Development(非压缩且带debug信息) 经验证,此项不可用
Default
、 Access
、 Gray
、 Neptune
、 Neptune Touch
、 Crisp
、 Crisp Touch
新建WebForm页面,默认body中的内容删除掉。
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ExtNetTemplate.aspx.cs" Inherits="WebFormDemo.ExtNetTemplate" %> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>ExtNetTemplate</title> </head> <body> <ext:ResourceManager runat="server" /> </body> </html>
若是 <body>
中输入 <ext
没有自动代码提示的话,重新加载Web项目或重新打开解决方案即可。
<ext:ResourceManager runat="server" />
必须在 <body></body>
中第一行,因为它负责为页面添加js和各种css文件的引用。
Web项目开发,无法避免编写 javascript
脚本,VS提供的 Intellisense
方便快捷,如何添加 javascript
的 EXTJS
的代码提示支持?
在Web项目的 Scripts
目录中(若没有新建)添加 _references.js
文件,并输入如下代码;
/// <autosync enabled="true" /> /// <reference name="Ext.Net.Build.Ext.Net.extjs.ext-all-debug.js" assembly="Ext.Net" /> /// <reference name="Ext.Net.Build.Ext.Net.extnet.extnet-all-debug.js" assembly="Ext.Net" />
这样项目中的js文件中,就有了代码提示。
支持的就不够全不够好?因为Sencha官方现在好像只提供对Sublime Text的支持,有好的方法别忘了告诉我,谢谢。
使用时可查看 ExtJs官方API文档 。
Ext.NET/EXTJS都是用的CSS来控制样式的,若想自定义,自己加一个css样式表文件引用至实际的ASPX页面中就可以。针对中文覆盖默认字体的CSS定义,新建ExtjsExtra.css文件,内容如下:
/*#region Extjs样式扩展*/ * { font-family: 'Helvetica', 'Tahoma', 'Arial', "Microsoft YaHei", "微软雅黑",'STXihei', "华文细黑", 'SimSun', "宋体", 'Heiti', "黑体", 'sans-serif' !important; } /*#endregion */
在ASPX文件的 <head></head>
中添加对此CSS文件的引用即可。
<link rel="stylesheet" type="text/css" href="/Content/ExtjsExtra.css" />
前面说过, EXT.NET
基本没有对设计时可视化支持的,这也是新手常常遇到的问题,在 官方示例 中,已经有详尽的示例代码,认真阅读官方示例,常见的布局问题都可以应付。
EXTJS
有 Sencha Architect 提供了设计时的支持,不过生成的是纯js代码。
EXT.NET
官方示例Layout节点中有各种布局的详细代码例子,如下
大致说明下:
ColumnWidth
指定所占宽度比例(0到1之间的小数),同级别的容器加起来为1就行,可以和 Width
一起使用,详见 示例 。 Layout
属性为 FitLayout
时(写成 Fit
也能解析),其内部容器将铺满A的大小; 请参考 Sencha官方API文档 中关于各种Layout的详细说明。
EXT.NET或者说EXTJS提供的布局方式大致就这么多,可以根据需要组合使用,后面用到时做详细介绍。
最基本的容器,相对Panel来说,更为轻量,当仅仅需要将其它控件按照一定的方式布局时使用。
Container也是Sencha建议的布局方式。
关于Container详细说明请参见 Ext.container.Container
Panel应该是最为常用的容器控件之一,也是很多容器控件如FormPanel、Window等的基础,以下是一个Panel的最简单的应用示例,
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ExtNetTemplate.aspx.cs" Inherits="WebFormDemo.ExtNetTemplate" %> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>ExtNetTemplate</title> <link rel="stylesheet" type="text/css" href="/Content/ExtjsExtra.css" /> </head> <body> <ext:ResourceManager runat="server" /> <ext:Panel runat="server" ID="pnlMain" Title="Panel示例" Layout="HBoxLayout" Width="300" Height="200" Closable="true" CloseAction="Hide"> <LayoutConfig> <ext:HBoxLayoutConfig Align="Stretch" /> </LayoutConfig> <TopBar> <ext:Toolbar runat="server"> <Items> <ext:Button runat="server" Text="+" ToolTip="新建" /> <ext:ToolbarSeparator runat="server" /> <ext:Button runat="server" Icon="Disk" ToolTip="保存" /> </Items> </ext:Toolbar> </TopBar> <Buttons> <ext:Button runat="server" Text="Delete" Scale="Medium" UI="Danger" /> <ext:Button runat="server" Text="Cancel" Scale="Large" /> </Buttons> <Items> <ext:Panel runat="server" ID="pnlChild1" Html="<b>Flex=1</b>" Flex="1" Border="true" /> <ext:Panel runat="server" ID="pnlChild2" Html="<b>Flex=2</b>" Flex="2" Border="true" /> </Items> <Tools> <ext:Tool Type="Help" ToolTip="帮助" /> <ext:Tool Type="Gear" ToolTip="设置" /> </Tools> </ext:Panel> </body> </html>
说明:
Layout="HBoxLayout"
定义 pnlMain
内部控件使用HBoxLayout布局; Width="300" Height="200"
定义 pnlMain
的宽度和高度,通常使用中不建议这样写; <LayoutConfig></LayoutConfig>
中的 <ext:HBoxLayoutConfig Align="Stretch" />
定义 pnlMain
内部控件纵向拉伸; <TopBar></TopBar>
定义 pnlMain
中顶端的工具条,其中包含了新建和保存按钮; <Buttons></Buttons>
定义 pnlMain
包含两个按钮; <Items></Items>
定义 pnlMain
所包含的子控件,可以是EXT支持的任意容器或Form控件 关于Panel详细说明请参见 Ext.panel.Panel
FormPanel一般用来做编辑界面,大部分功能与Panel相同,不同的是,它为其包含的Field提供了一些很方便实用的功能,如 reset
、 loadRecord
等方法,后面再细说。
关于FormPanel详细说明请参见 Ext.form.Panel
最为常用、最多插件、功能最多(复杂)的容器控件,没有之一。用到的时候再来细说,先来看看它提供的功能:
为演示使用,请先添加Person.cs类,代码如下
namespace WebFormDemo { public class Person { public string Name { get; set; } public int Age { get; set; } public string Desc { get; set; } } }
一般用在客户端通过AJAX方式触发服务器端DirectEvent(其实也是方法),如单击按钮后执行一段服务器端代码等;触发服务器端DirectEvent的为EXT.NET控件、ASP.NET控件、甚至任何HTML DOM元素都可以;
注意:服务器端事件应按照 protected void Do (object sender, DirectEventArgs e)
方式声明;
以下代码演示了一个DirectEvent请求。
ASPX.cs
using Ext.Net; using System.Threading; namespace WebFormDemo.DirectEvents { public partial class Default : System.Web.UI.Page { protected void btnMe_Click(object sender, DirectEventArgs e) { string name = e.ExtraParams["name"]; int age; int.TryParse(e.ExtraParams["age"], out age); if (age > 18) { Thread.Sleep(1000); //do something... string desc = age < 30 ? "年轻人" : "大叔"; Person s = new Person { Name = name, Age = age, Desc = desc }; e.ExtraParamsResponse.Add(s); e.Success = true;//执行成功 } else { e.Success = false;//执行失败 e.ErrorMessage = "错误-未满18岁.";//执行失败时给客户端的信息 } } } }
ASPX
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebFormDemo.DirectEvents.Default" %> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>DirectEvents示例</title> <script type="text/javascript" src="default.js"></script> </head> <body> <ext:ResourceManager runat="server" /> <ext:Button runat="server" ID="btnMe" Text="请点我" Scale="Large"> <DirectEvents> <Click OnEvent="btnMe_Click" Success="btnMe_Success" Failure="btnMe_Failure"> <%--确认--%> <Confirmation ConfirmRequest="true" Message="确定点我?" /> <%--AJAX Loading--%> <EventMask Msg="正在执行..." Target="Page" ShowMask="true" /> <ExtraParams> <%--Mode:Value表示直接传值--%> <ext:Parameter Name="name" Value="张三" Mode="Value" /> <%--Mode:Raw表示经过运算后的值,此处调用了getAge方法--%> <ext:Parameter Name="age" Value="getAge()" Mode="Raw" /> </ExtraParams> </Click> </DirectEvents> </ext:Button> </body> </html>
Javascript
/* * 服务器端执行成功时 */ var btnMe_Success = function (response, result, control, type, action, extraParams) { var res = result.extraParamsResponse; var msg = Ext.util.Format.format("你好<b>{0}</b>!name:{1},age:{2}", res.desc, res.name, res.age); //提示成功 Ext.net.Notification.show({ html: msg, title: '执行成功' }); }; /* * 服务器端执行失败时 */ var btnMe_Failure = function (response, result, control, type, action, extraParams) { var msg = result.errorMessage; //提示失败 Ext.net.Notification.show({ html: msg, title: '执行失败' }); }; /* * 产生随机数 */ var getAge = function () { return Ext.Number.randomInt(1, 100); };
更多示例
DirectMethod为在javascript中调用服务器端方法提供了很方便的一种调用方式。
public
或 public static
; [DirectMethod]
特性的签名; 接着上面的例子,来看看用DirectMethod方式的实现ASPX.cs
using Ext.Net; using System; using System.Threading; namespace WebFormDemo.DirectMethod { public partial class Default : System.Web.UI.Page { [DirectMethod] public Person GetPerson(string name,int age) { if (age > 18) { Thread.Sleep(1000); //do something... string desc = age < 30 ? "年轻人" : "大叔"; return new Person { Name = name, Age = age, Desc = desc };//返回给客户端 } else { throw new Exception("错误-未满18岁.");//执行失败时给客户端的信息 } } } }
ASPX
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebFormDemo.DirectMethod.Default" %> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>DirectMethod示例</title> <script type="text/javascript" src="default.js"></script> </head> <body> <ext:ResourceManager runat="server" /> <ext:Button runat="server" ID="btnMe" Text="请点我" Scale="Large"> <Listeners> <Click Fn="btnMe_Click" /> </Listeners> </ext:Button> </body> </html>
Javascript
/* *调用DirectMethod */ var btnMe_Click = function (sender, e) { //对应服务器端GetPerson(string name,int age)方法的签名 App.direct.GetPerson("张三", getAge(), { //服务器端执行成功时 success: function (result) { //result是服务器端Person的一个实例,通过json串行化后返回客户端, //所以此处result.Name需要注意大小写与Person类属性对应 var msg = Ext.util.Format.format("你好<b>{0}</b>!name:{1},age:{2}", result.Desc, result.Name, result.Age); Ext.net.Notification.show({ html: msg, title: '执行成功' }); }, //服务器端失败时 failure: function (errorMessage) { Ext.net.Notification.show({ html: errorMessage, title: '执行失败' }); }, //AJAX Loading eventMask: { showMask: true, msg: '数据加载中...', target: 'page' } }); }; /* * 产生随机数 */ var getAge = function () { return Ext.Number.randomInt(1, 100); };
其中 App.direct.GetPerson("张三", getAge(), {//...});
,前面两个参数对应服务器端方法 public Person GetPerson(string name,int age)
的参数。
Listener表示客户端事件(Extjs本身提供),调用客户端javascript方法。上面的DirectMethod示例代码中
<Listeners> <Click Fn="btnMe_Click" /> </Listeners>
就表示一个Click事件,并调用javascript中的 btnMe_Click
方法。
作者自2010年的 Coolite 时代开始,几乎所有.NET Web项目中使用 Ext.NET ,这篇文章算是表达对他们的一点敬意。