請下載本文的代碼: Longhorn.exe (113KB)
注:本文是在產品的發行版投入生產之前完成的,因此,我們不能保證這里包含的任何細節與發行產品中找到的細節完全一樣。文中對產品的描述信息僅限于本文發表時的產品,并且僅用于規劃方面的用途。本文的信息隨時可能更改,恕不預先通知。
摘要 下一個版本的 Microsoft Windows 操作系統(代號為 "Longhorn"),它不僅標志著操作系統工作方式的重大改變,而且標志著應用程序構建方式的重大改變。Longhorn 版本的 Windows 包括一個新的存儲系統和自然搜索技術,而且更加強調安全機制和可信計算。作者在本文提供了 Longhorn 的概述,討論的重點是一次構建、可部署 n 次的應用模型。此外,他還討論了代號為 "XAML"、用于創建 UI 元素的新語言,然后提供了一些操作示例。
Longhorn 應用模型 | |
理解 Longhorn 應用程序 | |
XAML 語言 | |
構建應用程序示例 | |
結論 |
從許多方面來看,代號為 "Longhorn" 的下一版 Microsoft? Windows? 操作系統都是一個重要的里程碑。"Longhorn" 是第一個用托管代碼構建的操作系統,而且首次采用了最新的存儲子系統(代號為 "WinFS"),這種存儲系統是文件系統概念的一次革命。它還是第一個支持自然搜索技術 (Natural UI) 的操作系統,這種技術自動解決了查詢文本固有的許多多義性問題。此外,Longhorn 是第一個以安全機制和可信計算為核心從頭設計的操作系統。上述信息以及其他特性都表明,Longhorn 將改變應用程序構建的方式 — 這可不是每天都能發生的事情。自從 Windows 問世以來,我記得曾經出現過兩個同樣重要的里程碑 — 一個是 Windows 由 16 位向 32 位的遷移,另一個是 Microsoft .NET 框架的托管環境的誕生。
Longhorn 中最為重要的一個改變是,這種操作系統使應用程序可以一次編碼,在多個部署方案中使用。為了實現這個偉大的目標,基于 Longhorn 的應用程序是完全面向對象的,整個應用建立在一個核心對象 Application 之上,該對象提供了運行應用程序所需的所有關鍵服務。本文將帶領讀者在一定深度上體驗 Longhorn 應用模型,并將它應用于幾個基本示例,其中包括經典的 Hello World 應用程序。
Application 對象是 Longhorn 應用模型的核心。通過該對象的一整套屬性、方法和事件,您可以使用標記頁集合 — 一種增強版本的 HTML — 來編寫一致而典型的 Windows 應用程序。Application 對象是 Longhorn 提供的根應用程序對象。它提供了基本的應用程序支持,通常用于那些需要低開銷并且不使用頁導航和狀態管理的應用程序。更復雜的 Longhorn 應用程序將使用密切相關的 NavigationApplication 對象,該對象是從 Application 繼承的,但增加了對導航的支持。
一個典型的 Longhorn 應用程序可以視為一組用某些過程代碼編寫腳本的頁。Application 對象控制著程序的執行,并向用戶代碼產生事件。頁使用一種新的聲明標記語言來編寫,這種語言的代號是 "XAML"(可擴展應用程序標記語言)。利用 XAML 元素,您可以控制每個頁的布局,包括文本和圖像的顯示、插入按鈕、文本框等交互式組件??傊?,XAML 是用于以聲明方式呈現構成應用程序的頁的用戶界面的語言。當然,除了使用 XAML,您也可以完全使用過程代碼來編寫 Longhorn 的應用程序。一般來說,一個基于 Longhorn 的成功的應用程序會同時具備 XAML 頁和托管過程代碼。您可以按自己的方式來組合它們,但這兩者的任何組合都是可以接受的。
通過結合使用 XAML 和 C#(或 Visual Basic? .NET)代碼,您可以構建各種類型的輸出文件,包括傳統的 Windows 桌面可執行文件、DLL 庫或控制臺應用程序。而且,如果您的應用程序足夠簡單的話,也可以使用獨立的 XAML 標記來編寫它。這樣,在 Longhorn 中就增加了另一種類型的應用程序。只要獨立的 XAML 文件不引用代碼隱藏類,它就可以在 Longhorn Shell(外殼程序)和瀏覽器中運行。最后要說明的是,Windows 可執行文件既可以運行在一個窗口中,也可以運行在瀏覽器中。在這兩種情況下,代碼保持不變,只要以不同的項目屬性重新編譯一遍就可以了。
對于 Longhorn,桌面可執行文件是今天的 Windows 窗體客戶端應用程序的下一個版本。但從另一方面來說,XAML 以及以瀏覽器為宿主的應用程序也代表了如今在 Web 上進行客戶端編程模型的一次革新。目前,現有的客戶端應用程序很少部署到 Web 上。如果您要將 Windows 窗體嵌入瀏覽器頁,原來的特性會有所減少,您還必須對代碼做相應的修改。而在 Longhorn 中,通用應用模型使您可以編寫一個程序,然后在 Web 上部署。不過,最終的應用程序是特定于 Longhorn 的,與傳統的 Web 應用程序(如 ASP.NET)有很大的不同。
當您編譯一個應用程序時,代號為 "Whidbey" 的下一個版本的 Visual Studio? 和 .NET 框架(或底層的 MSBuild.exe 工具)會產生一個 .exe 文件、一個應用程序清單(擴展名是 .manifest)和一個部署清單(擴展名是 .deploy)。如果單擊 .exe 文件,應用程序會像您期望的那樣開始運行。但如果將應用程序設置為在瀏覽器中運行,則單擊 .exe 文件后,會啟動 Internet Explorer 的一個實例,并在其中運行該應用程序。還有一種可選的方式是,從遠程服務器部署應用程序。完成部署的步驟如下。首先,將部署清單文件復制到服務器的適當位置??梢允?FTP 路徑或 HTTP 路徑。然后,將編譯后的應用程序文件和清單復制到服務器上的適當位置。部署清單、應用程序的文件及清單在服務器端的位置不一定相同。如果它們放在不同的位置,您可以手動編輯部署清單,使它指向應用程序清單的位置。清單文件都是普通的 XML 文件。當用戶使瀏覽器指向指定的部署位置時,Longhorn 會自動下載應用程序及其清單,然后將它們安裝在客戶端計算機上,同時還創建一個指向 .deploy 文件的快捷方式。最后,用戶單擊 .deploy 文件就可以運行應用程序。
所有 Longhorn 都有一個共同的結構 — 帶有過程代碼的 XAML 頁(內聯或者使用代碼隱藏)— 根對象派生于 Application。Application 對象充當控制器;它的生命周期與應用程序的生命周期是一致的。通過 Application 對象,您可以處理高級事件,有時可以在頁之間共享代碼和狀態。它還負責根據應用程序的邏輯讓用戶在頁之間導航。在一個典型的 Longhorn 程序中,用戶先執行任務,然后通過從一個頁導航到下一個頁在應用程序中前進。導航通常通過用新的頁替代舊的頁來實現。不過,您也可以選擇打開一個新的彈出式窗口來顯示新的頁。導航并不是所有 Longhorn 應用程序所必需的;只包括一個頁的簡單應用程序就不需要導航。
剛剛提到,除了標記元素,XAML 頁還可以包含過程代碼。過程代碼是必需的,例如,用于處理由頁上的一個 XAML 元素產生的事件。過程代碼既可以內嵌到 XAML 文件的正文中,也可以放在單獨的代碼隱藏文件中。
Longhorn 中的編程基于托管代碼。不過,只有幾種與 .NET 兼容的語言可用于編寫基于 XAML 的應用程序。目前,這類語言包括 C#、Visual Basic .NET 和 JScript? .NET。到 Longhorn 發布時,其他與 .NET 兼容的語言也將包括進來。目前只能使用這三種語言的原因是,XAML 文件的源代碼必須即時分析和編譯,因此,編譯器和相關的文檔對象模型必須提前就緒。不過,需要注意的是,如果完全使用過程代碼編寫應用程序,您可以使用任何與 .NET 兼容的語言,它們都具備有效的編譯器。注意,基于 XAML 的應用程序只能使用這三種語言。如果 XAML 頁中嵌入了過程代碼,那么您必須先編譯應用程序,然后才能運行它;如果 XAML 頁中沒有過程代碼,那么雙擊就可以顯示它,就像 HTML 網頁那樣。Longhorn 不處理未編譯的代碼,也不能即時編譯代碼。您一定迫不及待地希望看到 Longhorn 版本的 "Hello World" 應用程序是什么樣子吧? 下面是一個您可以編寫的最簡單的 XAML 代碼的示例:
clearcase/" target="_blank" >cccccc>
<Canvas xmlns="http://schemas.microsoft.com/2003/xaml" Background="LightCyan" Width="100%" Height="100%"> <Image Source="lh.bmp" Canvas.Left="5" Canvas.Top="5" /> <Text Canvas.Left="90" Canvas.Top="20" FontSize="36">Hello, Longhorn! </Text> </Canvas> |
將這段代碼保存在文本文件中并用 .xaml 作為擴展名,然后用 Longhorn 瀏覽器指向該文件或者在外殼程序中雙擊該文件即可。圖 1 顯示了結果。<Canvas> 節點定義了應用程序的用戶界面區域 — 基本上,相當于畫布。Background 屬性指定了該區域的背景色,Width 和 Height 則指定了表面的大小。<Image> 和 <Text> 元素定義了該頁的內容。這兩個元素使用父級 Canvas 對象的 Left 和 Top 屬性定義了它們的絕對位置。
返回頁首Longhorn 提供了一組擴展和增強 .NET 框架 1.1 的框架類。Longhorn 中的擴展包括:XAML 支持、存儲系統、應用模型、可信計算和高級 Web 服務等。在 Microsoft 的路線圖計劃中,Longhorn 和 Whidbey 代表了兩個截然不同的里程碑。Whidbey 預期將比 Longhorn 提前幾個月發布,因此,當 Longhorn 發布時,將包括 Whidbey 的升級版本,以提供 Longhorn 中的核心服務。
我們再來看看所有 Longhorn 應用程序共同的基礎 — XAML 語言。XAML 語言是一種基于 XML 的語言,它專門用于描述應用程序的用戶界面。熟悉 Win32? 和 .NET 框架的程序員可以看出 XAML 標記和傳統的 Windows 控件之間明顯的相似之處。不過,相比全套 Win32 公共控件或 Windows 窗體控件,XAML 標記更抽象,范圍也更廣。為了迅速理解 XAML 代表的含義以及您應該怎樣看待 XAML,可以想想 ASP.NET 頁?;蛘?,更具體一點,您可以想像某個只有服務器端控件 (runat="server") 的 ASP.NET 頁,就無需用文字解釋了。
每一個 XAML 標記都對應一個 .NET 框架類,并包括許多方法、屬性和事件。您可以直接在 XAML 腳本中以聲明的方式來設置屬性和編寫事件,也可以使用封裝到代碼隱藏類的過程代碼。隱藏在每個標記后面的控件在運行時進行實例化,并得到屏幕上的一個區域,以便在上面呈現其輸出。從最高的抽象級別來看,該模型非常像 ASP.NET,只不過這個模型經過抽象后,可用于一般的、更豐富的 Windows 平臺。
XAML 中的每個元素都使用一個基礎類,但許多類沒有對應的 XAML 元素。這些類常常是抽象類,它們大多被用于繼承。用 XAML 創建的任何東西都可以用過程代碼來創建。例如,要用 XAML 創建一個按鈕元素,可使用下面的代碼:
<Canvas xmlns="http://schemas.microsoft.com/2003/xaml"> <Button Canvas.Left="10" Canvas.Top="10" Width="90px" Height="32px"> Click Me</Button> </Canvas> |
也可以用下面的 C# 過程代碼創建一個一模一樣的按鈕:
Button btn = new Button(); btn.Width = new Length(90); btn.Height = new Length(32); Canvas.SetTop(btn, new Length(10)); Canvas.SetLeft(btn, new Length(10)); btn.Content = "Click Me"; |
在 XAML 文件中,您不能使用方法,但可以設置屬性 (attribute)。XAML 中的 attribute 通常與類的 property(屬性)相對應,但類的幾個 property 并沒有對應的 XAML attribute。您可以逐個設置類屬性或使用樣式表。樣式表是樣式屬性的集合,編譯器會將它自動應用到使用該樣式表的控件。所有 XAML 頁都至少有一個 panel 元素,它充當窗體容器,并控制子內容的位置以及背景色和字體等全局屬性。XAML 頁的元素是以層次結構組織的,只有一個根元素。通常,這個根元素是 Panel 派生的類,如 DockPanel 或 Canvas,或是 Decorator 派生的類,如 Border。Canvas 元素用于根據絕對坐標來確定內容的位置。一般來說,每個元素被繪制在不同的位置;如果兩個以上的元素被繪制在相同的坐標上,元素在標記中出現的順序將決定它們的繪制順序。
除了屬性和方法,XAML 元素還支持許多事件。通過創建事件處理程序,您可以使頁動態地響應各種通知。創建 Longhorn 事件處理程序并關聯到元素的方法與您如今在基于 .NET 的應用程序中使用的方法幾乎是一樣的。事件處理程序通過一個屬性來聲明,然后,處理程序通過代碼隱藏類集成到應用程序中:
<Button Width="90px" Height="25px" Click="OnHandleClick"> Click Me </Button> |
頁中的元素形成了應用程序樹,這是一個包括了應用程序的所有運行時組件的對象模型,并且可以通過代碼訪問。每個控件都提供了自己的訪問子級的方法。主要模式有:panel.Children.Add(element)、listbox.Items.Add(object)、button.Content = object 和 textbox.TextRange.Text = string。
支持子級的控件還支持作為子級的任意對象 — 字符串、元素,或某個完全隨機的對象(在這種情況下可調用 ToString)。每個控件都有一個 Parent 屬性,用于訪問它在樹中的父級。注意,訪問該樹的各個屬性只返回直接的子級,而不是子代。利用對象模型,您可以自如地操縱頁上元素的每個方面。它還提供了一些無法通過 XAML 實現的額外功能。例如,您可以動態地創建元素,但還可以根據運行時條件即時創建元素。
為了更清楚地說明這一點,我們來看第二個應用程序示例。正如前面提到的,任何規范的 Longhorn 應用程序都包括過程代碼以及 XAML 腳本。我們將討論一個比最初的 Hello World 應用程序更復雜的情況,并且處理一些事件。
圖 2 顯示了一個新的應用程序的所有源代碼,其中,XAML 被綁定到代碼隱藏類中存儲的某些過程代碼。如果將 XAML 解決方案與 ASP.NET Web 窗體頁進行比較,除了語法不同之外,您很難發現任何明顯的區別。def:CodeBehind 和 def:Class 屬性封裝 C# 代碼的方式與 Visual Studio 代碼隱藏類封裝 ASP.NET 代碼的方式也非常相似。我們來命名 圖 2 events.xaml 中的 XAML 文件,并且命名也出現在 圖 2 events.xaml.cs 中的代碼隱藏類。如果您將瀏覽器指向該文件,就會產生一個運行時錯誤,如圖3所示。該錯誤消息在我使用的內部版本中不是很清楚,但錯誤的原因非常明顯。該錯誤一定與 XAML 代碼不能被動態編譯有關。與 ASP.NET 不同的是,Longhorn 要求您顯式編譯任何嵌入的或只是由 XAML 腳本引用的過程代碼。這一特性可能會在未來的內部版本中有很大的變動,但在目前,它使您不得不在 Visual Studio 中管理 Longhorn 項目文件?;蛘?,您的另一個選擇是,去熟悉 MSBuild,它的可執行文件是 msbuild.exe。Longhorn 解決方案和項目文件的擴展名和結構與 Visual Studio 2003 中是一致的。Longhorn 項目文件大體上如 圖 4 中列出的代碼所示。
圖 3 XAML 錯誤
項目文件包含有關項目的重要信息。<Project> 標記指明了編譯器必須生成的包的類型。項目屬性和項集中在嵌套標記中 — <ProjectGroup> 和 <ItemGroup>。每個元素的名稱都很易于理解。項目文件在命令行中被傳遞到 msbuild.exe 實用程序。MSBuild 駐留在 Windows\ Microsoft .NET 下的 Framework 文件夾中。下面的簡單命令生成一個基于 Events.proj 項目文件的可執行文件:
msbuild.exe Events.proj |
除非您希望實踐一下 MSBuild 工具,否則,您不必過于關注它。前面提到,Whidbey 版本的 Visual Studio 與 Longhorn SDK 高度集成,只要單擊工具欄按鈕或按一下 F5 就可以構建 Longhorn 應用程序。圖5顯示了 圖 2 中的代碼的運行效果。在應用程序樹中,只有一個上面有文字的藍色面板是可見的。應用程序樹其實比您在圖5中看到的要稍微復雜一些。根節點是一個包含 DockPanel 對象的窗口。DockPanel 是所有用戶界面元素最外層的容器,它包含一個子級 — FlowPanel,FlowPanel 又包含一個 Text 對象。文本由 Text 類的一個實例來表示。您應該已經注意到,XAML 標記有幾個屬性用于控制其顯示。更重要的是,這些標記支持 ID 屬性,ID 屬性提供了運行時標識。只要您在被分配給控件的區域內單擊鼠標,與 FlowPanel 類相關聯的 MouseLeftButtonDown 事件就會觸發。此時,將調用 OnLeftMouseDown 事件處理程序代碼。流動面板的寬度和高度變成了原來的兩倍,文字也隨之改變。再次單擊鼠標,面板又恢復為原來的大小。
圖 5 運行應用程序
雖然您也可以完全使用過程代碼編寫應用程序,但 XAML 文件使應用程序用戶界面的描述和模板化簡單得多。
返回頁首XAML 語言由四個主要類別的元素構成 — 面板、交互控件、與文檔相關的元素以及圖形。Border(邊框)元素雖然不屬于上述四個類別中的任何一類,但它也很重要。從技術角度來說,它相當于負責細節布局的“裝修工人”,只包含一個子級,但添加了繪制效果。在 XAML 中,面板負責頁面布局,并充當其他元素的容器。面板是管理所包含的元素的繪制、大小和位置、內容安排的組件。Longhorn 中有六個內置的面板類,但開發人員可以用自定義繪制行為來創建自己的面板。預定義的面板包括:Canvas、DockPanel、FlowPanel、GridPanel、Table 和 TextPanel。 圖 6 中描述了這些面板類型。
Canvas 面板是預定義面板中唯一支持顯式定位的。它所有的子元素從一個固定的位置開始繪制,延長指定的尺寸。如果兩個元素重疊,后繪制的那個將覆蓋下面的區域。注意,坐標是相對于畫布的,這意味著,(0,0) 表示區域的左上角像素。下面是一個畫布對象的示例:
<Canvas xmlns="http://schemas.microsoft.com/2003/xaml" Height="600" Width="800"> <Border Background="red" Canvas.Top="0px" Canvas.Left="0px" Height="100px" Width="100px" /> <Border Background="green " Canvas.Top="100px" Canvas.Left="100px" Height="100px" Width="100px" /> <Border Background="blue" Canvas.Top="50px" Canvas.Left="50px" Height="100px" Width="100px" /> </Canvas> |
DockPanel 組件以不同的方式發展出相同的包容概念。這種面板的所有子級都水平或垂直地相互??吭谝黄?。在這種情況下,定位是相對于前一個控件的,并且根本不需要坐標。DockPanel 是創建顯示效果像工具欄這樣的按鈕條的理想選擇。下面是一個示例:
<Border xmlns="http://schemas.microsoft.com/2003/xaml" Background="black" > <DockPanel> <Button DockPanel.Dock="Left" Width="50px" Height="32px"> Open </Button> <Button DockPanel.Dock="Left" Width="50px" Height="32px"> Save </Button> <Button DockPanel.Dock="Left" Width="50px" Height="32px"> </Button> </DockPanel> </Border> |
第一個按鈕位于面板的最左側,其他每個按鈕都按水平方向排列在前一個按鈕的旁邊(請參見圖7)。
圖 7 按鈕布局
FlowPanel 元素使子組件以各種方向在可用的區域中流動。該面板還包含可處理內容超出面板寬度的情況的邏輯。在這種情況下,根據對象的配置,超出部分的內容可以折疊顯示在下一行或被截掉。下面的 XAML 示例說明了 FlowPanel 如何中斷內容并使內容折行顯示(這種內容在邏輯上已經設計為適合單個行)。在這個示例中,四個方形的元素包含在一個更大的元素中。這四個方塊的寬度之和大于容器的寬度。因為所有小方塊不能在一行顯示,這四個方塊被截斷,最后一個方塊在第二行顯示。注意,該面板默認的方向是:從左到右,從上到下:
<FlowPanel xmlns="http://schemas.microsoft.com/2003/xaml" Width="250px" Height="250px"> <Border Background="red" Width="75px" Height="75px" /> <Border Background="green" Width="75px" Height="75px" /> <Border Background="blue" Width="75px" Height="75px" /> <Border Background="orange" Width="75px" Height="75px" /> </FlowPanel> |
GridPanel 是一個開銷不大的元素,它用類似網格的方式安排對象的布局,從而構建出一個相對比較簡單的表。通過 GridPanel,您可以在行和列上任意放置控件,構成一個矩陣,但總的來說,它的功能還是很有限的。要構建具有高級功能的更復雜的表,您可以使用 Table 面板。Table 面板的結構是由多組行構成的。您可以為頁眉或頁腳定義一組行,還可以插入多組具有不同設置的行。利用該面板的布局功能,您可以為數據創建非常復雜的表格式表示形式。
最后,如果需要復雜的文本布局支持,TextPanel 是一個理想的選擇。不過,對于基本的文本支持,Text 元素是一個更好的選擇,因為它的開銷更?。ó斎?,功能也更少)。
MSAvalon.Windows.Controls 命名空間集中了所有負責用戶交互的用戶控件。屬于此命名空間的類都是您很熟悉的類:Button、ComboBox、ListBox 和 CheckBox,但也有一些新成員,如 ContextMenu、PageViewer 和 RadioButtonList。用戶交互式元素的基類是 Control,它提供了一組公用的屬性和方法。
圖 8 頁面查看器
比較特別的是,PageViewer 控件提供了用于查看在線文檔的用戶界面,并且包含分頁和頁導航功能。下面的示例生成了一個頁面查看器(如圖8所示),它占據了整個工作區。該頁面查看器將 PageViewer 標記的 Source 屬性中指定的文件中的文本分頁并顯示出來:
<DockPanel ID="root" xmlns="http:// schemas.microsoft.com/2003/xaml" xmlns:def="Definition"> <Text DockPanel.Dock="Top"> See a PageViewer control in action below. </Text> <PageViewer DockPanel.Dock="Top" Source="Sample.xaml" Height="80%" Width="80%"/> <Button DockPanel.Dock="Top" Width="50%">OK</Button> </DockPanel> |
有意思的是,通過 PageViewer 控件查看的源文件不能是純粹的文本、RTF 或 HTML。至少在目前,它必須是包含無格式 ASCII 文本、由支持分頁的 Avalon 控件封裝的 XAML 文件。Avalon 是 Longhorn 中新的表示子系統的代號(請參見 Charles Petzold 在本期撰寫的文章)。例如,我們來看看 TextPanel 類:
<TextPanel ID="root" xmlns="http://schemas.microsoft.com/2003/xaml"> text to show goes here </TextPanel> |
將上面的代碼片斷保存到 sample.xaml,以便運行前面的示例。記住,xmlns 命名空間是必需的。
MSAvalon.Windows.Documents 命名空間中的類負責文檔的顯示。這些類合在一起,看上去像是高級 HTML 標記的超集。其中包括的類有:Block、Column、Heading 和 Footer,以及 ColumnGroup、RowGroup、HyperLink、List 等等。
您在前面看到的 Text 類屬于這個預發布版本的 Longhorn 的 System.Windows.Controls 命名空間。Text 類支持多行和各種文本格式設置規范,包括粗體和斜體、字體大小,以及嵌套子元素。在所需文本相對比較簡單的情況下,Text 就是理想的類,因為它開銷較小,功能全面。 Longhorn 表示模型通過使用 XAML 面板元素來繪制圖形。面板提供了許多大小和對齊方面的屬性,并且可以控制邊界、背景色和填充。
Longhorn 使用 Windows 矢量圖形 (Windows Vector Graphics) 來繪制圖形內容,它與 GDI 和 GDI+ 相比有許多優點。Windows 矢量圖形是一個基于 XML、便于使用和重用的圖形標記系統。如果您是可縮放矢量圖形的愛好者,您一定也會癡迷于 Windows 矢量圖形。Windows 矢量圖形提供了預定義的形狀,包括 Ellipse、Line、Path、Polygon、Polyline 和 Rectangle,它們都是從 Shape 類繼承的。這些元素從 Shape 那里繼承了許多共有的屬性,包括 Stroke 和 StrokeThickness,以及 Fill,再加上一些用于指定坐標和頂點的屬性。通過進行變形,形狀可以扭斜、旋轉、平移和縮放。除了可以為形狀指定純色填充色和背景,您還可以指定漸進色。下面的示例將水平漸進色設置為一個 Rectangle(矩形)形狀的 Fill 屬性,將 Red(紅色)設置為起始色,將 Blue(藍色)設置為最終過渡到的顏色:
<Rectangle xmlns="http://schemas.microsoft.com/2003/xaml" Canvas.Top="10" Canvas.Left="10" Fill="HorizontalGradient Red Blue" RectangleLeft="0" RectangleTop="0" Width="50" Height="50"/> |
您可以使用 XAML 語言迅速有效地構建一個用戶界面的原型。我敢保證,到 Longhorn 發布時,許多開發工具將會更新(或從新構建),以完全支持具有所見即所得特性的 XAML。Longhorn 的技術預覽版已經包括了一些到 Whidbey 版本的 Visual Studio .NET 的擴展。下面我們來看一個更規范的交互式應用程序。您很快就會發現,這與編寫 Windows 窗體應用程序并沒有太大的不同,而且,您將驚喜地發現,您目前已經掌握的 .NET 技巧可以很好地應用于 Longhorn。如圖9所示,您可以看到一個很小的應用程序示例的用戶界面,界面中包括一個文本框和一個上下文菜單。文本框是使用 XAML 定義的;上下文菜單是動態創建的。該應用程序的全部源代碼顯示在 圖 10 中。
圖 9 上下文菜單
在 Longhorn 中,所有應用程序都由 Application 類的一個實例來表示。此對象是 Longhorn 應用模型的核心。不過,Application 對象只提供基本的應用程序支持,通常只有那些需要低開銷并且不使用導航功能的應用程序才使用該對象。實際上,大多數 Longhorn 應用程序使用密切相關的 NavigationApplication 對象,該對象是從 Application 繼承的,并增加了對導航的支持。
NavigationApplication 對象支持各種方法、屬性和事件,它們使您能夠將大量 XAML 頁組合到一個應用程序中。在某種意義上,基于更簡單的 Application 類的 Longhorn 應用程序是可以與基于對話框的 Win32 應用程序進行比較的。同樣,您可以將支持導航的應用程序與完整的 Win32 應用程序進行比較,在這樣的 Win32 應用程序中,各種窗口和窗體共同形成了應用程序的整體功能。下面的代碼顯示了這種導航功能的示例:
myApp = NavigationApplication.Current; win = (Navigation.NavigationWindow) myApp.Windows[0]; ??? private void Button_Back(Object sender, ClickEventArgs e) { // If possible, go to the previous window if(win.CanGoBack()) win.GoBack(); } |
您可以通過使用 Application(或 NavigationApplication)導航對象上的靜態屬性 Current 獲得對應用程序對象的引用。前面的示例還說明了如何獲得對堆棧中第一個窗口的引用。Button_Back 事件處理程序檢查前一個窗口對象是否存在,如果存在,就以一種類似瀏覽器的方式跳回它那里。
下一個示例將說明如何通過派生一個新的類并覆蓋 OnStartingUp 方法來定制導航應用程序啟動時的行為。下面的代碼片斷覆蓋了 OnStartingUp,在應用程序啟動時創建并顯示一個導航窗口:
public class MyApp : NavigationApplication { NavigationWindow win; ??? protected override void OnStartingUp(StartingUpCancelEventArgs e) { win = new NavigationWindow(); // Add elements to the window ??? navWin.Show(); } ??? } |
讓我們再回到圖9中顯示的應用程序示例。根據我剛剛討論的理由,您可以使用 Application 或 NavigationApplication 作為基類,因為該應用程序將使用一個單窗口、基于對話框的應用程序。正在運行的、名為 Sample1 的類覆蓋了 OnStartingUp,并定義了好幾個事件處理程序。覆蓋 OnStartingUp 方法是必需的,因為它表示應用程序啟動的初始化步驟,因此,是在窗口打開之前執行您自己的操作的理想地點。
在 OnStartingUp 中完成的操作就是窗口的創建。窗口的內容在 XAML 文件及其代碼隱藏類中描述。XAML 頁本身是由控件和其他組件構成的,它們被組織在一個具有層次結構的樹中。正是這些不同的組件(稱為元素)之間的關系在很大程度上說明了頁如何呈現和表現。 圖 9 中的示例頁包括一個 TextBox 控件,該控件具有給定的大小和字體。這個文本框被綁定到 ContextMenuEvent 事件。只要用戶右擊控件的工作區,就立即觸發該事件。
事件處理器將創建一個 ContextMenu 對象(請參見 圖 10 )。上下文菜單經過填充、以圖形方式配置后,就綁定到它的父對象 — TextBox。毫無疑問,在 Longhorn 中,通過選擇背景色和前景色、邊框和字體,您可以輕松地自定義菜單的外觀(以及所有控件的外觀)。如果您認為以前版本的 Windows 和 .NET 框架也有可能完成同樣的任務,那您就錯了。在 Win32 中,這種自定義需要許多編程工作,一點也不簡單。而在 .NET 框架中,包裝類封裝了必要的代碼,只留下很少的屬性供用戶控制。另一方面,在 Longhorn 中,控件的用戶界面就像它看上去那樣簡單。
上下文菜單的元素是從 MenuItem 類創建的。使它們觸發事件處理程序的方式幾乎與基于框架的應用程序完全一樣:
mia = new MenuItem[3]; for (int i=0; i<3; i++) { mia[i] = new MenuItem(); cm.Items.Add(mia[i]); mia[i].Foreground = Brushes.Black; } mia[0].Header = "Lower Text"; mia[1].Header = "Upper case"; mia[2].Header = "Select all"; mia[0].Click += new ClickEventHandler(LowerCase); mia[1].Click += new ClickEventHandler(UpperCase); mia[2].Click += new ClickEventHandler(SelectAll); |
當某個菜單項被單擊后,立即執行事件處理程序,并使用傳遞的第一個參數來檢索對其源對象的引用:
public void LowerCase(Object sender, ClickEventArgs args) { MenuItem mi = (MenuItem) args.Source; ContextMenu menu = (ContextMenu) mi.Parent; TextBox thisTextBox = (TextBox) menu.PlacementTarget; thisTextBox.Text = thisTextBox.Text.ToLower(); } |
為了檢索 TextBox,您必須在樹中向上追溯。首先,到達 MenuItem,然后是 ContextMenu,最后,您就可以訪問其所有者 TextBox 了。此時,修改 TextBox 的內容顯得輕而易舉。
返回頁首Longhorn 代表了 Windows 操作系統歷史上的一個重要里程碑。它將成為第一個專門圍繞托管代碼進行設計的 Windows 版本。新的應用模型進一步確立了 Longhorn 的重要意義;過去在基于 .NET 框架的應用程序(尤其是 ASP.NET 應用程序)的應用建模方面的豐富經驗使它的設計和實現達到了頂點。
Longhorn 應用程序是圍繞 Application 對象構建的,使您能夠將大量標記頁組合在一個作為整體存在的應用程序中。您還可以將 Longhorn 應用程序背后的 XAML 語言視為設計 Longhorn 應用模型時所采用的抽象級別的標志。Longhorn 的最終目標是,允許您一次編碼,可在各種方案中進行部署,無論這些方案是基于 Web,還是基于客戶端。
介紹一種沒有多少人用過的新平臺的應用模型可不是件容易的事情。如果考慮到有些方面很可能在將來還會發生重大變化,這個任務就顯得更困難了。從這個角度來說,您可以將本文視為一張快照,以此來了解 Longhorn 目前的情況以及未來的發展方向。
我已經提供了可作為代碼進行下載的項目示例,以便幫助您實踐 Longhorn。您可以單擊本文開頭的鏈接,以獲得此項目。
Dino Esposito 在意大利羅馬工作,任職教員兼顧問。作為 Microsoft Press 推出的《Programming ASP.NET》的作者,他將大多數時間用于教授 ADO.NET 和 ASP.NET 方面的課程以及在各種會議上演講。如果希望與 Dino 聯系,請發送電子郵件至 cutting@microsoft.com 。
原文轉自:http://www.anti-gravitydesign.com