1. 程式人生 > >Ext.NET

Ext.NET

firefox 相同 onf thread frame 排序 快捷 覆蓋 代碼下載

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.1Ext.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呢?

  1. 一整套專業的前端框架,兼容各種主流瀏覽器(甚至IE6),很少需要引入第三方庫,降低了學習成本;
  2. 減少了javascript的代碼量,易於維護,同時又不失ExtJs的靈活性;
  3. 提供的DirectEvents和DirectMethod,使調用服務器端方法更為簡單;
  4. 使ASP.NET開發人員更容易理解和使用ExtJS;

總之,減少了工作量,降低了學習成本;不過在實際的使用中,還是需要寫一些簡單的javascript代碼。

關於ExtJS這裏不多介紹,其提供的多種主題樣式,尤其適用於企業應用開發,很少需要美工的介入,這一點對於小型團隊來說,尤其缺少專業美工的情況下,頗為實用。
關於請參見Sencha官方博客,其中有Extjs與AngularJS的比較。

開發環境配置

官方的Readme以及Visual Studio配置說明已經說的很清楚了,兩種方法: 自動配置 和 手動配置。

至於添加到VS工具箱拖拽控件至頁面,基本沒用,還是省省時間吧,Ext.NET基本沒有對設計時可視化支持的,這也是入門較難的原因之一。

自動配置(推薦)

使用NuGet,新手推薦使用這種方式,因為——簡單
方法如下:

  1. 打開Visual Studio,菜單欄 工具 > 擴展和更新,安裝 NuGet程序包管理器,通常,VS2013已經自動安裝了,若沒有,左側點 聯機,右上方搜索框中輸入 NuGet ,具體安裝過程 參見此處,安裝完成會需要重啟VS。
    若是搜不出來,改DNS/FQ/VPN/改Host文件等問度娘。
  2. 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 (測試頁面)可以刪除。

手動配置

  1. 下載DLL文件;
  2. 項目中添加對DLL的引用;
  3. 配置 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". 可選項有 ReleaseDebugDevelopment
  • Release (壓縮過的)
  • Debug(不壓縮)
  • Development(非壓縮且帶debug信息) 經驗證,此項不可用

    • sourceFormatting : 是否格式化EXT.NET生成的javascript代碼
      默認值為 is ‘false‘. 可選項有 [true|false]
    • theme : 默認主題樣式
      默認值為"Default" (經典的藍色主題). 可選項有 DefaultAccessGrayNeptuneNeptune TouchCrispCrisp 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文件的引用。

為javascript代碼添加EXTJS代碼提示

Web項目開發,無法避免編寫javascript腳本,VS提供的Intellisense方便快捷,如何添加javascriptEXTJS的代碼提示支持?
在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>

說明:

  1. Layout="HBoxLayout"定義pnlMain內部控件使用HBoxLayout布局;
  2. Width="300" Height="200"定義pnlMain的寬度和高度,通常使用中不建議這樣寫;
  3. <LayoutConfig></LayoutConfig>中的<ext:HBoxLayoutConfig Align="Stretch" />定義pnlMain內部控件縱向拉伸;
  4. <TopBar></TopBar>定義pnlMain中頂端的工具條,其中包含了新建和保存按鈕;
  5. <Buttons></Buttons>定義pnlMain包含兩個按鈕;
  6. <Items></Items>定義pnlMain所包含的子控件,可以是EXT支持的任意容器或Form控件

關於Panel詳細說明請參見Ext.panel.Panel

FormPanel

FormPanel一般用來做編輯界面,大部分功能與Panel相同,不同的是,它為其包含的Field提供了一些很方便實用的功能,如resetloadRecord等方法,後面再細說。

關於FormPanel詳細說明請參見Ext.form.Panel

GridPanel

最為常用、最多插件、功能最多(復雜)的容器控件,沒有之一。
用到的時候再來細說,先來看看它提供的功能:

  1. 排序;
  2. 查詢;
  3. 編輯;
  4. 分頁;
  5. 分組顯示;
  6. 統計;
  7. 顯示/隱藏列;
  8. 列順序調整;
  9. 各種列類型的支持,文本、數字、布爾、日期、進度條、自定義等等;
  10. 各種插件等等;
    關於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請求。

  1. 客戶端點擊按鈕觸發服務器端事件,並傳遞兩個參數;
  2. 服務器端執行完成後返回執行結果,根據結果顯示提示信息;

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中調用服務器端方法提供了很方便的一種調用方式。

  • 服務器端方法必須定義為publicpublic 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