Ext.NET
Ext.NET-基礎篇
概述
本文介紹Ext.NET的基本概念,安裝配置、布局以及容器,最後介紹了DirectEvents、DirectMethod、Listener,並提供了示例代碼。
示例代碼下載地址>>>>>
Ext.NET 簡介
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
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
上面提到,Ext.NET是對ExtJS的.NET封裝,那麽為麽不直接用ExtJS呢?
- 一整套專業的前端框架,兼容各種主流瀏覽器(甚至IE6),很少需要引入第三方庫,降低了學習成本;
- 減少了javascript的代碼量,易於維護,同時又不失ExtJs的靈活性;
- 提供的DirectEvents和DirectMethod,使調用服務器端方法更為簡單;
- 使ASP.NET開發人員更容易理解和使用ExtJS;
總之,減少了工作量,降低了學習成本;不過在實際的使用中,還是需要寫一些簡單的javascript代碼。
關於ExtJS這裏不多介紹,其提供的多種主題樣式,尤其適用於企業應用開發,很少需要美工的介入,這一點對於小型團隊來說,尤其缺少專業美工的情況下,頗為實用。
關於請參見Sencha官方博客,其中有Extjs與AngularJS的比較。
開發環境配置
官方的Readme以及Visual Studio配置說明已經說的很清楚了,兩種方法: 自動配置 和 手動配置。
至於添加到VS工具箱拖拽控件至頁面,基本沒用,還是省省時間吧,Ext.NET基本沒有對設計時可視化支持的,這也是入門較難的原因之一。
自動配置(推薦)
使用NuGet,新手推薦使用這種方式,因為——簡單。
方法如下:
- 打開Visual Studio,菜單欄
工具
>擴展和更新
,安裝NuGet程序包管理器
,通常,VS2013已經自動安裝了,若沒有,左側點聯機
,右上方搜索框中輸入NuGet
,具體安裝過程 參見此處,安裝完成會需要重啟VS。
若是搜不出來,改DNS/FQ/VPN/改Host文件等問度娘。 -
VS中新建空Web項目,解決方案資源管理器中項目名稱上
右鍵
>管理NuGet程序包
,左側點聯機
,右上方搜索框中輸入ext.net
,安裝之。
耐心等待,Ext.NET的DLL也要好幾十M的,經過無聊的等待後,開發環境自動配置好了,來看看NuGet都自動做了些什麽:- 自動下載了相關DLL文件,請打開項目所在物理路徑看看;
- 根據當前Web項目.NET Framework版本自動添加了Ext.NET的DLL對應.NET版本,包括Ext.NET本身的依賴DLL;
- 自動配置好了項目的
Web.Config
文件。
我們手動要做的無非就這幾個事情。
下圖是Ext.NET3.1.0的依賴關系:
也就意味著手動配置的話需要為項目添加這些依賴項的引用。
自動添加的 APP_Readme
目錄和 Ext.Net.Default.aspx
(測試頁面)可以刪除。
手動配置
- 下載DLL文件;
- 項目中添加對DLL的引用;
- 配置
Web.Config
文件。
至於如何手動配置,請參見前面提到的Readme以及Visual Studio配置說明。
WEB.CONFIG中<extnet />
配置說明
默認的配置如下
<extnet theme="Crisp"
licenseKey="** Ext.NET LICENSE KEY HERE **"
initScriptMode="Linked" />
Readme文件中有詳盡的<extnet/>
屬性配置說明,下面列出幾個比較常用的:
- ajaxTimeout : 設置默認的AJAX請求超時時間
默認為30000(30秒),單位毫秒.- glyphFontFamily : 為支持Glyph的組件設置字體名稱
如:FontAwesome,需要頁面引入相關的字體css文件,默認為空.- licenseKey : Ext.NET License key
- scriptMode: 指定javascript代碼呈現方式。
默認值: "Release". 可選項有Release
、Debug
、Development
- Release (壓縮過的)
- Debug(不壓縮)
-
Development(非壓縮且帶debug信息) 經驗證,此項不可用
- sourceFormatting : 是否格式化EXT.NET生成的javascript代碼
默認值為 is ‘false‘. 可選項有 [true|false] - theme : 默認主題樣式
默認值為"Default" (經典的藍色主題). 可選項有Default
、Access
、Gray
、Neptune
、Neptune Touch
、Crisp
、Crisp Touch
- sourceFormatting : 是否格式化EXT.NET生成的javascript代碼
開始之前
模板窗體
新建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文件的引用。
為javascript代碼添加EXTJS代碼提示
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文檔。
CSS說明
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" />
布局(Layout)
前面說過,EXT.NET
基本沒有對設計時可視化支持的,這也是新手常常遇到的問題,在 官方示例 中,已經有詳盡的示例代碼,認真閱讀官方示例,常見的布局問題都可以應付。
EXTJS
有Sencha Architect提供了設計時的支持,不過生成的是純js代碼。
EXT.NET
官方示例Layout節點中有各種布局的詳細代碼例子,如下
大致說明下:
- AbsoluteLayout: 絕對,指定控件的X和Y值(像素);
- AccordionLayout: 折疊式布局,常用於頁面菜單之類;
- AnchorLayout: 配置高度和寬度,值可以是百分比(1-100%)或偏移量(正/負整數),詳細說明參見 Anchor Layout的源碼;
- BorderLayout: 以邊框方式劃分區域,通常用於整個頁面(容器內部也可以用)的布局,如官方示例的首頁就是這種布局;
- CardLayout: 卡片式布局,常用於需要上一步&下一步的向導頁。
- CenterLayout: 始終居中,這個是3.x新加的功能,比較有用。
- ColumnLayout: 列式布局,用
ColumnWidth
指定所占寬度比例(0到1之間的小數),同級別的容器加起來為1就行,可以和Width
一起使用,詳見示例。 - FitLayout: 鋪滿,若A容器的
Layout
屬性為FitLayout
時(寫成Fit
也能解析),其內部容器將鋪滿A的大小; - FormLayout: Form布局,提供了常用From的特殊功能,通常編輯功能用到;
- HBoxLayout: 橫向布局,示例中用的是Button,如Panel、FormPanel、Container等容器都可以用;
- TableLayout: 表格式布局,沒怎麽用過這個;
- VBoxLayout: 縱向布局,其余同HBoxLayout。
請參考Sencha官方API文檔中關於各種Layout的詳細說明。
EXT.NET或者說EXTJS提供的布局方式大致就這麽多,可以根據需要組合使用,後面用到時做詳細介紹。
基本容器簡介
Container
最基本的容器,相對Panel來說,更為輕量,當僅僅需要將其它控件按照一定的方式布局時使用。
Container也是Sencha建議的布局方式。
關於Container詳細說明請參見Ext.container.Container
Panel
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
FormPanel一般用來做編輯界面,大部分功能與Panel相同,不同的是,它為其包含的Field提供了一些很方便實用的功能,如reset
、loadRecord
等方法,後面再細說。
關於FormPanel詳細說明請參見Ext.form.Panel
GridPanel
最為常用、最多插件、功能最多(復雜)的容器控件,沒有之一。
用到的時候再來細說,先來看看它提供的功能:
- 排序;
- 查詢;
- 編輯;
- 分頁;
- 分組顯示;
- 統計;
- 顯示/隱藏列;
- 列順序調整;
- 各種列類型的支持,文本、數字、布爾、日期、進度條、自定義等等;
- 各種插件等等;
關於GridPanel詳細說明請參見Ext.grid.Panel
AJAX事件/方法
為演示使用,請先添加Person.cs類,代碼如下
namespace WebFormDemo
{
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public string Desc { get; set; }
}
}
DirectEvents
一般用在客戶端通過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
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
Listener表示客戶端事件(Extjs本身提供),調用客戶端javascript方法。
上面的DirectMethod示例代碼中
<Listeners>
<Click Fn="btnMe_Click" />
</Listeners>
就表示一個Click事件,並調用javascript中的btnMe_Click
方法。
- Listener的支持事件列表及參數
- 更多示例
作者自2010年的 Coolite 時代開始,幾乎所有.NET Web項目中使用 Ext.NET ,這篇文章算是表達對他們的一點敬意。
Ext.NET