Silverlight 快速指南



Silverlight - 概述

歡迎使用 Silverlight 教程。Silverlight 是一個用於構建富網際網路應用程式的平臺。本教程將解釋 Silverlight 背後的概念,並向您展示如何將其構建到您的 Web 應用程式中。完成本教程後,您將更好地理解使用 XAML 和 C# 的 Silverlight 應用程式。

什麼是 Silverlight

Silverlight 是一種瀏覽器外掛,旨在構建富網際網路應用程式;這些應用程式像普通 Web 應用程式一樣在瀏覽器中執行,但試圖將使用者介面提升到 HTML 可以達到的範圍之外。例如,

  • Silverlight 是一個用於構建在各種作業系統上執行的、瀏覽器託管的富應用程式的框架。

  • 它還可以與 HTML 共存。因此,Silverlight 可以增強現有的 Web 應用程式。

  • Silverlight 透過瀏覽器外掛發揮其魔力。當您瀏覽到包含 Silverlight 內容的網頁時,此瀏覽器外掛會執行、執行程式碼並在頁面中專門指定的區域呈現該內容。

  • 重要的是,Silverlight 外掛提供的環境比為普通網頁提供支援的 HTML 和 JavaScript 的傳統組合更豐富。

  • 您可以建立播放影片、具有硬體加速的 3D 圖形並使用向量動畫的 Silverlight 頁面。

從開發人員的角度來看,Silverlight 最有趣的特性是它將 .NET Framework 程式設計模型引入 Web 應用程式的客戶端。

Feature of Silverlight
  • Silverlight 旨在在網頁內部執行,因此它可以作為瀏覽器外掛執行。它提供用於渲染點陣圖、向量圖形、高畫質影片和動畫的圖形服務。

  • 您可以使用 C# 或 Visual Basic .NET 編寫程式碼,並在 Web 瀏覽器中執行的程式碼上使用 .NET Framework 類庫功能。

  • Silverlight 使用者介面本身使用與 Windows Presentation Foundation (WPF) 非常相似的模型,WPF 是完整桌面 .NET Framework 中的使用者介面框架。

  • 如果您瞭解 WPF,那麼 Silverlight 就很容易學習。Silverlight 的下載量比 .NET 小得多。它的大小大約是 .NET 的十分之一,因此只存在類庫的一個子集,並且對 WPF 的模型進行了一些修改。

  • 儘管規模縮小了,但經驗豐富的 .NET 開發人員會立即在 Silverlight 中找到熟悉的感覺。

平臺和瀏覽器

Silverlight 支援的平臺和瀏覽器如下:-

Windows

  • Silverlight 支援 Windows,正如您對 Microsoft 產品的預期一樣。它至少需要 Windows XP Service Pack 2 或最新版本的 Windows。

  • 較舊的版本不受完全支援。例如,Silverlight 根本無法在 Windows ME 上執行,並且 Windows 2000 的支援有限。

  • 對於瀏覽器,Silverlight 當然支援 Microsoft 自身的 Internet Explorer,並且支援 Firefox 和 Google Chrome 版本 4。

  • 總的來說,Silverlight 支援常見的 Web 瀏覽器外掛 API。它可以在比官方支援列表更廣泛的瀏覽器中執行。

Mac

  • Silverlight 支援 Mac OS10,儘管 Silverlight 版本 2 或更高版本僅在基於 Intel 的 Mac 上執行。

  • 在現代 Mac 上,Firefox 和 Safari 都受支援。

Linux

  • Microsoft 自身的 Silverlight 外掛無法在 Linux 上執行,但 Mono 開源專案有一個名為 Moonlight 的分支,它是一個與 Silverlight 相容的外掛,可以在 Linux 上執行。

  • Moonlight 在 Firefox 中執行,有趣的是,它一直能夠在獨立模式下執行。

  • Mono 專案最初決定構建 Moonlight 的原因之一是,他們認為 Silverlight 將是一種有用的技術,可以用來構建在桌面上執行的使用者介面小部件。

Silverlight - 環境設定

Microsoft 為 Silverlight 應用程式開發提供了兩個重要的工具。它們是:-

  • Visual Studio
  • Expression Blend

目前,這兩個工具都可以建立 Silverlight 專案,但事實是 Visual Studio 更受開發人員使用,而 Blend 仍然更常被設計人員使用。Microsoft 提供了 Visual Studio 的免費版本,您可以從 https://www.visualstudio.com 下載。在本教程中,我們將主要使用 Visual Studio。

安裝

步驟 1 - 下載 Silverlight 後,執行安裝程式。將顯示以下對話方塊。

Silverlight Downloaded

步驟 2 - 單擊安裝按鈕,它將啟動安裝過程。

Installation Process

步驟 3 - Silverlight 成功安裝後,您將看到以下對話方塊。

Successfully Installed

步驟 4 - 關閉此對話方塊,並在需要時重新啟動計算機。

步驟 5 - 現在從開始選單開啟Visual Studio,這將開啟如下所示的對話方塊。首次啟動時,它需要一些時間進行準備。

Visual Studio

步驟 6 - 接下來,您將看到 Visual Studio 的主視窗。

Window Visual Studio

步驟 7 - 現在,要開始使用 Silverlight 應用程式,您還需要在您的計算機上安裝 Silverlight 開發人員工具。從http://silverlight.dlservice.microsoft.com/download/8/E/7/8E7D9B4B-2088-4AED8356-20E65BE3EC91/40728.00/Silverlight_Developer_x64.exe下載並安裝最新的 Silverlight 開發人員工具。

Silverlight Application

步驟 8 - 單擊安裝。安裝需要一些時間。

Silverlight Install

步驟 9 - 安裝完成後,您將看到以下訊息。

Successfully Installed

步驟 10 - 現在您已準備好構建您的第一個 Silverlight 應用程式。單擊關閉

Silverlight - 入門

在本章中,我們將瞭解 Silverlight 的一個工作示例。我們需要兩件事:-

  • 首先,我們需要一個網頁。Silverlight 旨在用於富網際網路應用程式,它旨在作為網頁的一部分在 Web 瀏覽器中執行。頁面需要包含一個合適的標籤來載入 Silverlight 外掛。它還可以包含檢測 Silverlight 是否已安裝的邏輯,並在 Silverlight 不存在時提供一些後備使用者介面。

  • 我們需要做的第二件事是 Silverlight 內容本身。本教程將重點介紹 Silverlight 的 .NET 程式設計模型。我們將建立一個編譯後的 Silverlight 應用程式,其中包含 XAML(我們用來定義 Silverlight 使用者介面的模擬語言)和用 C# 編寫的 .NET 程式碼的混合。

建立網頁

使用 Silverlight 的最簡單方法是建立一個帶有 HTML 頁面的普通網站,並且沒有伺服器端程式碼。讓我們看一個非常簡單的例子。

步驟 1 - 開啟Visual Studio。單擊檔案選單,指向新建,然後單擊專案

Create a Web-page

步驟 2 - 將開啟新建專案對話方塊。在模板下,選擇Visual C#,然後單擊Silverlight。在右側窗格中,選擇 Silverlight 應用程式。

Choose Silverlight Application

輸入專案名稱和硬碟驅動器上的儲存位置,然後單擊確定以建立專案。

Silverlight 專案本身只是構建 Silverlight 內容,而該內容只是構成整個 Web 應用程式的眾多資產之一。

單擊確定

步驟 3 - 選中託管 Silverlight 應用程式複選框。預設值為 ASP.NET Web 應用程式專案。

New Silverlight Application

步驟 4 - MS-Visual Studio 建立了兩個專案,Silverlight 專案和 ASP.NET Web 應用程式。現在,我們確實需要一個 ASP.NET Web 應用程式。您可以在解決方案資源管理器視窗中看到它,如下所示。

Solution Explorer

任何可以透過 HTTP 提供內容的內容都可以,但這是Visual Studio,它理解 ASP.NET Web 技術,所以這就是它提供給我們的內容。

為了證明 Silverlight 不依賴於任何特定的伺服器端技術,讓我們刪除此.aspx檔案,只保留純靜態 HTML 檔案。

步驟 5 - 右鍵單擊 FirstExampleTestpage.aspx。從選項列表中,單擊刪除

FirstExampleTestpage.aspx

步驟 6 - 將FirstExampleTestPage.html設定為啟動頁面。

FirstExampleTestpage.html

MainPage.xaml檔案定義了 Silverlight 內容的使用者介面。您可以直接編寫 XAML 程式碼,也可以使用工具箱拖放不同的 UI 元素。

步驟 7 - 下面是在MainPage.xaml中的一段簡單程式碼,其中ButtonTextBlock定義在StackPanel內。

<UserControl x:Class = "FirstExample.MainPage" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   mc:Ignorable = "d" 
   d:DesignHeight = "300" d:DesignWidth = "400">  
   
   <Grid x:Name = "LayoutRoot" Background = "White"> 
      <StackPanel> 
         <TextBlock x:Name = "TextMessage"  
            Text = "Hello World!"  
            Margin = "5">
         </TextBlock> 
			
         <Button x:Name = "ClickMe"  
            Click = "ClickMe_Click"  
            Content = "Click Me!"  
            Margin = "5"> 
         </Button> 
			
      </StackPanel> 
   </Grid> 
	
</UserControl>

步驟 8 - 此示例假設您已建立了一個名為ClickMe_Click的事件處理方法。以下是它在MainPage.xaml.cs檔案中的樣子。

using System.Windows; 
using System.Windows.Controls;
  
namespace FirstExample { 

   public partial class MainPage : UserControl { 
	
      public MainPage() { 
         InitializeComponent(); 
      } 
	  
      private void ClickMe_Click(object sender, RoutedEventArgs e) { 
         TextMessage.Text = "Congratulations! you have created your first Silverlight Applicatoin"; 
      } 
   } 
}

步驟 9 - Silverlight 應用程式可以在任何已安裝的瀏覽器上執行。

Silverlight Application Run

步驟 10 - 當上述程式碼編譯並執行時,您將看到以下網頁。

Compiled Executed

步驟 11 - 現在,當您單擊單擊我按鈕時,它將更新TextBlock中的文字,如下所示。

Text Update

我們建議您透過新增更多 UI 元素來執行上述示例。

Silverlight - XAML 概述

在使用 Silverlight 時,您會遇到的第一件事之一是 XAML。XAML 代表可擴充套件應用程式標記語言。它是一種基於 XML 的簡單且宣告性的語言。

  • 在 XAML 中,建立、初始化和設定具有層次關係的物件的屬性非常容易。

  • 它主要用於設計 GUI。

  • 它也可以用於其他目的,例如,在工作流基礎中宣告工作流。

基本語法

當您建立一個新的 Silverlight 專案時,您將在MainPage.xaml中看到一些預設的 XAML 程式碼,如下所示。

<UserControl x:Class = "FirstExample.MainPage" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   mc:Ignorable = "d" 
   d:DesignHeight = "300" d:DesignWidth = "400"> 
	
   <Grid x:Name = "LayoutRoot" Background = "White"> 
         
   </Grid> 
	
</UserControl>

您可以看到上面給出的 XAML 檔案提到了不同型別的資訊;下面給出的表中簡要描述了所有這些資訊。

資訊 描述
<UserControl> 提供定義一個封裝現有控制元件並提供自身邏輯的新控制元件的基類。
x:Class = "FirstExample.MainPage" 這是一個部分類宣告,它將標記與在其中定義的程式碼隱藏部分類程式碼連線起來。
xmlns = "http://schemas.microsoft.com /winfx/2006/xaml/presentation" 對映 Silverlight 客戶端/框架的預設 XAML 名稱空間。
xmlns:x = "http://schemas.microsoft.c om/winfx/2006/xaml" XAML 語言的 XAML 名稱空間,將其對映到 x: 字首。
xmlns:d = "http://schemas.microsoft.com /expression/blend/2008" XAML 名稱空間用於設計器支援,特別是 Microsoft Visual Studio 和 Microsoft Expression Blend 中的 XAML 設計介面的設計器支援。
xmlns:mc = "http://schemas.openxmlforma ts.org/markup-compatibility/2006" 指示並支援用於讀取 XAML 的標記相容模式。
> 根物件的元素結束。
<Grid></Grid> 這些是空網格物件的開始和結束標籤。
</UserControl> 關閉物件元素。

XAML 的語法規則與 XML 的語法規則幾乎相同。如果您檢視 XAML 文件,您會注意到它實際上是一個有效的 XML 檔案。反之則不成立,因為在 XML 中,屬性的值必須是字串,而在 XAML 中它可以是不同的物件,這被稱為屬性元素語法。

  • 物件元素的語法以左尖括號 (<) 開頭,後跟物件的名稱,例如 Button。

  • 定義該物件元素的屬性和特性。

  • 物件元素必須以正斜槓 (/) 後跟右尖括號 (>) 立即關閉。

下面顯示了一個沒有子元素的簡單物件的示例。

<Button/> 

具有某些屬性的物件元素示例 -

<Button Content = "Click Me" Height = "30" Width = "60"/> 

定義屬性的備用語法的示例(屬性元素語法) -

<Button> 
   <Button.Content>Click Me</Button.Content> 
   <Button.Height>30</Button.Height> 
   <Button.Width>60</Button.Width> 
</Button>  

具有子元素的物件示例:StackPanel 包含 Textblock 作為子元素。

<StackPanel Orientation = "Horizontal"> 
   <TextBlock Text = "Hello"/> 
</StackPanel/> 

為什麼 Silverlight 中要使用 XAML

XAML 最初並非為 Silverlight 而發明。它來自 WPF,即 Windows Presentation Foundation。Silverlight 通常被描述為 WPF 的子集。這並不完全正確,因為 Silverlight 可以執行 WPF 無法執行的操作。即使在功能重疊的地方,這兩者在細節上也略有不同。

  • 更準確地說,WPF 和 Silverlight 在許多方面非常相似。儘管存在差異,但檢視 Silverlight 從 WPF 借用的 XAML 功能仍然很有幫助。例如,Silverlight 提供了點陣圖和可縮放形狀的圖形基元。

  • 它還提供用於渲染影片和音訊的元素。

  • 它具有簡單的格式化文字支援,您可以動畫化任何元素。如果您瞭解 WPF,則此功能集將非常熟悉。

  • 有一點很重要,您不能獲取 WPF XAML 並將其用於 Silverlight。

  • 儘管存在相似之處,但您也會發現許多細微差別。

XAML 和程式碼隱藏

XAML 定義使用者介面的外觀和結構。但是,如果您希望應用程式在使用者與之互動時執行任何有用的操作,則需要一些程式碼。

  • 每個 XAML 檔案通常都與一個原始碼檔案關聯,我們將其稱為程式碼隱藏。各種 Microsoft 框架都使用此術語。

  • 程式碼隱藏通常需要使用 XAML 中定義的元素,以檢索有關使用者輸入的資訊或向用戶顯示資訊。

  • 在下面給出的 XAML 程式碼中,定義了TextBlockButton。預設情況下,當應用程式執行時,它將在網頁上顯示文字“Hello World!”和一個按鈕。

<UserControl x:Class = "FirstExample.MainPage" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   mc:Ignorable = "d" 
   d:DesignHeight = "300" d:DesignWidth = "400">
   
   <Grid x:Name = "LayoutRoot" Background = "White"> 
      <StackPanel> 
         <TextBlock x:Name = "TextMessage"  
            Text = "Hello World!"  
            Margin = "5"> 
         </TextBlock> 
			
         <Button x:Name = "ClickMe"  
            Click = "ClickMe_Click"  
            Content = "Click Me!"  
            Margin = "5"> 
         </Button> 
			
      </StackPanel> 
   </Grid> 
</UserControl> 
  • 程式碼隱藏可以訪問使用x:Name指令命名的任何元素。

  • 命名元素透過程式碼隱藏中的欄位可用,允許程式碼以通常的方式訪問這些物件及其成員。

  • x:Prefix表示該名稱不是普通屬性。

  • x:Name是 XAML 編譯器的一個特殊訊號,表明我們希望在程式碼隱藏中訪問此物件。

下面給出了按鈕單擊事件的實現,其中更新了TextBlock文字。

using System.Windows; 
using System.Windows.Controls;
  
namespace FirstExample {
 
   public partial class MainPage : UserControl {
	
      public MainPage() { 
         InitializeComponent(); 
      }
		
      private void ClickMe_Click(object sender, RoutedEventArgs e) { 
         TextMessage.Text = "Congratulations! you have created your first Silverlight Applicatoin"; 
      } 
   } 
}
  • XAML 不是設計 UI 元素的唯一方法。您可以選擇在 XAML 中宣告物件,或者在程式碼中宣告/編寫。

  • XAML 是可選的,但儘管如此,它仍然是Silverlight設計的核心。

  • 使用 XAML 編碼的目標是使視覺設計人員能夠直接建立使用者介面元素。因此,Silverlight旨在使從標記控制使用者介面的所有視覺方面成為可能。

Silverlight - 專案型別

如果您在 Visual Studio 中建立一個新專案,您將在對話方塊的右側窗格中看到四種類型的專案。它們是 -

  • Silverlight 應用程式
  • Silverlight 類庫
  • 類庫(可移植)
  • Silverlight 導航應用程式
Silverlight New Application
  • 前兩個,Silverlight 應用程式Silverlight 類庫,非常簡單易懂。它們類似於經典 Windows 應用程式世界中的 DLL 中的可執行檔案。由於 Silverlight 應用程式的部署方式,兩者都構建 DLL。

  • 從概念上講,Silverlight 應用程式專案構建一個可以執行的程式,而類庫專案構建一個旨在整合到其他應用程式中的庫。

  • 如果您計劃構建多個應用程式並希望重用公共程式碼,則可以構建類庫。如果您計劃銷售其他人將在其應用程式中使用的控制元件,那麼庫也是要構建的內容。

  • 其他專案型別不太明顯,因此我們將在本章後面詳細介紹這些內容。

Silverlight Web 應用程式

Silverlight 應用程式是從 Web 下載的,因此您通常會與 Silverlight 專案關聯一個 Web 專案。Visual Studio 有幾個功能旨在管理這些專案之間的關係。

讓我們再看一個簡單的 Silverlight 應用程式專案示例。

步驟 1 - 開啟Visual Studio。單擊檔案選單,指向新建,然後單擊專案

Create a Web-page

步驟 2 - 將開啟新建專案對話方塊。在模板下,選擇Visual C#,然後單擊Silverlight。在右側窗格中,選擇 Silverlight 應用程式。

Silverlight Application

輸入專案名稱和硬碟驅動器上的位置以儲存您的專案。

Silverlight 專案本身只是構建 Silverlight 內容,而該內容只是構成整個 Web 應用程式的眾多資產之一。

單擊確定

步驟 3 - 選中託管 Silverlight 應用程式複選框。預設值為 ASP.NET Web 應用程式專案。

New Silverlight Application

步驟 4 - MS-Visual Studio 建立了兩個專案,Silverlight 專案和 ASP.NET Web 應用程式。現在,我們需要一個 ASP.NET Web 應用程式。您可以在解決方案資源管理器視窗中看到它,如下所示。

Solution Explorer

任何可以透過 HTTP 提供內容的內容都可以,但這是Visual Studio,它理解 ASP.NET Web 技術,所以這就是它提供給我們的內容。

為了證明 Silverlight 不依賴於任何特定的伺服器端技術,讓我們刪除此.aspx檔案,只保留純靜態 HTML 檔案。

步驟 5 - 右鍵單擊 FirstExampleTestpage.aspx。從選項列表中,單擊刪除

FirstExampleTestpage aspx

步驟 6 - 將FirstExampleTestPage.html設定為啟動頁面。

FirstExampleTestpage html

MainPage.xaml檔案定義了 Silverlight 內容的使用者介面。您可以直接編寫 XAML 程式碼,也可以使用工具箱拖放不同的 UI 元素。

步驟 7 - 下面是在MainPage.xaml中的一段簡單程式碼,其中ButtonTextBlock定義在StackPanel內。

<UserControl x:Class = "FirstExample.MainPage" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   mc:Ignorable = "d" 
   d:DesignHeight = "300" d:DesignWidth = "400">  
   
   <Grid x:Name = "LayoutRoot" Background = "White"> 
      <StackPanel> 
         <TextBlock x:Name = "TextMessage" Text = "Hello World!"  
            Margin = "5"> </TextBlock> 
         <Button x:Name = "ClickMe" Click = "ClickMe_Click" Content = "Click 
            Me!"  Margin = "5"> </Button> 
      </StackPanel> 
   </Grid> 
	
</UserControl>

步驟 8 - 此示例假設您已建立了一個名為ClickMe_Click的事件處理方法。以下是它在MainPage.xaml.cs檔案中的樣子。

using System.Windows; 
using System.Windows.Controls;
  
namespace FirstExample { 

   public partial class MainPage : UserControl { 
	
      public MainPage() { 
         InitializeComponent(); 
      } 
	  
      private void ClickMe_Click(object sender, RoutedEventArgs e) { 
         TextMessage.Text = "Congratulations! you have created your 
            first Silverlight Applicatoin"; 
      } 
   } 
}

步驟 9 - Silverlight 應用程式可以在任何已安裝的瀏覽器上執行。

Silverlight Application Run

步驟 10 - 當上述程式碼編譯並執行時,您將看到以下網頁。

Compiled Executed

Silverlight 導航應用程式

Silverlight 導航應用程式模板構建了一個類似於普通 Silverlight 應用程式的專案。這兩種專案型別之間沒有任何根本區別。導航模板僅包含一些您可以輕鬆新增的其他程式碼。顧名思義,它支援 Silverlight 應用程式內的類似 Web 的導航。

讓我們建立一個導航應用程式。

步驟 1 - 在新建專案對話方塊的右側窗格中選擇Silverlight 導航應用程式

Silverlight Navigation Application

步驟 2 - 按照您對 Silverlight Web 應用程式所做的設定進行操作。

Silverlight Web Application

步驟 3 - 點選確定按鈕。將開啟一個視窗,如下所示。

Silverlight Navigation App.Web

這些通常具有關聯的 Web 專案,因此我們將擁有其中一個。它建立了前面描述的兩個專案,但如您所見,預設使用者介面看起來不那麼空白了。

步驟 4 - 它提供了一個應用程式 Chrome,包括一個導航欄。該解決方案包含一些額外的檔案。此樣式檔案定義了導航欄的外觀。在此檢視資料夾中,我們看到幾個頁面,以及一個顯示錯誤的視窗。

Navigation Bar

如您所見,當您執行應用程式時,它會顯示一個帶有某些佔位符內容的主頁。

Application Name

步驟 5 - 當您點選關於按鈕時,它將導航到關於頁面。

About page

重要的是,您可以隨後使用瀏覽器後退前進按鈕來回溯步驟。

通常,當您這樣做時,Web 瀏覽器會從一個網頁跳轉到另一個網頁,但此處不會。Silverlight 應用程式實際上並沒有解除安裝;它保持執行,只是顯示不同的內容。

因此,從瀏覽器的角度來看,它實際上都在一個網頁上。Silverlight 對導航按鈕進行了一些技巧,以確保在導航時網頁不會解除安裝。

Silverlight - 固定佈局

控制元件的佈局對於應用程式可用性非常重要且至關重要。它用於在應用程式中排列一組 GUI 元素。在選擇佈局面板時,需要考慮某些重要事項。它們是 -

  • 子元素的位置。
  • 子元素的大小。
  • 子元素彼此重疊的分層。

如果應用程式已在不同的螢幕解析度上使用,則控制元件的固定畫素排列不起作用。XAML 提供了一套豐富的內建佈局面板,以適當的方式排列 GUI 元素。

我們將從檢視簡單的固定佈局開始。然後,我們將檢視 Silverlight 設計為支援的動態佈局場景。我們將看到貫穿所有使用者介面元素的佈局相關屬性和概念。

固定佈局

Canvas元素提供了最簡單的佈局型別。Canvas面板是基本佈局面板,其中可以使用相對於 Canvas 任何一側(如左、右、上和下)的座標明確定位子元素。

Fixed Layout

通常,Canvas用於 2D 圖形元素(例如 Ellipse、Rectangle 等)。它不用於 UI 元素,因為在調整大小、本地化或縮放 XAML 應用程式時,指定絕對座標會帶來麻煩。

下面列出了Canvas類的常用屬性

序號 屬性和描述
1

Background

獲取或設定填充面板內容區域的 Brush。(繼承自 Panel)

2

Children

獲取此 Panel 的子元素的 UIElementCollection。(繼承自 Panel。)

3

Height

獲取或設定元素的建議高度。(繼承自 FrameworkElement。)

4

ItemHeight

獲取或設定一個值,該值指定 WrapPanel 中包含的所有專案的的高度。

5

ItemWidth

獲取或設定一個值,該值指定 WrapPanel 中包含的所有專案的寬度。

6

LogicalChildren

獲取一個列舉器,該列舉器可以迭代此 Panel 元素的邏輯子元素。(繼承自 Panel。)

7

LogicalOrientation

面板的方向,如果面板僅支援單維度佈局。(繼承自 Panel。)

8

LeftProperty

標識 Canvas.Left XAML 附加屬性。

9

Margin

獲取或設定元素的外邊距。(繼承自 FrameworkElement。)

10

Name

獲取或設定元素的標識名稱。名稱提供了一個引用,以便程式碼隱藏(例如事件處理程式程式碼)在 XAML 處理器處理期間構造標記元素後引用它。(繼承自 FrameworkElement。)

11

Orientation

獲取或設定一個值,該值指定子內容排列的維度。

12

Parent

獲取此元素的邏輯父元素。(繼承自 FrameworkElement。)

13

Resources

獲取或設定本地定義的資源字典。(繼承自 FrameworkElement。)

14

Style

獲取或設定此元素渲染時使用的樣式。(繼承自 FrameworkElement。)

15

TopProperty

標識 Canvas.Top XAML 附加屬性。

16

Width

獲取或設定元素的寬度。(繼承自 FrameworkElement。)

17

ZIndexProperty

標識 Canvas.ZIndex XAML 附加屬性。

以下是Canvas常用方法

序號 方法及描述
1

GetLeft

獲取目標元素的 Canvas.Left XAML 附加屬性的值。

2

GetTop

獲取目標元素的 Canvas.Top XAML 附加屬性的值。

3

GetZIndex

獲取目標元素的 Canvas.ZIndex XAML 附加屬性的值。

4

SetLeft

設定目標元素的 Canvas.Left XAML 附加屬性的值。

5

SetTop

設定目標元素的 Canvas.Top XAML 附加屬性的值。

6

SetZIndex

設定目標元素的 Canvas.ZIndex XAML 附加屬性的值。

以下示例演示如何將子元素新增到Canvas中。以下是 XAML 實現,其中在 Canvas 中建立了一個 Ellipse,並帶有不同的偏移屬性。

<UserControl x:Class = "FirstExample.MainPage" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   mc:Ignorable = "d" 
   d:DesignHeight = "300" d:DesignWidth = "400">
   
   <Grid x:Name = "LayoutRoot" Background = "White"> 
      <Canvas Width = "380" Height = "280" > 
         <Ellipse Canvas.Left = "30" Canvas.Top = "30"  
            Fill = "Gray" Width = "200" Height = "120" />             
      </Canvas>  
   </Grid>
	
</UserControl>

編譯並執行上述程式碼後,您將看到以下輸出。

Add Child Elements Canvas

Silverlight - 動態佈局

Canvas是所有 Silverlight 佈局面板中最不有趣的一個。其他面板支援動態佈局,這意味著佈局可以根據顯示專案數量、顯示資訊的尺寸或使用者調整瀏覽器大小導致的應用程式可用空間數量的變化進行調整。

Silverlight 提供了兩個具有動態佈局策略的面板。

  • StackPanel - 將元素垂直或水平排列成堆疊。

  • Grid - 提供靈活的網格狀或表格狀佈局系統。

Stack Panel

Stack Panel 是 XAML 中一個簡單而有用的佈局面板。在Stack Panel中,子元素可以基於其方向屬性水平或垂直排列成一行。它通常用於建立任何型別的列表時。ItemsControls 使用 Stack Panel。Menu、ListBoxComboBox 是它們的預設內部佈局面板。

以下是StackPanel的常用屬性

序號 屬性和描述
1

Background

獲取或設定填充面板內容區域的 Brush。(繼承自 Panel)

2

Children

獲取此 Panel 的子元素的 UIElementCollection。(繼承自 Panel。)

3

Height

獲取或設定元素的建議高度。(繼承自 FrameworkElement。)

4

ItemHeight

獲取或設定一個值,該值指定 WrapPanel 中包含的所有專案的的高度。

5

ItemWidth

獲取或設定一個值,該值指定 WrapPanel 中包含的所有專案的寬度。

6

LogicalChildren

獲取一個列舉器,該列舉器可以迭代此 Panel 元素的邏輯子元素。(繼承自 Panel。)

7

LogicalOrientation

面板的方向,如果面板僅支援單維度佈局。(繼承自 Panel。)

8

Margin

獲取或設定元素的外邊距。(繼承自 FrameworkElement。)

9

Name

獲取或設定元素的標識名稱。名稱提供了一個引用,以便程式碼隱藏(例如事件處理程式程式碼)在 XAML 處理器處理期間構造標記元素後引用它。(繼承自 FrameworkElement。)

10

Orientation

獲取或設定一個值,該值指定子內容排列的維度。

11

Parent

獲取此元素的邏輯父元素。(繼承自 FrameworkElement。)

12

Resources

獲取或設定本地定義的資源字典。(繼承自 FrameworkElement。)

13

Style

獲取或設定此元素渲染時使用的樣式。(繼承自 FrameworkElement。)

14

Width

獲取或設定元素的寬度。(繼承自 FrameworkElement。)

以下示例演示如何將子元素新增到StackPanel中。以下是 XAML 實現,其中在 StackPanel 中建立了Buttons,並帶有一些屬性。

<UserControl x:Class = "DynamicLayout.MainPage" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   mc:Ignorable = "d" 
   d:DesignHeight = "300" d:DesignWidth = "400"> 
    
   <Grid x:Name = "LayoutRoot" Background = "White"> 
      <StackPanel>
         <Button x:Name = "button" Content = "Button" Margin = "10" /> 
         <Button x:Name = "button1" Content = "Button" Margin = "10"/> 
         <Button x:Name = "button2" Content = "Button" Margin = "10"/> 
         <Button x:Name = "button3" Content = "Button" Margin = "10"/> 
      </StackPanel>  
   </Grid> 
	
</UserControl> 

編譯並執行上述程式碼後,您將看到以下輸出。

Dynamic Layout Complied

StackPanel 嘗試為每個元素在堆疊方向上提供儘可能多的空間。

現在,如果您調整瀏覽器大小,您將看到按鈕的寬度也發生了變化。

Resize Dynamic Layout Complied

Grid

Grid 面板提供了一個靈活的區域,該區域由行和列組成。在Grid中,子元素可以以表格形式排列。可以透過使用Grid.RowGrid.Column 屬性將元素新增到任何特定的行和列。預設情況下,Grid面板建立一行一列。多個行和列由RowDefinitionsColumnDefinitions 屬性建立。行的高度和列的寬度可以透過以下三種方式定義:

  • 固定值 - 為邏輯單位(1/96 英寸)分配固定大小。

  • Auto - 它將佔用特定行/列中的控制元件所需的空間。

  • 星號 (*) - 當Auto固定大小填充後,它將佔用剩餘的空間。

以下是Grid類的常用屬性

序號 屬性和描述
1

Background

獲取或設定填充面板內容區域的 Brush。(繼承自 Panel)

2

Children

獲取此 Panel 的子元素的 UIElementCollection。(繼承自 Panel。)

3

ColumnDefinitions

獲取在此 Grid 例項上定義的 ColumnDefinition 物件列表。

4

Height

獲取或設定元素的建議高度。(繼承自 FrameworkElement。)

5

ItemHeight

獲取或設定一個值,該值指定 WrapPanel 中包含的所有專案的的高度。

6

ItemWidth

獲取或設定一個值,該值指定 WrapPanel 中包含的所有專案的寬度。

7

Margin

獲取或設定元素的外邊距。(繼承自 FrameworkElement。)

8

Name

獲取或設定元素的標識名稱。名稱提供了一個引用,以便程式碼隱藏(例如事件處理程式程式碼)在 XAML 處理器處理期間構造標記元素後引用它。(繼承自 FrameworkElement。)

9

Orientation

獲取或設定一個值,該值指定子內容排列的維度。

10

Parent

獲取此元素的邏輯父元素。(繼承自 FrameworkElement。)

11

Resources

獲取或設定本地定義的資源字典。(繼承自 FrameworkElement。)

12

RowDefinitions

獲取在此 Grid 例項上定義的 RowDefinition 物件列表。

13

Style

獲取或設定此元素渲染時使用的樣式。(繼承自 FrameworkElement。)

14

Width

獲取或設定元素的寬度。(繼承自 FrameworkElement。)

以下是Grid類的常用方法

序號 方法及描述
1

GetColumn

從指定的 FrameworkElement 獲取 Grid.Column XAML 附加屬性的值。

2

GetColumnSpan

從指定的 FrameworkElement 獲取 Grid.ColumnSpan XAML 附加屬性的值。

3

GetRow

從指定的 FrameworkElement 獲取 Grid.Row XAML 附加屬性的值。

4

SetColumn

設定指定 FrameworkElement 上 Grid.Column XAML 附加屬性的值。

5

SetRow

設定指定 FrameworkElement 上 Grid.Row XAML 附加屬性的值。

6

SetRowSpan

設定指定 FrameworkElement 上 Grid.RowSpan XAML 附加屬性的值。

以下示例演示如何將子元素新增到 Grid 以表格形式指定它。以下是 XAML 實現,其中添加了一些 UI 元素。

<UserControl x:Class = "DynamicLayout.MainPage" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008"
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   mc:Ignorable = "d" 
   d:DesignHeight = "300" d:DesignWidth = "400">  
   
   <Grid x:Name = "LayoutRoot" Background = "White"> 
	
      <Grid.ColumnDefinitions> 
         <ColumnDefinition Width = "130" /> 
         <ColumnDefinition Width = "1*" /> 
         <ColumnDefinition Width = "2*" /> 
      </Grid.ColumnDefinitions>
		
      <Grid.RowDefinitions> 
         <RowDefinition Height = "Auto" /> 
         <RowDefinition Height = "50" /> 
      </Grid.RowDefinitions>  
		
      <TextBlock Grid.Column = "0" Grid.Row = "0" 
         Text = "Content that no longer fits, not even close here" 
         TextWrapping = "Wrap" /> 
			
      <Button Grid.Column = "1" Grid.Row = "0" Content = "OK" />  
      <Ellipse Grid.Column = "1" Grid.Row = "1"  Fill = "Aqua" /> 
      <Rectangle Grid.Column = "2" Grid.Row = "1" Fill = "Orchid" RadiusX = "20" RadiusY = "20" />  
		
   </Grid> 
	
</UserControl> 

第一列設定為固定大小。此列中的任何元素都將具有該寬度。Grid.ColumnGrid.Row 屬性指定這些專案位於哪一行和哪一列,它們是基於 0 的屬性。

第二列或第三列的寬度為1*2*。這意味著它們共享在任何固定寬度和自動寬度列佔用其空間後剩餘的空間。此處12的意義在於,2*列獲得的空間是1*列的兩倍。

執行上述程式碼後,您將看到以下輸出。

Dynamic Layout Grid

調整應用程式大小時,這兩列的內容也會調整大小以匹配。順便說一句,星號大小的行或列的絕對值無關緊要;只有比率很重要。

Resize Dynamic Layout Grid

受約束與不受約束的佈局

Silverlight 中的佈局始終以兩種模式之一發生,即受約束或不受約束。受約束的佈局是指容器強制實施寬度或高度的佈局。例如,Web 瀏覽器通常使用 CSS 始終確定 Silverlight 外掛的整體尺寸。

一些重要的特性是:

  • 頂級元素的佈局在水平和垂直方向上都受到約束。無論它產生什麼佈局,最終都必須始終得到瀏覽器強制實施的大小結果。

  • 某些元素最終具有不受約束的佈局,這意味著這些元素可以自由選擇自己的大小。例如,垂直StackPanel內的元素在垂直方向上不受約束。

  • StackPanel 將為它們提供所需的高度。事實上,即使沒有足夠的空間,它也會這樣做。它會告訴元素它們擁有所需的高度,然後裁剪任何不適合的部分。

  • 大多數 Silverlight 使用者介面包含這兩種佈局樣式的混合。無論其父級是否施加約束,StackPanel始終會在堆疊方向上執行不受約束的佈局。當高度或寬度設定為Auto時,Grid 行或列也是如此。

假設您有一個元素,它位於一個強制實施固定水平寬度的容器內。預設情況下,您的元素將被拉伸以填充空間。如果將對齊方式設定為 Left、Right 或 Center,它將刪除約束。

Constrained Unconstrained

元素將僅佔用其所需寬度。當然,您可以使用固定寬度或高度引入約束。

  • 不受約束的佈局有時稱為根據內容調整大小,因為不受約束的元素的大小通常由其內容決定。

  • 根據內容調整大小是 Silverlight 佈局中的一個重要概念。它使佈局能夠根據正在顯示的資訊自適應。

序號 控制元件及描述
1 GridSplitter

約束可以來自包含的瀏覽器,也可以來自設計中的固定尺寸。但是,有時讓使用者施加約束也很有用。

2 ScrollViewer

某些使用者介面最終需要顯示比可用空間所能容納的更多資訊。對此的一種常見解決方案是提供一個可滾動區域。Silverlight 使用 ScrollViewer 使此操作非常容易。

3 Border

在佈局使用者介面時,另一個需要牢記的有用元素是 Border。

全屏模式

Silverlight 外掛能夠接管整個螢幕。您可以設定輔助類上的一個屬性以進入全屏模式。但是,出於安全目的,有一些約束。為了防止網站能夠隨意接管螢幕,並執行一些惡意操作,例如偽造提示以要求使用者輸入密碼。

要進入全屏模式,您需要從應用程式物件獲取 Host.Content 屬性,並將 IsFullScreen 屬性設定為 true。

讓我們來看一個簡單的示例,該示例切換屬性,以便它在全屏和普通模式之間來回切換。

<UserControl x:Class = "FullScreenExample.MainPage" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   mc:Ignorable = "d" 
   d:DesignHeight = "300" d:DesignWidth = "400">
   
   <Border BorderBrush = "Gray" BorderThickness = "4" CornerRadius = "30" Padding = "20"> 
	
      <Border.Background> 
         <LinearGradientBrush StartPoint = "0,0" EndPoint = "0,1"> 
            <GradientStop Offset = "0" Color = "Wheat" /> 
            <GradientStop Offset = "1" Color = "BurlyWood" />
         </LinearGradientBrush> 
      </Border.Background> 
		
      <Grid x:Name = "LayoutRoot"> 
         <Button x:Name = "fullScreenButton" HorizontalAlignment = "Center" 
            VerticalAlignment = "Center" FontSize = "30" Width = "300" 
            Height = "100" Content = "Go Full Screen" Click = "Button_Click" /> 
      </Grid> 
		
   </Border> 
	
</UserControl> 

這是一個在 C# 中啟動從全屏返回到正常的程式碼。您可以透過處理Host.Content 物件的FullScreenChanged 事件來了解何時發生這種情況。

using System; 
using System.Windows; 
using System.Windows.Controls;  

namespace FullScreenExample { 

   public partial class MainPage : UserControl { 
	
      public MainPage() { 
         InitializeComponent();  
         App.Current.Host.Content.FullScreenChanged += Content_FullScreenChanged; 
      }
	  
      void Content_FullScreenChanged(object sender, EventArgs e) { 
		
         if (Application.Current.Host.Content.IsFullScreen) { 
            fullScreenButton.Content = "Return to Normal"; 
         } else { 
            fullScreenButton.Content = "Go Full Screen";
         } 
      }
	  
      private void Button_Click(object sender, RoutedEventArgs e) { 
         var content = Application.Current.Host.Content; 
         content.IsFullScreen = !content.IsFullScreen; 
      } 
		
   } 
}

編譯並執行上述程式碼後,您將看到以下輸出。

Full Screen Mode

當用戶單擊進入全屏按鈕時,它將切換到全屏模式。

Full Screen Button

請注意按鈕的文字已更改。現在顯示為返回正常。如果再次點選它或按Esc鍵,它將退出全屏模式。

Silverlight - CSS

由於Silverlight內容始終在網頁內執行,因此object標籤受普通CSS佈局規則的約束。外掛無法將首選大小推回瀏覽器,因此無論Silverlight內容希望多大,其大小和位置都將完全由包含它的網頁決定。

  • 預設的Silverlight專案模板在網頁中放置CSS,使object標籤佔據整個瀏覽器視窗。

  • 預設的XAML似乎具有固定大小,但如果仔細觀察,您會發現模板設定了design width和design height屬性。

  • 這些屬性告訴Visual Studio或Blend在設計器中使用者介面應該有多大,但它們允許它在執行時調整大小。

解決方案資源管理器中,您將看到{project name}TestPage.html檔案,這是在Visual Studio中建立新的Silverlight專案時獲得的預設HTML,如下所示。

Silverlight project

此處的頂部CSS將HTML和body樣式設定為100%,這可能看起來有點奇怪。

這是完整的html檔案,其中包含不同的設定。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
	
<html xmlns = "http://www.w3.org/1999/xhtml" >  
   <head> 
      <title>FirstExample</title> 
		
      <style type = "text/css"> 
         html, body { 
            height: 100%; 
            overflow: auto; 
         } 
			
         body { 
            padding: 0; 
            margin: 0; 
         } 
			
         #silverlightControlHost { 
            height: 100%; 
            text-align:center; 
         } 
      </style>
		
      <script type = "text/javascript" src = "Silverlight.js"></script> 
		
      <script type = "text/javascript"> 
         function onSilverlightError(sender, args) { 
            var appSource = ""; 
				
            if (sender != null && sender != 0) { 
               appSource = sender.getHost().Source; 
            } 
             
            var errorType = args.ErrorType; 
            var iErrorCode = args.ErrorCode;  
				
            if (errorType == "ImageError" || errorType == "MediaError") { 
               return; 
            } 
				
            var errMsg = "Unhandled Error in Silverlight Application " +  appSource + "\n" ;  
            errMsg += "Code: "+ iErrorCode + "    \n"; 
            errMsg += "Category: " + errorType + "       \n"; 
            errMsg += "Message: " + args.ErrorMessage + "     \n";  
				
            if (errorType == "ParserError") { 
               errMsg += "File: " + args.xamlFile + "     \n"; 
               errMsg += "Line: " + args.lineNumber + "     \n"; 
               errMsg += "Position: " + args.charPosition + "     \n"; 
            } else if (errorType == "RuntimeError") {            
               if (args.lineNumber != 0) { 
                  errMsg += "Line: " + args.lineNumber + "     \n"; 
                  errMsg += "Position: " +  args.charPosition + "     \n"; 
               } 
					
               errMsg += "MethodName: " + args.methodName + "     \n"; 
            } 
				
            throw new Error(errMsg); 
         }
			
      </script> 
		
   </head> 
	
   <body>
	
      <form id = "form1" runat = "server" style = "height:100%"> 
         <div id = "silverlightControlHost"> 
			
            <object data = "data:application/x-silverlight-2," 
               type = "application/xsilverlight-2" width = "100%" height = "100%"> 
					
               <param name = "source" value = "ClientBin/FirstExample.xap"/> 
               <param name = "onError" value = "onSilverlightError" /> 
               <param name = "background" value = "white" /> 
               <param name = "minRuntimeVersion" value = "5.0.61118.0" /> 
               <param name = "autoUpgrade" value = "true" /> 
					
               <a href = "http://go.microsoft.com/fwlink/?LinkID=149156&v=5.0.61118.0" 
                  style = "textdecoration:none"> 
                  <img src = "http://go.microsoft.com/fwlink/?LinkId=161376" 
                     alt = "Get Microsoft Silverlight" style = "border-style:none"/> 
               </a> 
					
            </object>
				
            <iframe id = "_sl_historyFrame" style = "visibility:hidden;height:0px; 
               width:0px;border:0px"></iframe>
					
         </div> 
			
      </form> 
		
   </body> 
	
</html>

檢視silverlightControlHost,我們需要確保它以固定高度(例如300畫素)和寬度(例如400畫素)開始,這與XAML中的預設設計寬度和高度相匹配。您還可以根據應用程式需求更改這些設定。

重疊內容

預設情況下,Silverlight和HTML內容無法在螢幕上共享相同的空間。如果您建立了來自兩者都的內容,使其佔據相同空間,則只有Silverlight內容可見。

這是因為,預設情況下,Silverlight會向瀏覽器請求其自己的私有視窗,並將所有內容渲染到該視窗中。它是在瀏覽器內的子視窗,所以看起來像是網頁的一部分,但它阻止了內容重疊。

這樣做的主要原因是效能。透過獲得螢幕上自己的私有區域,Silverlight不必與其渲染與網頁瀏覽器協調。

但是,有時使用重疊內容很有用。這會帶來效能上的代價。您可能會發現當Silverlight和HTML在螢幕上共享空間時,動畫執行不那麼流暢,但額外的佈局靈活性可能值得付出這個代價。要使用重疊內容,您需要啟用無視窗模式。

  • 在無視窗模式下,Silverlight外掛渲染到與瀏覽器相同的目標視窗處理程式,從而允許內容混合。

  • Z索引在內容重疊時非常重要。就HTML而言,Silverlight內容是一個單獨的HTML元素,因此它出現在HTML Z順序中的一個確切位置。

  • 這會影響滑鼠處理。如果Silverlight外掛位於HTML Z順序的頂部,則其邊界框內的任何滑鼠活動都將傳遞到外掛。

  • 即使外掛的某些區域是透明的,並且您可以看到後面的HTML,您也無法點選它。

  • 但是,如果您安排某個HTML內容的Z索引位於頂部,則即使它與Silverlight內容重疊,它也將繼續保持互動性。

示例

請檢視下面給出的簡單示例,其中我們有一個帶有容器的佈局,其中三個div都已安排在此容器內部重疊。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
	
<html xmlns = "http://www.w3.org/1999/xhtml" >  
   <head> 
	
      <title>HtmlOverlap</title> 
		
      <style type = "text/css"> 
         #container { 
            position: relative; 
            height: 300px; 
            font-size: small; 
            text-align:justify; 
         } 
			
         #silverlightControlHost { 
            position: absolute; 
            width: 400px; 
            height: 300px; 
         } 
			
         #underSilverlight { 
            position: absolute; 
            left: 4px; 
            width: 196px; 
         } 
			
         #overSilverlight { 
            position: relative; 
            left: 204px; 
            width: 196px; 
         } 
			
      </style> 
		
      <script type = "text/javascript" src = "Silverlight.js"></script> 
		
      <script type = "text/javascript"> 
         function onSilverlightError(sender, args) { 
            var appSource = ""; 
				
            if (sender != null && sender != 0) { 
               appSource = sender.getHost().Source; 
            } 
             
            var errorType = args.ErrorType; 
            var iErrorCode = args.ErrorCode;
				
            if (errorType == "ImageError" || errorType == "MediaError") { 
               return; 
            }  
				
            var errMsg = "Unhandled Error in Silverlight Application " +  
               appSource + "\n" ;  
					
            errMsg += "Code: "+ iErrorCode + "    \n"; 
            errMsg += "Category: " + errorType + "       \n"; 
            errMsg += "Message: " + args.ErrorMessage + "     \n";  
				
            if (errorType == "ParserError") { 
               errMsg += "File: " + args.xamlFile + "     \n"; 
               errMsg += "Line: " + args.lineNumber + "     \n"; 
               errMsg += "Position: " + args.charPosition + "     \n"; 
            } else if (errorType == "RuntimeError") {            
               if (args.lineNumber != 0) { 
                  errMsg += "Line: " + args.lineNumber + "     \n"; 
                  errMsg += "Position: " +  args.charPosition + "     \n"; 
               } 
					
               errMsg += "MethodName: " + args.methodName + "     \n"; 
            } 
				
            throw new Error(errMsg); 
         } 
      </script>
		
   </head> 
	
   <body> 
      <form id = "form1" runat = "server" style = "height:100%">
		
         <div id = 'container'>
			
            <div id = 'underSilverlight'> 
               This is below. This is below. This is below. This is below. This is below. 
					
               This is below. This is below. This is below. This is below. This is below. 
					
               This is below. This is below. This is below. This is below. This is below. 
					
               This is below. This is below. This is below. This is below. This is below. 
					
               This is below. This is below. This is below. This is below. This is below. 
					
               This is below. This is below. This is below. This is below. This is below. 
					
               This is below. This is below. This is below. This is below. This is below. 
					
               This is below. This is below. This is below. This is below. This is below. 
					
               This is below. This is below. This is below. This is below. This is below. 
					
               This is below. This is below. This is below. This is below. This is below. 
					
               This is below. This is below. This is below. This is below. This is below. 
					
               This is below. This is below. This is below. This is below. This is below. 
            </div> 
				
            <div id = "silverlightControlHost"> 
				
               <object data = "data:application/x-silverlight-2," 
                  type = "application/xsilverlight-2" width = "100%" height = "100%"> 
						
                  <param name = "source" value = "ClientBin/HtmlOverlap.xap"/> 
                  <param name = "onError" value = "onSilverlightError" /> 
                  <param name = "background" value = "transparent" /> 
                  <param name = "windowless" value = "true" /> 
                  <param name = "minRuntimeVersion" value = "4.0.50401.0" /> 
                  <param name = "autoUpgrade" value = "true" /> 
						
                  <a href = "http://go.microsoft.com/fwlink/?LinkID=149156&v=4.0.50401.0" 
                     style = "text-decoration:none"> 
							
                  <img src = "http://go.microsoft.com/fwlink/?LinkId=161376" 
                     alt = "Get Microsoft Silverlight" style = "border-style:none"/> </a> 
							
               </object>
					
               <iframe id = "_sl_historyFrame" style = "visibility:hidden; height:0px; 
                  width:0px; border:0px"> </iframe>
						
            </div> 
				
            <div id = 'overSilverlight'> 
               This is on top. This is on top. This is on top. This is on top. 
                  This is on top. This is on top.
						
               This is on top. This is on top. This is on top. This is on top. 
                  This is on top. This is on top. 
						
               This is on top. This is on top. This is on top. This is on top. 
                  This is on top. This is on top. 
						
               This is on top. This is on top. This is on top. This is on top. 
                  This is on top. This is on top. 
						
               This is on top. This is on top. This is on top. This is on top. 
                  This is on top. This is on top. 
						
               This is on top. This is on top. This is on top. This is on top. 
                  This is on top. This is on top. 
						
               This is on top. This is on top. This is on top. This is on top. 
                  This is on top. This is on top.
						
               This is on top. This is on top. This is on top. This is on top. 
                  This is on top. This is on top. 
						
               This is on top. This is on top. This is on top. This is on top. 
            </div>
				
         </div>    
			
      </form> 
		
   </body> 
	
</html>
  • 此div將移到左側,並且位於Z順序的後面,因為它排在第一位。

  • 然後在中間,我們有Silverlight內容,它將填充整個寬度。

  • 然後在其頂部,右側有一個div包含文字-這是在頂部

下面給出的是XAML檔案,其中添加了一個矩形並設定了一些屬性。

<UserControl x:Class = "HtmlOverlap.MainPage" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   mc:Ignorable = "d" 
   d:DesignHeight = "300" d:DesignWidth = "400">
	
   <Grid x:Name = "LayoutRoot"> 
      <Rectangle Margin = "0,120" Fill = "Aquamarine" />    
   </Grid> 
	
</UserControl>

執行此應用程式時,您將看到兩列,一列在左側顯示“下方”,另一列在右側顯示“上方”。Silverlight外掛位於這兩者的同一區域,並且在Z順序中,Silverlight內容在這兩者之間。

Overlapping Content

您可以看到此處的半透明綠色填充稍微著色了左側的文字,因為它位於該文字的頂部,但它沒有著色右側的文字,因為它位於該文字的後面。

您可以選擇右側的文字。如果嘗試使用左側的此文字,則不會發生任何事情,這是因為就瀏覽器而言,此處的整個空間都被Silverlight控制元件佔用。由於它位於Z順序中文字的上面,因此Silverlight控制元件負責處理輸入。

Silverlight - 控制元件

所有控制元件都具有一定的互動行為,例如,滑鼠懸停在按鈕上時按鈕亮起以及按下時按鈕按下、列表框的滾動和選擇行為。在所有情況下,控制元件都超出了簡單的可見性。它可能比看起來更復雜。這些控制元件是父控制元件和程式碼的組合。Silverlight允許開發人員輕鬆構建和建立視覺豐富的基於UI的應用程式。控制元件使Silverlight與其他元素區分開來。

一些重要的特性是:

  • 其他UI框架中的經典UI元素或控制元件在Silverlight應用程式中也得到了增強。

  • 幾乎所有標準的Silverlight控制元件都可以在工具箱中找到,工具箱是System.Windows.Controls的一部分。

  • 這些控制元件也可以在XAML標記語言中建立。

Silverlight控制元件的完整繼承層次結構如下所示:

Silverlight Controls

Silverlight - 按鈕

Button類表示最基本的按鈕控制元件型別。Silverlight識別三種類型的按鈕控制元件:熟悉的ButtonCheckBoxRadioButton。所有這些控制元件都是從ButtonBase派生的內容控制元件。Button類的層次繼承如下所示:

Hierarchical Inheritance Button

下面列出了按鈕最常用的屬性

序號 屬性和描述
1

Background

獲取或設定一個畫刷,該畫刷提供控制元件的背景。(從Control繼承)

2

BorderBrush

獲取或設定一個畫刷,該畫刷描述控制元件的邊框填充。(從Control繼承)

3

BorderThickness

獲取或設定控制元件的邊框粗細。(從Control繼承)

4

Content

獲取或設定ContentControl的內容。(從ContentControl繼承)

5

ClickMode

獲取或設定一個值,該值指示Click事件何時發生,以裝置行為表示。(從ButtonBase繼承)

6

ContentTemplate

獲取或設定用於顯示ContentControl內容的資料模板。(從ContentControl繼承)

7

FontFamily

獲取或設定用於在控制元件中顯示文字的字型。(從Control繼承)

8

FontSize

獲取或設定此控制元件中文字的大小。(從Control繼承)

9

FontStyle

獲取或設定呈現文字的樣式。(從Control繼承)

10

FontWeight

獲取或設定指定字型的粗細。(從Control繼承)

11

Foreground

獲取或設定一個畫刷,該畫刷描述前景色。(從Control繼承)

12

Height

獲取或設定FrameworkElement的建議高度。(從FrameworkElement繼承)

13

HorizontalAlignment

獲取或設定應用於FrameworkElement的水平對齊特性,當它在佈局父級(如面板或項控制元件)中組合時。(從FrameworkElement繼承)

14

IsEnabled

獲取或設定一個值,指示使用者是否可以與控制元件互動。(從Control繼承)

15

IsPressed

獲取一個值,指示ButtonBase當前是否處於按下狀態。(從ButtonBase繼承)

16

Margin

獲取或設定FrameworkElement的外邊距。(從FrameworkElement繼承)

17

Name

獲取或設定物件的標識名稱。當XAML處理器從XAML標記建立物件樹時,執行時程式碼可以透過此名稱引用XAML宣告的物件。(從FrameworkElement繼承)

18

Opacity

獲取或設定物件的透明度。(從UIElement繼承)

19

Resources

獲取本地定義的資源字典。在XAML中,您可以將資源項作為frameworkElement.Resources屬性元素的子物件元素建立,透過XAML隱式集合語法。(從FrameworkElement繼承)

20

Style

獲取或設定一個例項Style,該Style在佈局和渲染期間應用於此物件。(從FrameworkElement繼承)

21

Template

獲取或設定控制元件模板。控制元件模板定義了控制元件在UI中的視覺外觀,並在XAML標記中定義。(從Control繼承)

22

VerticalAlignment

獲取或設定應用於FrameworkElement的垂直對齊特性,當它在父物件(如面板或項控制元件)中組合時。(從FrameworkElement繼承)

23

Visibility

獲取或設定UIElement的可見性。不可見的UIElement不會呈現,也不會將其所需的大小傳達給佈局。(從UIElement繼承)

24

Width

獲取或設定FrameworkElement的寬度。(從FrameworkElement繼承)

下面列出了按鈕常用的方法

序號 方法及描述
1

ClearValue

清除依賴屬性的本地值。(從DependencyObject繼承)

2

FindName

檢索具有指定識別符號名稱的物件。(從FrameworkElement繼承)

3

OnApplyTemplate

每當應用程式程式碼或內部程序(例如重建佈局傳遞)呼叫ApplyTemplate時都會呼叫。簡單來說,這意味著該方法在UI元素在應用程式中顯示之前被呼叫。重寫此方法以影響類的預設模板後邏輯。(從FrameworkElement繼承)

4

OnContentChanged

當Content屬性的值更改時呼叫。(從ContentControl繼承)

5

OnDragEnter

在DragEnter事件發生之前呼叫。(從Control繼承)

6

OnDragLeave

在DragLeave事件發生之前呼叫。(從Control繼承)

7

OnDragOver

在DragOver事件發生之前呼叫。(從Control繼承)

8

OnDrop

在Drop事件發生之前呼叫。(從Control繼承)

9

OnGotFocus

在GotFocus事件發生之前呼叫。(從Control繼承)

10

OnKeyDown

在KeyDown事件發生之前呼叫。(從Control繼承)

11

OnKeyUp

在KeyUp事件發生之前呼叫。(從Control繼承)

12

OnLostFocus

在LostFocus事件發生之前呼叫。(從Control繼承)

13

SetBinding

使用提供的繫結物件將繫結附加到FrameworkElement。(從FrameworkElement繼承)

下面列出了按鈕常用的事件

序號 事件及說明
1

Click

當點選按鈕控制元件時發生。(從ButtonBase繼承)

2

DataContextChanged

當FrameworkElement.DataContext屬性的值更改時發生。(從FrameworkElement繼承)

3

DragEnter

當輸入系統報告以該元素作為目標的底層拖動事件時發生。(從UIElement繼承)

4

DragLeave

當輸入系統報告以該元素為原點的底層拖動事件時發生。(繼承自 UIElement)

5

DragOver

當輸入系統報告以該元素為潛在放置目標的底層拖動事件時發生。(繼承自 UIElement)

6

DragStarting

當拖動操作開始時發生。(繼承自 UIElement)

7

GotFocus

當 UIElement 獲得焦點時發生。(繼承自 UIElement)

8

Holding

當在此元素的命中測試區域上發生其他未處理的按住互動時發生。(繼承自 UIElement)

9

IsEnabledChanged

當 IsEnabled 屬性更改時發生。(繼承自 Control)

10

KeyDown

當 UIElement 具有焦點時按下鍵盤鍵時發生。(繼承自 UIElement)

11

KeyUp

當 UIElement 具有焦點時釋放鍵盤鍵時發生。(繼承自 UIElement)

12

LostFocus

當 UIElement 失去焦點時發生。(繼承自 UIElement)

13

SizeChanged

當 FrameworkElement 上的 ActualHeight 或 ActualWidth 屬性的值發生更改時發生。(繼承自 FrameworkElement)

序號 按鈕和說明
1 HyperlinkButton

HyperlinkButton 不會繪製標準按鈕背景。相反,它只是呈現您提供的內容。

2 ToggleButton 和 RepeatButton

RepeatButton 控制元件持續觸發 Click 事件,只要按鈕被按下。ToggleButton 控制元件表示具有兩種狀態(已點選或未點選)的按鈕。

3 CheckBox

使用者可以選擇(選中)或取消選擇(取消選中)的控制元件。它提供使用者可以選擇的一系列選項,例如應用於應用程式的一系列設定。

4 RadioButton

RadioButton 是一個按鈕,允許使用者從一組選項中選擇單個選項。

Silverlight - 內容模型

這些按鈕為模型內容提供了一種內容形式。模型在控制元件中大量出現。這個想法很簡單。它將接受任何內容,而不僅僅是文字。如果您想建立一個真正奇特的按鈕,您甚至可以將其他內容控制元件(例如文字框和按鈕)放在裡面(並在這些控制元件中巢狀更多元素)。這種介面不太可能有什麼意義,但它是可能的。

讓我們來看一個簡單的示例,其中按鈕內包含其他內容控制元件。

<UserControl x:Class = "ContentModel.MainPage" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   mc:Ignorable = "d" 
   d:DesignHeight = "300" d:DesignWidth = "400">
   
   <Grid x:Name = "LayoutRoot" Background = "White"> 
	
      <Button Margin = "3" Height = "70" Width = "215"> 
         <Grid Margin = "5"> 
            <Polygon Points = "100,25 125,0 200,25 125,50" Fill = "LightSteelBlue" /> 
            <Polygon Points = "100,25 75,0 0,25 75,50" Fill = "LightGray"/> 
         </Grid> 
      </Button> 
		
   </Grid> 
	
</UserControl>

編譯並執行上述程式碼後,您將看到以下按鈕。

Content Controls

RangeControl

捲軸和滑塊控制元件密切相關。它們都允許使用者從特定範圍內選擇輸入值。通常,這些控制元件表示不同的含義。捲軸通常用於設定滾動區域中的位置,而滑塊用於指定某個值或設定。這些僅僅是約定;控制元件具有類似的行為和 API。

範圍控制元件易於使用。您指定最小值和最大值以指示您希望滑塊表示的值範圍。Value 屬性將隨著使用者拖動的變化而變化。

Slider 類的層次繼承如下:

Inheritance of Slider

以下是 Slider 的常用屬性

序號 屬性和描述
1

Header

獲取或設定控制元件標題的內容。

2

HeaderProperty

標識 Header 依賴屬性。

3

HeaderTemplate

獲取或設定用於顯示控制元件標題內容的 DataTemplate。

4

HeaderTemplateProperty

標識 HeaderTemplate 依賴屬性。

5

IntermediateValue

獲取或設定使用者與滑塊互動期間的值,在該值捕捉到刻度或步進值之前。SnapsTo 屬性指定滑塊的值。

6

IntermediateValueProperty

標識 IntermediateValue 依賴屬性。

7

IsDirectionReversed

獲取或設定一個值,該值指示值的增加方向。

8

IsDirectionReversedProperty

標識 IsDirectionReversed 依賴屬性。

9

IsThumbToolTipEnabled

獲取或設定一個值,該值確定是否在 Slider 的 Thumb 元件的工具提示中顯示滑塊值。

10

IsThumbToolTipEnabledProperty

標識 IsThumbToolTipEnabled 依賴屬性。

11

Orientation

獲取或設定 Slider 的方向。

12

OrientationProperty

標識 Orientation 依賴屬性。

13

StepFrequency

獲取或設定應為其建立步進的值範圍的一部分。

14

StepFrequencyProperty

標識 StepFrequency 依賴屬性。

15

ThumbToolTipValueConverter

獲取或設定將 Slider 的範圍值轉換為工具提示內容的轉換器邏輯。

16

ThumbToolTipValueConverterProperty

標識 ThumbToolTipValueConverter 依賴屬性。

17

TickFrequency

獲取或設定應為其建立刻度的值範圍的增量。

18

TickFrequencyProperty

標識 TickFrequency 依賴屬性。

19

TickPlacement

獲取或設定一個值,該值指示相對於軌道繪製刻度標記的位置。

20

TickPlacementProperty

標識 TickPlacement 依賴屬性。

以下是 Slider 類中常用的事件

序號 事件及說明
1

ManipulationCompleted

當對 UIElement 的操作完成時發生。(繼承自 UIElement)

2

ManipulationDelta

當輸入裝置在操作期間更改位置時發生。(繼承自 UIElement)

3

ManipulationInertiaStarting

當輸入裝置在操作期間與 UIElement 物件失去接觸並開始慣性時發生。(繼承自 UIElement)

4

ManipulationStarted

當輸入裝置開始對 UIElement 進行操作時發生。(繼承自 UIElement)

5

ManipulationStarting

當第一次建立操作處理器時發生。(繼承自 UIElement)

6

ValueChanged

當範圍值更改時發生。(繼承自 RangeBase)

以下是 Slider 類中常用的方法

序號 方法及描述
1

OnManipulationCompleted

在 ManipulationCompleted 事件發生之前呼叫。(繼承自 Control)

2

OnManipulationDelta

在 ManipulationDelta 事件發生之前呼叫。(繼承自 Control)

3

OnManipulationInertiaStarting

在 ManipulationInertiaStarting 事件發生之前呼叫。(繼承自 Control)

4

OnManipulationStarted

在 ManipulationStarted 事件發生之前呼叫。(繼承自 Control)

5

OnManipulationStarting

在 ManipulationStarting 事件發生之前呼叫。(繼承自 Control)

6

OnMaximumChanged

當 Maximum 屬性更改時呼叫。(繼承自 RangeBase)

7

OnMinimumChanged

當 Minimum 屬性更改時呼叫。(繼承自 RangeBase)

8

OnValueChanged

觸發 ValueChanged 路由事件。(繼承自 RangeBase)

9

SetBinding

使用提供的繫結物件將繫結附加到FrameworkElement。(從FrameworkElement繼承)

10

SetValue

設定 DependencyObject 上依賴屬性的本地值。(繼承自 DependencyObject)

示例

讓我們來看一個簡單的示例,其中添加了一個滑塊和一個橢圓,並且滑塊控制橢圓的寬度。

<UserControl x:Class = "SliderExample.MainPage" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" xmlns:mc = "
   http://schemas.openxmlformats.org/markup-compatibility/2006"  
   mc:Ignorable = "d" d:DesignWidth = "640" d:DesignHeight = "480"> 
   
   <Grid x:Name = "LayoutRoot">
	
      <Grid.RowDefinitions> 
         <RowDefinition Height = "Auto" /> 
         <RowDefinition /> 
      </Grid.RowDefinitions>  
		
      <Slider Minimum = "1" Maximum = "400" Value = "1" 
         ValueChanged = "Slider_ValueChanged" />  
			
      <Ellipse Grid.Row = "1" Fill = "Aqua" Width = "1" x:Name = "myEllipse" /> 
		
   </Grid> 
	
</UserControl>

以下是 C# 中的值更改事件實現。

using System.Windows; 
using System.Windows.Controls; 
 
namespace SliderExample { 

   public partial class MainPage : UserControl { 
	
      public MainPage() { 
         InitializeComponent(); 
      }
	  
      private void Slider_ValueChanged(object sender, 
         RoutedPropertyChangedEventArgs<double> e) { 
			
            if (myEllipse != null) { 
               myEllipse.Width = e.NewValue; 
            } 
      } 
   } 
}

編譯並執行上述程式碼後,您將看到以下輸出。如您所見,當您將滑塊從左向右移動時,橢圓的寬度會增加。

Add Slider And Ellipse

Silverlight - ListBox

Listbox 是一種控制元件,它為使用者提供專案列表以供選擇。使用者可以一次從預定義的專案列表中選擇一個或多個專案。在ListBox 中,多個選項始終對使用者可見,無需任何使用者互動。

Listbox 顯示一個可滾動的專案列表。如果使用者選擇一個專案,則所選專案的顯示外觀將發生變化以指示選擇。它支援更廣泛的內容模型和按鈕。按鈕和列表框之間的主要區別在於,按鈕包含單個內容,而列表框允許列表中的每個專案。

ListBox 類的層次繼承如下:

Inheritance Listbox

以下是 ListBox 類中常用的屬性

序號 屬性和描述
1

Background

獲取或設定一個畫刷,該畫刷提供控制元件的背景。(從Control繼承)

2

BorderThickness

獲取或設定控制元件的邊框粗細。(從Control繼承)

3

FontFamily

獲取或設定用於在控制元件中顯示文字的字型。(從Control繼承)

4

FontSize

獲取或設定此控制元件中文字的大小。(從Control繼承)

5

FontStyle

獲取或設定呈現文字的樣式。(從Control繼承)

6

FontWeight

獲取或設定指定字型的粗細。(從Control繼承)

7

Foreground

獲取或設定一個畫刷,該畫刷描述前景色。(從Control繼承)

8

GroupStyle

獲取 GroupStyle 物件的集合,這些物件定義每一級組的外觀。(繼承自 ItemsControl)

9

Height

獲取或設定FrameworkElement的建議高度。(從FrameworkElement繼承)

10

HorizontalAlignment

獲取或設定應用於FrameworkElement的水平對齊特性,當它在佈局父級(如面板或項控制元件)中組合時。(從FrameworkElement繼承)

11

IsEnabled

獲取或設定一個值,指示使用者是否可以與控制元件互動。(從Control繼承)

12

Item

獲取用於生成控制元件內容的集合。(繼承自 ItemsControl)

13

ItemsSource

獲取或設定用於生成 ItemsControl 內容的物件源。(繼承自 ItemsControl)

14

Margin

獲取或設定FrameworkElement的外邊距。(從FrameworkElement繼承)

15

Name

獲取或設定物件的標識名稱。當 XAML 處理器從 XAML 標記建立物件樹時,執行時程式碼可以透過此名稱引用 XAML 宣告的物件。(繼承自 FrameworkElement)

16

Opacity

獲取或設定物件的透明度。(從UIElement繼承)

17

SelectedIndex

獲取或設定所選專案的索引。(繼承自 Selector)

18

SelectedItem

獲取或設定所選專案。(繼承自 Selector)

19

SelectedValue

獲取或設定所選專案的值,透過使用 SelectedValuePath 獲取。(繼承自 Selector)

20

Style

獲取或設定一個例項Style,該Style在佈局和渲染期間應用於此物件。(從FrameworkElement繼承)

21

VerticalAlignment

獲取或設定應用於FrameworkElement的垂直對齊特性,當它在父物件(如面板或項控制元件)中組合時。(從FrameworkElement繼承)

22

Width

獲取或設定FrameworkElement的寬度。(從FrameworkElement繼承)

以下是 ListBox 的常用事件

序號 事件及說明
1

DragEnter

當輸入系統報告以該元素作為目標的底層拖動事件時發生。(從UIElement繼承)

2

DragLeave

當輸入系統報告以該元素為原點的底層拖動事件時發生。(繼承自 UIElement)

3

DragOver

當輸入系統報告以該元素為潛在放置目標的底層拖動事件時發生。(繼承自 UIElement)

4

DragStarting

當拖動操作開始時發生。(繼承自 UIElement)

5

Drop

當輸入系統報告以該元素為放置目標的底層放置事件時發生。(繼承自 UIElement)

6

DropCompleted

當拖放操作結束時發生。(繼承自 UIElement)

7

GotFocus

當 UIElement 獲得焦點時發生。(繼承自 UIElement)

8

IsEnabledChanged

當 IsEnabled 屬性更改時發生。(繼承自 Control)

9

KeyDown

當 UIElement 具有焦點時按下鍵盤鍵時發生。(繼承自 UIElement)

10

KeyUp

當 UIElement 具有焦點時釋放鍵盤鍵時發生。(繼承自 UIElement)

11

LostFocus

當 UIElement 失去焦點時發生。(繼承自 UIElement)

12

SelectionChanged

噹噹前選定的專案更改時發生。(繼承自 Selector)

13

SizeChanged

當 FrameworkElement 上的 ActualHeight 或 ActualWidth 屬性的值發生更改時發生。(繼承自 FrameworkElement)

以下是 ListBox 的常用方法

序號 方法及描述
1

Arrange

定位子物件並確定 UIElement 的大小。實現其子元素自定義佈局的父物件應從其佈局覆蓋實現中呼叫此方法,以形成遞迴佈局更新。(繼承自 UIElement)

2

FindName

檢索具有指定識別符號名稱的物件。(從FrameworkElement繼承)

3

Focus

嘗試將焦點設定到控制元件上。(繼承自 Control)

4

GetValue

返回 DependencyObject 上依賴屬性的當前有效值。(繼承自 DependencyObject)

5

IndexFromContainer

返回具有指定生成容器的專案的索引。(繼承自 ItemsControl)

6

OnDragEnter

在DragEnter事件發生之前呼叫。(從Control繼承)

7

OnDragLeave

在DragLeave事件發生之前呼叫。(從Control繼承)

8

OnDragOver

在DragOver事件發生之前呼叫。(從Control繼承)

9

OnDrop

在Drop事件發生之前呼叫。(從Control繼承)

10

OnKeyDown

在KeyDown事件發生之前呼叫。(從Control繼承)

11

OnKeyUp

在KeyUp事件發生之前呼叫。(從Control繼承)

12

OnLostFocus

在LostFocus事件發生之前呼叫。(從Control繼承)

13

ReadLocalValue

返回依賴屬性的本地值(如果設定了本地值)。(繼承自 DependencyObject)

14

SetBinding

使用提供的繫結物件將繫結附加到FrameworkElement。(從FrameworkElement繼承)

15

SetValue

設定 DependencyObject 上依賴屬性的本地值。(繼承自 DependencyObject)

讓我們來看一個簡單的示例,其中在ListBox 中添加了不同的 UI 元素。

<UserControl x:Class = "ListBoxExample.MainPage" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006"  
   mc:Ignorable = "d" d:DesignWidth = "640" d:DesignHeight = "480"> 
   
   <Grid x:Name = "LayoutRoot">
	
      <ListBox x:Name = "myList">
		
         <TextBlock Text = "First item" /> 
         <Button Content = "Second item" /> 
         <Path Fill = "Blue" Data = "M4,0 l-4,10 8,0z M15,0 l-4,10 8,0z M26,0 l4,10 8,0z" 
            Margin = "10" /> 
			
         <StackPanel Orientation = "Horizontal"> 
            <Ellipse Fill = "Red" Height = "30" Width = "100" /> 
            <TextBlock Text = "Name: " /> 
            <TextBox Width = "200" /> 
         </StackPanel>
			
         <TextBlock Text = "More..." /> 
			
      </ListBox> 
		
   </Grid>
	
</UserControl>

以下是 C# 實現。

using System.Windows.Controls; 
 
namespace ListBoxExample { 

   public partial class MainPage : UserControl { 
	
      public MainPage() { 
         InitializeComponent();  
			
         myList.Items.Add("String entry"); 
         myList.Items.Add(new Button { Content = "Content entry" });  
      } 
   } 
}

編譯並執行上述程式碼後,您將看到一個列表框,其中包含圖形文字的混合,以及一個可編輯的欄位,您可以在其中鍵入文字。

Add  UI Element in ListBox

序號 控制元件及描述
1 Calendar 和 DatePicker

日曆和日期選擇器表示一個控制元件,使用者可以透過視覺化日曆顯示來選擇日期。它提供了一些基本的滑鼠或鍵盤導航。

2 選項卡控制元件

一個容器,將專案放置到單獨的選項卡中,並允許使用者一次只檢視一個選項卡。它允許使用者透過點選選項卡標題從多個不同的檢視中進行選擇。

3 彈出視窗

此類在應用程式視窗的範圍內,將內容顯示在現有內容之上。它是在其他內容上臨時顯示。

4 工具提示

工具提示表示一個控制元件,它建立一個彈出視窗,用於顯示 GUI 中元素的資訊。Silverlight 允許您將工具提示附加到任何控制元件。

Silverlight - 模板

一個模板描述了控制元件的整體外觀和視覺外觀。每個控制元件都與其關聯一個預設模板,該模板賦予該控制元件外觀。

在 WPF 應用程式中,當您想要自定義控制元件的視覺行為和視覺外觀時,可以輕鬆建立自己的模板。

一些重要的特性是:

  • 所有 UI 元素都具有一定的外觀和行為,例如按鈕具有外觀和行為。

  • 單擊事件或滑鼠懸停事件是行為,它們響應單擊和懸停而觸發,並且按鈕有一個預設外觀,可以透過控制元件模板更改。

讓我們再次看一個簡單的示例,其中使用模板定義了一個按鈕。

<UserControl x:Class = "ButtonTemplate.MainPage" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006"  
   mc:Ignorable = "d" d:DesignWidth = "640" d:DesignHeight = "480"> 
   
   <Grid x:Name = "LayoutRoot" HorizontalAlignment = "Center" 
      VerticalAlignment = "Center">
		
      <Button Height = "100" Width = "100" Content = "Click!" 
         HorizontalContentAlignment = "Left" Click = "button_Click">
			
         <Button.Template> 
            <ControlTemplate TargetType = "Button"> 
				
               <Grid> 
					
                  <Ellipse Fill = "Gray" Stroke = "Black" 
                     StrokeThickness = "3" Margin = "-64,0,0,0" /> 
							
                  <ContentPresenter HorizontalAlignment = "{TemplateBinding 
                     HorizontalContentAlignment}" VerticalAlignment = "Center" 
                     Content = "{TemplateBinding Content}" /> 
               </Grid> 
					
            </ControlTemplate>
				
         </Button.Template>
			
      </Button>  
		
   </Grid> 
	
</UserControl> 

編譯並執行上述程式碼後,您將看到以下輸出。

Click Button

連線模板

我們想要模板化的所有控制元件功能都使用模板繫結。某些方面稍微複雜一些。例如,無論何時您擁有某種內容模型,僅使用模板繫結是不夠的,如您在按鈕上看到的。我們還必須使用內容呈現器,如上例所示。

Silverlight - 可視狀態

如果您的使用者能夠分辨出應用程式的哪個部分可能響應輸入,那將是很好的。在某種程度上,可以透過使按鈕看起來像按鈕來做到這一點。如果某物看起來可點選,它可能就是可點選的。

但是,現代使用者介面設計的慣例是,使用者介面元素還應該透過在滑鼠移動到它們上面時更改其外觀來表示其響應意願。

例如,內建的按鈕控制元件在滑鼠移到上面時會稍微更改其背景,以暗示它是互動式的,然後在單擊時進一步更改其外觀,使其看起來像被選中。幾乎所有控制元件都需要這樣做,並且設計人員需要一種方法來建立和編輯動畫以使其發生。

狀態和狀態組

讓我們看一個視覺狀態在實際應用中的示例。考慮一個複選框。它可以是未選中或選中狀態,如果您選擇,它可以支援第三種不確定狀態。對於所有三種情況,控制元件都需要看起來有所不同。因此,我們有三個視覺狀態。

State Group Checkbox

為了表明它已準備好響應使用者輸入,複選框在滑鼠移到它上面時會稍微更改其外觀,並且在滑鼠保持在該位置時會進一步更改。如果複選框被停用,則需要考慮第四種狀態,它看起來是灰色的,並表示它不會響應使用者輸入。

Changes Checkbox

因此,這裡還有另外四種狀態。在任何給定時間,複選框的視覺狀態必須是正常、滑鼠懸停、選中停用之一。同時,它必須是選中、未選中不確定之一。

視覺狀態管理器

由於其模板定義了控制元件的外觀,因此模板需要定義每個視覺狀態發生的情況。我們到目前為止看到的模板不包含此類資訊。因此,無論控制元件的當前狀態如何,控制元件的外觀都保持靜態。

要向模板新增視覺狀態,您可以從新增屬性元素開始。

  • 對於視覺狀態處理,您可以做的最簡單的事情是定義在控制元件進入特定狀態時將執行的動畫。

  • 控制元件在每次更改狀態時都會通知視覺狀態管理器類。

  • 然後,視覺狀態管理器會檢視模板的這一部分,並確定要執行哪個動畫。

  • 因此,當複選框進入滑鼠懸停狀態時,此動畫將執行,更改模板某些部分的顏色。

讓我們看一個簡單的示例,使用視覺狀態機制為複選框建立一個自定義模板,以反映狀態更改。

下面是帶有視覺狀態的複選框自定義模板的 XAML 程式碼。

<UserControl 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   x:Class = "CheckboxVisualState.Page" 
   Width = "640" Height="480" 
   xmlns:vsm = "clrnamespace:System.Windows;assembly = System.Windows" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   mc:Ignorable = "d"> 
   
   <UserControl.Resources> 
      <ControlTemplate x:Key = "CheckBoxControlTemplate1" TargetType = "CheckBox"> 
	
         <Grid> 
		
            <vsm:VisualStateManager.VisualStateGroups> 
			
               <vsm:VisualStateGroup x:Name = "FocusStates"> 
                  <vsm:VisualState x:Name = "ContentFocused"/> 
                  <vsm:VisualState x:Name = "Focused"/> 
                  <vsm:VisualState x:Name = "Unfocused"/>
               </vsm:VisualStateGroup> 
				
               <vsm:VisualStateGroup x:Name = "CommonStates"> 
				
                  <vsm:VisualStateGroup.Transitions> 
                     <vsm:VisualTransition GeneratedDuration = "00:00:00.5000000"/> 
                  </vsm:VisualStateGroup.Transitions> 
					
                  <vsm:VisualState x:Name = "MouseOver"> 
					
                     <Storyboard>
						
                        <ColorAnimationUsingKeyFrames BeginTime = "00:00:00" 
                           Duration = "00:00:00.0010000" Storyboard.TargetName = "background" 
                           Storyboard.TargetProperty = "(Shape.Fill).
                           (SolidColorBrush.Color)"> 
									
                              <SplineColorKeyFrame KeyTime = "00:00:00" Value = "#FFFF0000"/> 
                        </ColorAnimationUsingKeyFrames> 
							
                     </Storyboard> 
						
                  </vsm:VisualState>
					
                  <vsm:VisualState x:Name = "Pressed"> 
					
                     <Storyboard>
						
                        <ColorAnimationUsingKeyFrames BeginTime = "00:00:00" 
                           Duration = "00:00:00.0010000" Storyboard.TargetName = "background" 
                           Storyboard.TargetProperty = "(Shape.Fill).
                           (SolidColorBrush.Color)"> 
									
                              <SplineColorKeyFrame KeyTime = "00:00:00" Value = "#FFCEFF00"/> 
                        </ColorAnimationUsingKeyFrames>
							
                     </Storyboard> 
						
                  </vsm:VisualState>
					
                  <vsm:VisualState x:Name = "Disabled"/> 
                  <vsm:VisualState x:Name = "Normal"/> 
					
               </vsm:VisualStateGroup> 
				
               <vsm:VisualStateGroup x:Name = "CheckStates">
				
                  <vsm:VisualStateGroup.Transitions> 
                     <vsm:VisualTransition GeneratedDuration = "00:00:00.5000000"/> 
                  </vsm:VisualStateGroup.Transitions> 
					
                  <vsm:VisualState x:Name = "Checked">
					
                     <Storyboard> 
						
                        <DoubleAnimationUsingKeyFrames BeginTime = "00:00:00" 
                           Duration = "00:00:00.0010000" Storyboard.TargetName = "checkPath" 
                           Storyboard.TargetProperty = "(UIElement.Opacity)"> 
									
                              <SplineDoubleKeyFrame KeyTime = "00:00:00" Value = "1"/> 
                        </DoubleAnimationUsingKeyFrames> 
							
                     </Storyboard> 
						
                  </vsm:VisualState> 
					
                  <vsm:VisualState x:Name = "Unchecked"/> 
                  <vsm:VisualState x:Name = "Indeterminate"/> 
					
               </vsm:VisualStateGroup> 
				
            </vsm:VisualStateManager.VisualStateGroups> 
			
            <Grid.ColumnDefinitions> 
			
               <ColumnDefinition Width = "Auto"/> 
                  <ColumnDefinition Width = "3.61782296696066"/> 
               <ColumnDefinition Width = "Auto"/> 
				
            </Grid.ColumnDefinitions> 
			
            <Canvas Height = "50" HorizontalAlignment = "Left" VerticalAlignment = "Top" 
               Width = "50">
				
               <Rectangle Height = "33.746" x:Name = "background" Width = "33.746" 
                  Canvas.Left = "8.452" Canvas.Top = "7.88" Fill = "#FFFFFFFF" 
                  Stroke = "#FF000000" 
                  RadiusX = "5.507" RadiusY = "5.507"/> 
						
               <Path Height = "40.25" x:Name = "checkPath" Width = "39.75" Opacity = "0" 
                  Canvas.Left = "5.959" Canvas.Top = "7.903" Stretch = "Fill" 
                  Stroke = "#FF1F9300" StrokeThickness = "3" 
                  Data = "M1.5,1.5 C15.495283,8.7014561 27.056604,18.720875 33.75,33.75 
                  M36,3.75 C22.004717,10.951456 10.443395,20.970875 3.7499986,36"/> 
						
            </Canvas> 
				
            <ContentPresenter HorizontalAlignment = "Left" 
               Margin = "{TemplateBinding Padding}" 
               VerticalAlignment = "{TemplateBinding VerticalContentAlignment}" 
               Grid.Column = "2" Grid.ColumnSpan = "1" d:LayoutOverrides = "Height"/>
					
         </Grid> 
		
      </ControlTemplate> 
	
   </UserControl.Resources> 
 
   <Grid x:Name = "LayoutRoot" Background = "White" > 
      <CheckBox HorizontalAlignment = "Left" 
         Margin = "52.5410003662109,53.5970001220703,0,0" VerticalAlignment = "Top" 
         Template = "{StaticResource CheckBoxControlTemplate1}" 
         Content = "CheckBox"/> 
   </Grid>
	
</UserControl>

編譯並執行上述程式碼後,您將看到以下網頁,其中包含一個複選框

Template Checkbox

當游標進入複選框區域時,它將更改狀態。

Change The State

單擊複選框時,您將看到以下狀態。

Execute Change The State

我們建議您執行上述示例以更好地理解。

Silverlight - 資料繫結

資料繫結是 Silverlight 應用程式中的一種機制,它為使用部分類的 Windows 執行時應用程式提供了一種簡單易行的方式來顯示和互動資料。在此機制中,資料的管理與資料在使用者介面中顯示的方式完全分離。資料繫結允許資料在 UI 元素和使用者介面上的資料物件之間流動。當建立繫結並且資料或您的業務模型發生變化時,它將自動將更新反映到 UI 元素,反之亦然。也可以繫結到頁面上的另一個元素,而不是繫結到標準資料來源。

資料繫結分為以下兩種型別:

  • 單向資料繫結
  • 雙向資料繫結

單向資料繫結

在單向資料繫結中,資料從其源(即儲存資料的物件)繫結到其目標(即顯示資料的物件)。

讓我們看一個簡單的單向資料繫結示例。

下面是 XAML 程式碼,其中建立了兩個標籤、兩個文字框和一個按鈕,並設定了一些屬性。

<UserControl x:Class = "DataBinding.MainPage" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   mc:Ignorable = "d" 
   d:DesignHeight = "300" d:DesignWidth = "400">
   
   <Grid x:Name = "LayoutRoot" Background = "White"> 
	
      <Grid.RowDefinitions> 
         <RowDefinition Height = "Auto" /> 
         <RowDefinition Height = "Auto" /> 
         <RowDefinition Height = "*" /> 
      </Grid.RowDefinitions> 
		
      <Grid.ColumnDefinitions> 
         <ColumnDefinition Width = "Auto" /> 
         <ColumnDefinition Width = "200" />
      </Grid.ColumnDefinitions> 
		
      <TextBlock Name = "nameLabel" Margin = "2">Name:</TextBlock> 
      <TextBox Name = "nameText" Grid.Column = "1" Margin = "2" 
         Text = "{Binding Name, Mode=OneWay}"/>  
			
      <TextBlock Name = "ageLabel" Margin = "2" Grid.Row = "1">Age:</TextBlock> 
		
      <TextBox Name = "ageText" Grid.Column = "1" Grid.Row = "1" Margin="2" 
         Text = "{Binding Age, Mode = OneWay}"/>
			
      <StackPanel Grid.Row = "2" Grid.ColumnSpan = "2"> 
         <Button Content = "_Show..." Click = "Button_Click" /> 
      </StackPanel> 
		
   </Grid> 
	
</UserControl>

我們觀察到以下幾點:

  • 兩個文字框的文字屬性分別繫結到“Name”和“Age”,它們是Person類的類變數,如下所示。

  • Person類中,我們只有兩個變數NameAge,並且其物件在MainPage類中初始化。

  • 在 XAML 程式碼中,我們繫結到屬性Name和Age,但我們沒有選擇哪個屬性屬於該物件。

  • 一種簡單的方法是在MainPage建構函式的 C# 程式碼中將物件分配給DataContext,我們在其中繫結屬性,如下所示。

using System.Windows; 
using System.Windows.Controls;
 
namespace DataBinding {
 
   public partial class MainPage : UserControl { 
      Person person = new Person { Name = "Salman", Age = 26 }; 
		
      public MainPage() { 
         InitializeComponent(); 
         this.DataContext = person;
      }
	  
      private void Button_Click(object sender, RoutedEventArgs e) {
         string message = person.Name + " is " + person.Age; 
         MessageBox.Show(message); 
      } 
   } 
	
   public class Person { 
      private string nameValue; 
		
      public string Name { 
         get { return nameValue; } 
         set { nameValue = value; } 
      }
	  
      private double ageValue; 
		
      public double Age { 
         get { return ageValue; } 
			
         set { 
            if (value != ageValue) { 
               ageValue = value; 
            } 
         } 
      } 
   } 
} 

讓我們執行此應用程式,您會立即在網頁中看到我們已成功繫結到該Person物件的NameAge

Object to DataContext

按下顯示按鈕時,它將在訊息框中顯示姓名和年齡。

Display Message

讓我們更改上述對話方塊中的NameAge

Change Name and Age

現在,如果您單擊顯示按鈕,它將再次顯示相同的訊息。

Display Message

這是因為資料繫結模式在 XAML 程式碼中設定為單向。要顯示更新的訊息,您需要了解雙向資料繫結。

雙向資料繫結

雙向繫結中,使用者能夠透過使用者介面修改資料,並將該資料更新到源中。如果源在使用者檢視檢視時發生更改,則希望檢視更新。

讓我們看同一個示例,但僅將 XAML 程式碼中的繫結模式從單向更改為雙向,如下所示。

<UserControl x:Class = "DataBinding.MainPage" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   mc:Ignorable = "d" 
   d:DesignHeight = "300" d:DesignWidth = "400"> 
	
   <Grid x:Name = "LayoutRoot" Background = "White"> 
	
      <Grid.RowDefinitions> 
         <RowDefinition Height = "Auto" /> 
         <RowDefinition Height = "Auto" /> 
         <RowDefinition Height = "*" /> 
      </Grid.RowDefinitions>
		
      <Grid.ColumnDefinitions> 
         <ColumnDefinition Width = "Auto" /> 
         <ColumnDefinition Width = "200" /> 
      </Grid.ColumnDefinitions>
		
      <TextBlock Name = "nameLabel" Margin = "2">_Name:</TextBlock> 
		
      <TextBox Name = "nameText" Grid.Column = "1" Margin = "2" 
         Text = "{Binding Name, Mode=TwoWay}"/> 
			
      <TextBlock Name = "ageLabel" Margin = "2" Grid.Row = "1">_Age:</TextBlock>
		
      <TextBox Name = "ageText" Grid.Column = "1" Grid.Row = "1" Margin = "2" 
         Text = "{Binding Age, Mode = TwoWay}"/> 
					
      <StackPanel Grid.Row = "2" Grid.ColumnSpan = "2"> 
         <Button Content = "_Show..." Click = "Button_Click" /> 
      </StackPanel>  
		
   </Grid> 
	 
</UserControl> 

讓我們再次執行此應用程式,您會看到相同的輸出。

Object to DataContext

讓我們更改上述對話方塊中的NameAge

Change Name and Age

現在,如果您單擊顯示按鈕,它將顯示更新的訊息。

Change Name and Age Value

Silverlight - 瀏覽器整合

在本章中,我們將瞭解 Silverlight 應用程式如何使用瀏覽器整合支援與網頁一起工作。

我們可以透過以下兩種方式探索 Silverlight 與瀏覽器的整合:

  • 在瀏覽器中執行的 JavaScript 程式碼可以訪問 Silverlight 應用程式中的功能。

  • Silverlight 能夠為物件提供 JavaScript 包裝器。由於 Silverlight 為 JavaScript 物件提供了.NET包裝器,因此在 Silverlight 外掛內部執行的.NET程式碼可以訪問 HTML DOM 和其他瀏覽器指令碼功能。

我們將瞭解基於瀏覽器的軟體應用程式如何持久地將資訊儲存在客戶端。

Silverlight 和 HTML

就 HTML 世界而言,Silverlight 內容只是一個單個元素。這對佈局來說是正確的。整個 Silverlight 外掛及其所有內容看起來都像一個物件元素。

您必須牢記:

  • Silverlight 不是 HTML 的替代品,它是為了補充 HTML 而設計的。因此,能夠訪問 DOM 中的另一個元素非常重要。

  • 它使您能夠在適當的地方使用 Silverlight。

  • 在一個主要使用 HTML 的頁面上,Silverlight 與瀏覽器世界的整合不僅僅是作為 DOM 元素存在,還受普通 HTML 佈局的約束。

訪問 DOM

Silverlight 內容必須能夠完全參與網頁。因此,它應該能夠訪問 HTML DOM。Silverlight 提供了包裝瀏覽器指令碼物件作為 Dot Net 物件的橋接物件,即系統中的Script 物件類。瀏覽器名稱空間提供了一些方法,允許您讀取和寫入屬性並呼叫瀏覽器指令碼物件上的函式。

首先,您需要一種獲取 Script 物件的方法。Silverlight 提供了一個 HTML 頁面類,使您可以訪問各種頁面功能,例如 Script 物件。

讓我們看一個簡單的示例,其中我們有一個簡單的指令碼,它建立一個具有幾個屬性的物件。其中一些只是值,而另一些是函式。

<script type = "text/javascript">  
   myJsObject = { 
      answer: 42, 
      message: "Hello, world", 
      modifyHeading: function(title) 
         { document.getElementById('heading').innerHTML = title; }, 
      performReallyComplexCalculation: function(x, y) { return x + y; } 
   }; 
     
</script>

下面是 XAML 程式碼,其中添加了一個按鈕。

<UserControl x:Class = "DomAccess.Page" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"  
   Width = "400" Height = "300"> 
   
   <Grid x:Name = "LayoutRoot" Background = "White"> 
      <Button x:Name = "useDomButton" Content = "Use DOM" Width = "75" Height = "30" 
         Click = "useDomButton_Click" /> 
   </Grid>
	
</UserControl>

這是按鈕單擊實現,其中呼叫了在 HTML 檔案中建立的指令碼。

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Net; 

using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Documents; 
using System.Windows.Input; 
using System.Windows.Media; 
using System.Windows.Media.Animation; 
using System.Windows.Shapes;
using System.Windows.Browser; 

using System.Diagnostics; 
 
namespace DomAccess { 

   public partial class Page : UserControl { 
	
      public Page() { 
         InitializeComponent(); 
      } 
   
      private void useDomButton_Click(object sender, RoutedEventArgs e) { 
         ScriptObject myJsObject = HtmlPage.Window.GetProperty("myJsObject") as ScriptObject;  
         string[] propertyNames = { "answer", "message", "modifyHeading", 
            "performReallyComplexCalculation" }; 
				
         foreach (string propertyName in propertyNames) { 
            object value = myJsObject.GetProperty(propertyName); 
            Debug.WriteLine("{0}: {1} ({2})", propertyName, value, value.GetType()); 
         }
			
         object result = myJsObject.Invoke("performReallyComplexCalculation", 11, 31);  
         HtmlElement h1 = HtmlPage.Document.GetElementById("heading"); 
         h1.SetProperty("innerHTML", "Text from C# (without JavaScript's help)"); 
         h1.SetStyleAttribute("height", "200px"); 
      } 
   } 
} 

下面是完整的 HTML 檔案。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "
   http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
	
<html xmlns = "http://www.w3.org/1999/xhtml" > 
   <!-- saved from url = (0014)about:internet --> 
	
   <head> 
      <title>DomAccess</title>  
		
      <script type = "text/javascript">  
		
         myJsObject = { 
            answer: 42, 
            message: "Hello, world", 
            modifyHeading: function(title) { 
               document.getElementById('heading').innerHTML = title; }, 
            performReallyComplexCalculation: function(x, y) { return x + y; } 
         }; 
     
      </script> 
     
      <style type = "text/css"> 
		
         html, body { 
            height: 100%; 
            overflow: auto; 
         } 
			
         body { 
            padding: 0; 
            margin: 0; 
         } 
			
         #silverlightControlHost { 
            height: 100%; 
         }
			
      </style>
		
      <script type = "text/javascript" src = "Silverlight.js"></script> 
		
      <script type = "text/javascript"> 
		
         function onSilverlightError(sender, args) { 
            var appSource = ""; 
				
            if (sender != null && sender != 0) { 
               appSource = sender.getHost().Source; 
            }  
				
            var errorType = args.ErrorType; 
            var iErrorCode = args.ErrorCode; 
             
            var errMsg = "Unhandled Error in Silverlight 2 Application " +  
               appSource + "\n" ; 
					
            errMsg += "Code: "+ iErrorCode + "    \n"; 
            errMsg += "Category: " + errorType + "       \n"; 
            errMsg += "Message: " + args.ErrorMessage + "     \n";
				
            if (errorType == "ParserError") { 
               errMsg += "File: " + args.xamlFile + "     \n"; 
               errMsg += "Line: " + args.lineNumber + "     \n"; 
               errMsg += "Position: " + args.charPosition + "     \n"; 
            } else if (errorType == "RuntimeError") {  
				
               if (args.lineNumber != 0) { 
                  errMsg += "Line: " + args.lineNumber + "     \n"; 
                  errMsg += "Position: " +  args.charPosition + "     \n"; 
               } 
					
               errMsg += "MethodName: " + args.methodName + "     \n"; 
            }
				
            throw new Error(errMsg); 
         }
		  
      </script> 
		
   </head>  
	
   <body> 
	
      <!-- Runtime errors from Silverlight will be displayed here. 
         This will contain debugging information and should be removed or hidden when 
         debugging is completed -->
			
      <div id = 'errorLocation' style = "font-size: small;color: Gray;"></div> 
		
      <h1 id = 'heading'></h1>
		
      <div id = "silverlightControlHost"> 
		
         <object data = "data:application/x-silverlight-2," 
            type = "application/x-silverlight-2" width = "100%" height = "100%"> 
				
            <param name = "source" value = "ClientBin/DomAccess.xap"/> 
            <param name = "onerror" value = "onSilverlightError" /> 
            <param name = "background" value = "white" /> 
            <param name = "minRuntimeVersion" value = "2.0.30923.0" /> 
            <param name = "autoUpgrade" value = "true" /> 
				
            <a href = "http://go.microsoft.com/fwlink/?LinkID=124807" 
               style = "text-decoration: none;"> 
               <img src = "http://go.microsoft.com/fwlink/?LinkId=108181" 
               alt = "Get Microsoft Silverlight" style = "border-style: none"/> 
            </a> 
				
         </object>
			
         <iframe style = 'visibility:hidden;height:0;width:0;border:0px'></iframe> 
			
      </div> 
		
   </body> 
	
</html> 

編譯並執行上述程式碼後,您將在輸出視窗中看到所有值,這些值是從 HTML 檔案中獲取的。

Accessing DOM

Silverlight - 瀏覽器外應用程式

現在我們將探討 Silverlight 對應用程式的支援,這些應用程式可以安裝在終端使用者的計算機上,並在 Web 瀏覽器外部執行,就像普通的 Windows 應用程式一樣。您可能希望應用程式能夠在瀏覽器外部執行,主要有三個原因:

  • 互動性
  • 離線
  • 提升的信任級別

互動性

它可以實現更好的互動設計。Web 的導航模型並不特別適合某些應用程式。例如,位址列和後退按鈕可能是浪費空間,並且毫無用處。

Silverlight 在此處的意義如下:

  • Web 應用程式可以使用客戶端技術(例如 Silverlight、Flash 或 AJAX)為單個頁面提供持續更新,這可能會消除導航到其他頁面的需要。

  • 在某些應用程式中,使用者可能會花費數分鐘甚至數小時來使用瀏覽器認為是單個頁面的內容。

  • 對於此類應用程式,後退按鈕最終可能會產生相當意外的效果,即退出應用程式,因為它會將您帶回到進入應用程式之前所在的頁面。

  • 明顯地,非 Web 類應用程式通常最好在瀏覽器外部執行,因為這樣可以去除瀏覽器 Chrome。通常,可用性不是在瀏覽器外部執行的唯一原因。

離線

使用此功能的另一個原因是啟用離線執行。當 Silverlight 應用程式安裝用於瀏覽器外部操作時,它會被複制到本地計算機上的每個使用者儲存庫中,並可以透過通常的作業系統機制(例如 Windows 上的“開始”選單)啟動應用程式。

  • 即使使用者沒有網際網路連線,該應用程式也將可用。

  • 顯然,這僅對不完全依賴伺服器端資訊的應用程式才有幫助。

  • 例如,包裹遞送服務的自動跟蹤應用程式在沒有網路連線的情況下用處不大。

  • 對於某些應用程式,能夠在偶爾的連線故障期間繼續工作非常有用。

提升的信任級別

Silverlight 的 4 版增加了對受信任應用程式的支援。Silverlight 的安全沙箱通常會阻止某些特權操作,例如訪問使用者的檔案。

但是,瀏覽器外部的應用程式可能會請求提升許可權。如果使用者授予該請求,則該應用程式能夠執行更多任何普通 Windows 應用程式能夠執行的工作,例如利用 COM 自動化或自定義視窗邊框。

在瀏覽器內執行的應用程式永遠不會被信任,因此,如果您想使用這些功能,則必須編寫瀏覽器外部的應用程式。

啟用 OOB

我們如何編寫瀏覽器外部的應用程式?這非常容易。我們只需要更改 Silverlight 專案屬性中的單個設定,它會向AppManifest.xaml新增合適的設定。

讓我們看看它是如何工作的。

  • 當您的清單指示支援瀏覽器外部執行時,這不會立即生效。應用程式將照常在瀏覽器中執行。

  • 但是,如果使用者右鍵單擊,標準 Silverlight上下文選單將提供一個額外的專案來將應用程式安裝到計算機上。

ContextMenu
  • 如果使用者選擇該專案,將出現一個對話方塊,要求確認。它還會詢問應用程式是否應從“開始”選單、桌面或兩者都訪問。

Start menu
  • 您不必依賴上下文選單。您還可以提供一個按鈕,使用者可以單擊該按鈕來安裝應用程式,因為存在一個 API,您可以呼叫它來啟動安裝。

  • 當您以程式設計方式啟動安裝程式時,使用者仍然會看到對話方塊。未經使用者同意,您無法安裝應用程式。

Silverlight 應用程式

這是一個非常簡單的 Silverlight 應用程式。以下是其 XAML 程式碼。

<UserControl x:Class = "SimpleOob.MainPage" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   mc:Ignorable = "d" 
   d:DesignHeight = "300" d:DesignWidth = "400">
   
   <Grid x:Name = "LayoutRoot" Background = "White"> 
	
      <Border BorderBrush = "Blue" BorderThickness = "4" CornerRadius = "20" >
		
         <Border.Background>
			
            <LinearGradientBrush StartPoint = "0,0" EndPoint = "0,1"> 
               <GradientStop Offset = "0.0" Color = "White" /> 
               <GradientStop Offset = "0.15" Color = "#cef" /> 
               <GradientStop Offset = "1.0" Color = "White" /> 
            </LinearGradientBrush> 
				
         </Border.Background> 
			
         <TextBlock HorizontalAlignment = "Center" VerticalAlignment = "Center" 
            Text = "Silverlight Application" TextOptions.TextHintingMode = "Animated" 
            TextAlignment = "Center" TextWrapping = "Wrap" 
            FontSize = "72" FontFamily = "Trebuchet MS" > 
					 
               <TextBlock.Effect> 
                  <DropShadowEffect Color = "#888" /> 
               </TextBlock.Effect> 
				
         </TextBlock>
			
      </Border> 
		
   </Grid>
	
</UserControl>

步驟 1 - 要啟用瀏覽器外部執行,請轉到專案的屬性,然後單擊 Silverlight 選項卡。我們只需選中啟用在瀏覽器外部執行應用程式複選框。

Enable Running Application

如果您執行此應用程式,您會注意到根本不會出現 Web 瀏覽器。

Simple Silverlight Application

實際上,Visual Studio 已代表您做出了決定。當您啟用瀏覽器外部執行時,它不公平地更改了您的除錯設定。

步驟 2 - 因此,在此處的解決方案資源管理器中,請注意 Silverlight 專案現在以粗體顯示,表示它是啟動專案。

Solution Explorer Application

以前情況並非如此。它一直是 Web 專案。現在,我們不希望這樣,因為我們想展示該複選框如何為終端使用者更改內容。

步驟 3 - 我們將 Web 專案設定回啟動專案。

StartUp Project

步驟 4 - 再次執行應用程式,您會看到應用程式現在已回到瀏覽器中。

Run Application Project

步驟 5 - 右鍵單擊網頁。您會在上下文選單中看到通常的 Silverlight 條目,以及一個額外的安裝專案。

Silverlight Simple OOB App

步驟 6 - 選擇第二個選項時,將出現“安裝應用程式”對話方塊,如下所示。

Start menu

請注意,它顯示了網站的根 URL,應用程式來自該網站。我們使用 Visual Studio 提供的本地除錯 Web 伺服器,這就是它顯示 localhost 的原因。

步驟 7 - 單擊確定,應用程式將在獨立於瀏覽器的自己的視窗中執行。

Simple Silverlight Application

您可能會自然地認為此視窗以某種方式由瀏覽器擁有或與其連線,但事實並非如此。您可以關閉瀏覽器,而此視窗將保留。更重要的是,您可以關閉此視窗,然後在根本不使用瀏覽器的情況下重新執行應用程式。

步驟 8 - 如果您在開始選單中開啟搜尋對話方塊並開始鍵入應用程式名稱,它將像任何普通的 Windows 應用程式一樣顯示。

Search Dialog Box

步驟 9 - 您可以在瀏覽器完全不可見的情況下執行它。

Simple Silverlight Application

解除安裝應用程式

應用程式上的預設上下文選單提供了一種簡單的方法來執行此操作。使用者可以合理地期望以與解除安裝任何其他應用程式相同的方式解除安裝此應用程式。

Uninstall Application

您也可以透過右鍵單擊網頁並選擇刪除此應用程式…來刪除。

Remove Application

OOB 設定

儘管我們只需要更改一個設定即可啟用瀏覽器外部操作,但在實踐中,您通常希望執行的操作不止這些。AppManifest.xaml檔案可以包含多個與瀏覽器外部操作相關的設定,我們通常透過 Visual Studio 進行配置。

您可能已經注意到,當您選中啟用在瀏覽器外部執行的複選框時,Visual Studio 啟用了名為瀏覽器外部設定的按鈕。

Out-of-Browser Settings

讓我們透過單擊該按鈕來檢視它。它將生成以下對話方塊。

Simple Out-of-Browser App
  • 我們可以配置的第一件事是顯示為視窗標題的文字。

  • 我們還可以選擇修復視窗尺寸和位置,但現在我們將保留為自動。

  • 此快捷方式名稱顯示在開始選單中,以及應用程式安裝後的桌面連結。

  • 它也是上下文選單和安裝應用程式對話方塊中顯示的文字。

  • 此應用程式描述顯示在將滑鼠懸停在快捷方式上時的工具提示中。

  • 我們可以提供各種尺寸的圖示。這些必須內建到您的專案中。

應用程式、資源和部署

在本章中,我們將瞭解圍繞建立和部署應用程式及其所需資源的常見問題。

載入外掛

執行 Silverlight 應用程式的最低要求是包含用於載入 Silverlight 外掛的物件標記的主機網頁,以及編譯後的 Silverlight 內容本身。

如您所見,我們在物件標記中使用了param標記來指向內容。

  • HTML <Object> 標記

我們可以傳遞其他引數來控制功能,例如在下載內容時顯示的使用者介面、在發生錯誤時執行的 JavaScript 程式碼以及在未安裝 Silverlight 時顯示的回退內容。

<Object> 在 HTML 中

這是一個載入某些 Silverlight 內容的示例物件標記。您之前已經見過它,但我們將更詳細地瞭解一些內容,首先從物件標記本身的屬性開始。

Type 屬性

type 屬性包含一個 MIME 型別,將其標識為 Silverlight 元素。這是瀏覽器瞭解我們使用哪種嵌入內容的方式。物件標記非常靈活。它不僅用於外掛。您還可以使用它來託管嵌入影像或 HTML,以及基於外掛的內容,例如 Silverlight 或 Flash。

如果安裝了 Silverlight 外掛,則將載入它。如果沒有,則標準格式行為是瀏覽器呈現物件標記內的任何 HTML 內容,就好像物件和 param 標記不存在一樣。

<object data = "data:application/x-silverlight-2," type =  "application/x-silverlight-2"  
   width = "100%" height = "100%"> 
	
   <param name = "source" value = "ClientBin/DataBinding.xap"/> 
   <param name = "onError" value = "onSilverlightError" /> 
   <param name = "background" value = "white" /> 
   <param name = "minRuntimeVersion" value = "5.0.61118.0" /> 
   <param name = "autoUpgrade" value = "true" />
	
   <a href = "http://go.microsoft.com/fwlink/?LinkID=149156&v=5.0.61118.0" 
      style = "textdecoration:none"> 
		
      <img src = "http://go.microsoft.com/fwlink/?LinkId=161376" 
         alt = "Get Microsoft Silverlight" style = "border-style:none"/> 
   </a> 
	
</object>

Data 屬性

下一個屬性 data 稍微不那麼明顯。末尾的逗號應該放在那裡。一些重要的功能是:

  • 從技術上講,此屬性不是必需的,但 Microsoft 建議您新增它,因為某些 Web 瀏覽器的載入外掛行為相當意外。

  • 物件標記旨在託管嵌入內容,因此瀏覽器期望涉及二進位制字串、點陣圖檔案或影片或音訊流等。

  • 您通常希望在 data 屬性中放置一個 URL,並且瀏覽器下載該資料並將其傳遞給外掛。

  • data 屬性採用 URI,通常它將指向某些資料,例如 JPEG 檔案,但在這裡,我們使用了一種稍微不尋常的 URI 方案。

<param> 標記

我們在物件內部有各種param標記,從 sourceparam開始。

<param name = "source" value = "ClientBin/DataBinding.xap"/>

它告訴外掛從哪裡下載 Silverlight 內容。

您應該提供一個 JavaScript 錯誤處理程式。如果下載過程失敗,將呼叫此處理程式。一旦 Silverlight 程式碼啟動並執行,如果丟擲未處理的異常,也將呼叫此處理程式。

<param name = "onError" value = "onSilverlightError" />

所以,這不僅僅是為了載入失敗的情況。您還應該指定程式碼所需的 Silverlight 的最低版本。

微軟鼓勵使用者保持最新狀態,因此一旦機器安裝了 Silverlight 外掛,新版本將透過 Windows 更新提供,但使用者始終可能執行的是比您需要的版本更舊的版本。

<param name = "minRuntimeVersion" value = "5.0.61118.0" /> 
<param name = "autoUpgrade" value = "true" /> 

這個 **minRuntimeVersion** 引數允許您指定您需要的版本。如果安裝的版本較舊,則會呼叫 onError 處理程式。

Silverlight 將數字錯誤程式碼傳遞給錯誤處理 JavaScript 函式,並且有一個不同的錯誤程式碼(碰巧是“**8001**”),用於指示外掛已過期。

您可以編寫 JavaScript 程式碼來響應此問題,或者您可以只要求外掛嘗試為您進行升級。

這裡,**autoUpgrade** 引數設定為“**True**”,這意味著如果安裝的外掛已過期,Silverlight 將自動顯示一條訊息,告知使用者需要更新的版本,並提供為其安裝的選項。

備用 HTML 內容

在 param 標籤之後,是如果未安裝 Silverlight 則要使用的 **備用 HTML 內容**。

對於 **MIME** 型別未知的 object 標籤,標準瀏覽器行為是將其視為 object 和 param 標籤根本不存在。因此,此 a 標籤及其內容將在沒有 Silverlight 外掛的系統中顯示。

<a href = "http://go.microsoft.com/fwlink/?LinkID=149156&v=5.0.61118.0"  
   style = "text-decoration:none"> 
   <img src = "http://go.microsoft.com/fwlink/?LinkId=161376"  
      alt = "Get Microsoft Silverlight" style = "border-style:none"/> 
</a>

請注意指向 **go.microsoft.com** 站點的兩個 URL,一個超連結和一個影像。

影像連結解析為一個包含一些 Silverlight 品牌和一些提供安裝 Silverlight 的文字的點陣圖。超連結的端點相當智慧。伺服器檢查使用者代理以決定重定向的位置。

它可能會返回 Silverlight 安裝可執行檔案,或者如果使用者在不受支援的平臺上,它會將瀏覽器重定向到包含有關 Silverlight 資訊的頁面。

Silverlight.js

載入 Silverlight 內容還有另一種方法可以替代 HTML object 標籤。微軟提供了一個名為 **Silverlight.js** 的 JavaScript 檔案,允許從瀏覽器指令碼管理載入過程。

當您建立 Web 專案以託管新建立的 Silverlight 專案時,Visual Studio 會新增一個副本。Silverlight SDK 也包含此檔案的副本。

**Silverlight.js** 的主要優點是它在未安裝 Silverlight 時提供了更大的靈活性。

XAML 資源

Silverlight 還提供了一種在 XAML 中建立 **物件資源** 的機制。某些型別的物件通常透過 XAML 進行更正,您可能希望能夠在應用程式中的多個位置使用它們。在多個位置使用模板非常常見。

如果您為按鈕定義了自定義外觀,您可能希望將其應用於多個按鈕,或者甚至應用於應用程式中的所有按鈕。XAML 資源系統提供了一種實現此目的的方法。您可以定義一個 **命名資源**,然後在 XAML 中的其他位置使用它。

除了模板之外,對於圖形資源(如畫刷和形狀)也經常需要這樣做。如果您的應用程式中使用了特定的配色方案,您可以將該方案的顏色和畫刷定義為資源。

這是一個 **SolidColorBrush** 資源的簡單應用程式。

<UserControl x:Class = "XAMLResources.MainPage" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   mc:Ignorable = "d" 
   d:DesignHeight = "300" d:DesignWidth = "400">
   
   <UserControl.Resources> 
      <SolidColorBrush x:Key = "brushResource" Color = "AliceBlue" /> 
   </UserControl.Resources> 
	
   <Grid x:Name = "LayoutRoot" Background = "White"> 
      <StackPanel> 
         <Rectangle Height = "50" Margin = "20" Fill = "{StaticResource brushResource}" /> 
         <Rectangle Height = "50" Margin = "20" Fill = "{StaticResource brushResource}"/> 
      </StackPanel> 
   </Grid> 
	
</UserControl>

在上面的 XAML 程式碼中,您可以看到兩個矩形都具有 **StaticResource** **brushResource** 的顏色是 **AliceBlue**。

編譯並執行上述程式碼後,您將看到以下輸出。

XAML Resources

App.xaml

所有 Silverlight 應用程式都有一個名為 **App.xaml** 的檔案。它包含應用程式範圍的資訊。例如,它有一個 Resources 屬性,就像使用者介面元素一樣。

在 **App.xaml** 檔案中定義的資源可在專案中的所有 XAML 檔案中使用。因此,與其在 **MainPage.xaml** 中使用這些型別的資源,不如將其移至應用程式範圍。

<Application 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"  
   x:Class = "XAMLResources.App" > 
	
   <Application.Resources> 
      <SolidColorBrush x:Key = "brushResource" Color = "AliceBlue" /> 
   </Application.Resources>
	
</Application>

應用程式類

與大多數 XAML 檔案一樣,**App.xaml** 檔案及其相應的 **後臺程式碼** 檔案定義了一個類。此 Application 類是 Silverlight 應用程式的入口點。**App.xaml** 通常處理應用程式範圍的資源;其後臺程式碼檔案包含啟動和關閉處理程式碼。

  • 在建立 Application 類例項後不久,Silverlight 就會引發其 **Application.Startup** 事件。

  • 在這裡,我們建立使用者介面。我們期望建立一個使用者介面元素並將其分配給應用程式物件的 RootVisual 屬性(在 **Startup** 事件中),這將成為 Silverlight 外掛顯示的使用者介面。

public partial class App : Application { 
 
   public App() { 
      this.Startup += this.Application_Startup; 
      this.Exit += this.Application_Exit; 
      this.UnhandledException += this.Application_UnhandledException;  
      InitializeComponent(); 
   }  
	
   private void Application_Startup(object sender, StartupEventArgs e) { 
      this.RootVisual = new MainPage(); 
   } 
	
   private void Application_Exit(object sender, EventArgs e) {}  
	
   private void Application_UnhandledException(object sender, 
      ApplicationUnhandledExceptionEventArgs e) { 
		
      if (!System.Diagnostics.Debugger.IsAttached) { 
         e.Handled = true; 
         Deployment.Current.Dispatcher.BeginInvoke(delegate { ReportErrorToDOM(e); }); 
      } 
		
   }  
	
   private void ReportErrorToDOM(ApplicationUnhandledExceptionEventArgs e) { 
      try { 
         string errorMsg = e.ExceptionObject.Message + e.ExceptionObject.StackTrace; 
         errorMsg = errorMsg.Replace('"', '\'').Replace("\r\n", @"\n");  
         System.Windows.Browser.HtmlPage.Window.Eval("throw new Error
            (\"Unhandled Error in Silverlight Application " + errorMsg + "\");"); 
      } catch (Exception) {} 
   } 
} 

注意事項

請注意,您不能更改 **RootVisual**。您必須只設置一次。如果要在應用程式執行時更改使用者介面,則必須透過更改 **MainPage** 的內容來執行此操作,而不是嘗試用另一個 **MainPage** 替換它。

其他應用程式事件是 **Exit**,這是在使用者介面即將消失時執行 **關閉** 程式碼的最後機會,以及 **UnhandledException**,如果您的程式碼引發未處理的異常,則會引發此事件。

如果您沒有為 **UnhandledException** 事件提供處理程式,或者如果該處理程式沒有將事件標記為已處理,則 **UnhandledExceptions** 將有效地關閉您的 Silverlight 應用程式。

螢幕上的外掛區域將變為空白,並且會向瀏覽器報告指令碼錯誤。

Silverlight - 檔案訪問

在本章中,我們將瞭解 Silverlight 應用程式如何訪問終端使用者計算機上的檔案。在 Silverlight 中訪問檔案的主要方法有三種。選擇將取決於您需要使用檔案的原因以及您是否正在編寫受信任的應用程式。

  • 最靈活的選項是使用 **檔案對話方塊** 類。使用 **開啟** 和 **儲存** 檔案對話方塊,您可以訪問終端使用者選擇的任何檔案,只要使用者具有相應的許可權即可。使用者同意是此方法的核心。使用者必須選擇要讀取的檔案,或者在儲存時,他們選擇要覆蓋的檔案或為您選擇一個位置和檔名。

  • 第二個選項是使用 **System.IO** 名稱空間中的各種類。Silverlight 提供了諸如 **FileStream、StreamWriter、FileInfo、Directory** 和 **DirectoryInfo** 等類,所有這些類都使編寫程式碼成為可能,該程式碼可以在無需使用者參與的情況下開啟和訪問檔案。這對開發人員來說可能更方便,但當然,大多數使用者都不希望任何作為網頁一部分下載的舊程式碼能夠在他們的檔案中搜索。

  • 第三個選項是 **Isolated Storage**,我們將在後面討論。

開啟和儲存檔案對話方塊

SaveFileDialog

**SaveFileDialog** 類顯示用於選擇檔案儲存位置的標準作業系統提供的使用者介面。

一些重要的特性是:

  • 要使用它,我們建立 **SaveFileDialog** 類的例項。

  • 呼叫 **ShowDialog** 會使其出現,返回值告訴我們使用者是否選擇了儲存檔案的位置或取消了對話方塊。

  • 您可能想知道那裡與 **True** 的冗餘比較。如果 **ShowDialog** 返回 **True** 值,這意味著使用者已選擇了一個檔案。因此,我們可以繼續呼叫 **OpenFile** 方法,該方法會返回一個 **Stream**。

  • 如果需要,我們可以發現使用者選擇的檔名。對話方塊提供了一個名為 **SafeFileName** 的屬性,但它不包含路徑。無論如何,寫入資料的唯一方法是使用對話方塊返回的 **Stream**。從開發人員的角度來看,這只是一個普通的 **.NET 流**,因此我們可以將其包裝在 **StreamWriter** 中,以便將文字寫入其中。

OpenFileDialog

OpenFileDialog 在使用上類似於 **SaveFileDialog**。顯然,您始終選擇現有檔案而不是新檔案,但還有一個重要的區別。

  • 它提供了一個名為 **MultiSelect** 的屬性。如果將其設定為 **True**,則使用者可以選擇多個檔案。這意味著對話方塊需要一個稍微複雜的 API。

  • **SaveFileDialog** 每次只處理一個檔案,但 **OpenFileDialog** 能夠處理多個檔案,因此它不提供 **OpenFile** 方法。我們需要擴充套件程式碼。根據對話方塊是處於 **單檔案** 模式還是 **MultiSelect** 模式,您可以使用其 **File** 或 **Files** 屬性。

  • 這裡,在下面給出的示例中,我們處於單檔案模式。因此,我們使用 **File**,並對返回的 **FileInfo** 物件呼叫 **OpenRead**。

  • 在 **多選** 模式下,我們將使用 **Files**,它返回 **FileInfo** 物件的集合。

FileStream

如上所述,訪問檔案的第二種方法是直接使用 **FileStream** 類或 **System.IO** 名稱空間中的相關型別。對此沒有太多可說的,因為在大多數情況下,它類似於使用完整 **.NET Framework** 訪問檔案。

但是,有一些 Silverlight 特定的變化。

  • 首先,此方法允許您在任何時候無需使用者干預且沒有任何明顯的檔案活動指示的情況下訪問檔案,只有受信任的應用程式才能使用此技術。請記住,您需要在瀏覽器外部執行才能獲得提升的信任級別。

  • 第二個問題是隻有某些特定資料夾中的檔案可用。您只能讀取和寫入位於 **使用者的文件、音樂、圖片或影片檔案** 下面的檔案。這樣做的原因之一是 Silverlight 執行在多個平臺上,並且例如 Apple Mac 的檔案系統結構與 Windows 的檔案系統結構非常不同。因此,跨平臺檔案訪問必須根據所有 Silverlight 支援的系統上都可用的有限資料夾集來工作。

  • 由於這些資料夾在不同的作業系統上將位於不同的位置,並且其位置通常因使用者而異,因此您需要使用 **Environment.GetFolderPath** 方法在執行時發現實際位置。

  • 您可以檢查起始點下方的目錄結構。**System.IO** 名稱空間中的 **Directory** 和 **DirectoryInfo** 類允許您列舉檔案和目錄。

考慮一個簡單的示例,其中檔案可以透過 **OpenFileDialog** 開啟並透過 **SaveFileDialog** 將一些文字儲存到檔案。

下面是 XAML 程式碼,其中建立了兩個按鈕和一個 **文字框**。

<UserControl x:Class = "FileDialogs.MainPage" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   mc:Ignorable = "d" 
   d:DesignHeight = "300" d:DesignWidth = "400"> 
   
   <Grid x:Name = "LayoutRoot" Background = "White">
	
      <Grid.RowDefinitions> 
         <RowDefinition Height = "Auto" /> 
         <RowDefinition Height = "265*" /> 
      </Grid.RowDefinitions>
		
      <Button 
         x:Name = "saveFileButton" 
         Content = "Save" 
         Width = "75" FontSize = "20" 
         HorizontalAlignment = "Left" VerticalAlignment = "Top" 
         Margin = "12,12" Click = "saveFileButton_Click" /> 
				
      <Button 
         x:Name = "openFileButton" 
         Content = "Open" 
         Width = "75" FontSize = "20" 
         HorizontalAlignment = "Left" VerticalAlignment = "Top" 
         Margin = "101,12,0,0" Click = "openFileButton_Click" /> 
				
      <TextBox 
         x:Name = "contentTextBox" 
         Grid.Row = "1" 
         Margin = "12" FontSize = "20" /> 
				
   </Grid> 
	
</UserControl> 

下面是 C# 程式碼,用於實現單擊事件,其中開啟和儲存檔案。

using System; 
using System.Diagnostics; 
using System.IO; 

using System.Windows; 
using System.Windows.Controls; 
 
namespace FileDialogs {

   public partial class MainPage : UserControl { 
	
      public MainPage() { 
         InitializeComponent(); 
      }
	  
      private void saveFileButton_Click(object sender, RoutedEventArgs e) { 
         var save = new SaveFileDialog(); 
         save.Filter = "Text Files (*.txt)|*.txt|All Files (*.*)|*.*"; 
         save.DefaultExt = ".txt"; 
			
         if (save.ShowDialog() == true) { 
            Debug.WriteLine(save.SafeFileName); 
            using (Stream saveStream = save.OpenFile()) 
            using (var w = new StreamWriter(saveStream)) { 
               var fs = saveStream as FileStream; 
					
               if (fs != null) { 
                  w.Write(contentTextBox.Text); 
               } 
            } 
         } 
      }
	  
      private void openFileButton_Click(object sender, RoutedEventArgs e) { 
         var open = new OpenFileDialog(); 
			
         if (open.ShowDialog() == true) { 
            using (Stream openStream = open.File.OpenRead()) { 
               using (var read = new StreamReader(openStream)) { 
                  contentTextBox.Text = read.ReadToEnd(); 
               } 
            } 
         }  
      } 
   } 
}

編譯並執行上述程式碼後,您將看到以下網頁,其中包含兩個按鈕。

單擊 **開啟** 按鈕,這將開啟 **OpenFileDialog** 以選擇文字檔案。

OpenFileDialog

選擇一個文字檔案並單擊 **開啟**,您將在文字框中看到文字。

OpenSaveTextFile

要將文字儲存到檔案,請更新文字。

OpenSaveTextFile

單擊 **儲存** 按鈕將更改儲存到新的文字檔案或現有檔案中。

New Text File

要將更改儲存到現有的文字檔案,請在 **SaveFileDialog** 中選擇文字檔案,但如果要將更改儲存到新檔案,請寫入檔名並單擊 **儲存** 按鈕。

SaveFileDialog

Silverlight - 檢視模型

在本節中,我們將探討 Silverlight 軟體開發中一項重要的技術:使用**檢視模型**。

  • **檢視模型**是一個關鍵部分,它引入了名為分離表示的技術,透過將檢視與模型分離來實現。

  • **檢視模型**提供了一種實現分離表示的方法,我們將看到它們如何利用 Silverlight 的資料繫結來減少使用者介面中所需的程式碼量。

UI 開發挑戰

**檢視模型**旨在解決在開發使用者介面軟體時經常出現的某些問題。也許最重要的一點是,使用者介面程式碼通常難以進行徹底的測試,尤其是在使用自動單元測試時。還有一些程式碼質量問題會影響程式碼的持續靈活性和可維護性。

  • 如果您遵循 Visual Studio 設計工具引導您的最簡單的路徑,您最終可能會在程式碼隱藏中放入過多的程式碼。

  • 非常常見的是,大量的應用程式功能被新增到程式碼隱藏中。

  • 很少有開發人員會真正計劃將業務邏輯放入使用者介面類中,但由於 Visual Studio 將您的事件處理程式放在那裡,因此它變成了完成事情的一個過於方便的地方。

  • 人們普遍認為,如果類具有明確定義且範圍合理的職責,則軟體更容易開發和維護。

  • 程式碼隱藏的工作是根據需要直接與構成使用者介面的物件進行互動。

  • 一旦您開始在其中放置關於應用程式如何執行的決策程式碼,就會導致問題。

  • 不僅應用程式邏輯可能會流入應該關注使用者介面的程式碼,一些開發人員開始依賴控制元件和其他使用者介面物件來儲存重要的應用程式狀態。

  • 模型僅儲存資料,檢視僅儲存格式化後的資料,而控制器(ViewModel)充當兩者之間的聯絡員。控制器可能會獲取來自檢視的輸入並將其放置在模型上,反之亦然。

MVC

分離表示

為了避免將應用程式邏輯放在程式碼隱藏或 XAML 中導致的問題,最好使用一種稱為**分離表示**的技術。使 XAML 和程式碼隱藏具有與使用者介面物件直接互動所需的最小功能,使用者介面類還包含用於複雜互動行為、應用程式邏輯和其他所有內容的程式碼,如下面的左側所示。

Separated Presentation

分離表示的重要特性 -

  • 使用分離表示,使用者介面類變得更加簡單。它當然有 XAML,但程式碼隱藏儘可能地少。

  • 應用程式邏輯屬於一個單獨的類,通常稱為**模型**。

  • 許多開發人員嘗試使用資料繫結將 XAML 中的元素直接連線到模型中的屬性。

  • 問題是**模型**完全關注應用程式的功能問題,而不是使用者如何與應用程式互動。

  • 大多數使用者介面都有一些不屬於應用程式模型的狀態。例如,如果您的使用者介面使用拖放,則某些內容需要跟蹤諸如當前正在拖動的專案的位置、它在移動到可能的放置目標時外觀應如何更改以及這些放置目標在專案被拖動到它們上面時可能如何更改等內容。

  • 這種狀態可能會變得非常複雜,並且需要進行徹底的測試。

  • 在實踐中,您通常希望在使用者介面和模型之間放置其他一些類。它有兩個重要的作用。

    • 首先,它會為特定的使用者介面檢視調整您的應用程式模型。

    • 其次,它是任何非平凡互動邏輯所在的位置,我的意思是使您的使用者介面按您想要的方式執行所需的程式碼。

模型/檢視/檢視模型

**檢視模型**是分離表示方法的一個示例,但讓我們明確說明每一層中究竟是什麼樣的東西。有三層 -

  • 模型
  • 檢視
  • 檢視模型

模型

這是一個由普通 C# 類組成的**經典**物件模型,它與使用者介面沒有直接關係。

您通常會期望您的模型程式碼能夠在不引用任何使用者介面庫的情況下進行編譯。事實上,您可能能夠獲取完全相同的原始碼並將其編譯成 Silverlight 應用程式、普通 .NET 控制檯應用程式,甚至伺服器端 Web 程式碼。

模型中的型別應表示您的應用程式使用的概念。

檢視

檢視通常是 UserControl,它可能是您的 MainPage,也可能只是您頁面的一部分。

在大多數 Silverlight 應用程式中,將您的使用者介面拆分成小的部分,為每個部分定義一個 UserControl 或 View 是一個好主意。

Silverlight 應用程式在這方面並不獨特。顯然特定於 Silverlight 的是 View。您的使用者介面越細粒度,事情往往就越好。您不僅不太可能遇到其他開發人員處理相同檔案的麻煩,保持簡潔自然會阻止導致義大利麵條式程式碼的捷徑。

例如,定義一個**檢視**來表示列表中的單個專案非常常見。

檢視模型

最後,對於每個**檢視**,您都會編寫一個**檢視模型**。因此,這是**檢視模型**類的一個重要特性。

它的存在是為了服務於特定的檢視。**檢視模型**專用於特定的呈現方式,例如列表中顯示的特定資料項。

這就是為什麼它被稱為**檢視模型**;它專門針對特定檢視調整底層模型。與模型一樣,**檢視模型**也是一個普通的 C# 類。它不需要派生自任何特定型別。

碰巧的是,一些開發人員發現將一些通用功能放入基檢視模型類中很方便,但模式並不要求這樣做。特別是,您的**檢視模型**不會派生自任何 Silverlight 特定型別。但是,與模型不同,它可以在其屬性中使用 Silverlight 型別。

例如,您的檢視模型可能會選擇僅在某些條件下顯示使用者介面的某些部分,因此您可能會提供 System.Windows.Visibility 型別的屬性,這是 Silverlight 元素用於其 Visibility 屬性的型別。這使得能夠將元素(例如面板)的可見性直接繫結到檢視模型。

示例

讓我們看一個簡單的示例,我們將使用**模型-檢視-檢視模型 (MVVM)** 方法。

**步驟 1** - 建立一個新的 Silverlight 應用程式專案**SilverlightMVVMDemo**。

**步驟 2** - 將三個資料夾(Model、ViewModel 和 Views)新增到您的專案中,如下所示。

SilverlightMVVMDemo

**步驟 3** - 在 Model 資料夾中新增一個 StudentModel 類,並將以下程式碼貼上到該類中。

using System.ComponentModel; 
 
namespace SilverlightMVVMDemo.Model { 

   public class StudentModel {} 
	
   public class Student : INotifyPropertyChanged { 
      private string firstName; 
      private string lastName;  
		
      public string FirstName { 
         get { return firstName; } 
			
         set {
            if (firstName != value) { 
               firstName = value; 
               RaisePropertyChanged("FirstName"); 
               RaisePropertyChanged("FullName"); 
            } 
         } 
      }
		
      public string LastName { 
         get { return lastName; } 
			
         set { 
            if (lastName != value) { 
               lastName = value; 
               RaisePropertyChanged("LastName"); 
               RaisePropertyChanged("FullName"); 
            } 
         } 
      }  
		
      public string FullName { 
         get { 
            return firstName + " " + lastName; 
         } 
      } 
		
      public event PropertyChangedEventHandler PropertyChanged; 
		
      private void RaisePropertyChanged(string property) { 
         if (PropertyChanged != null) { 
            PropertyChanged(this, new PropertyChangedEventArgs(property)); 
         } 
      } 
   } 
}

**步驟 4** - 將另一個 StudentViewModel 類新增到 ViewModel 資料夾中,並貼上以下程式碼。

using SilverlightMVVMDemo.Model; 
using System.Collections.ObjectModel;
  
namespace SilverlightMVVMDemo.ViewModel { 

   public class StudentViewModel { 
	
      public ObservableCollection<Student> Students {  
         get;  
         set;  
      }  
		
      public void LoadStudents() { 
         ObservableCollection<Student> students = new ObservableCollection<Student>(); 
				
         students.Add(new Student { FirstName = "Mark", LastName = "Allain" }); 
         students.Add(new Student { FirstName = "Allen", LastName = "Brown" }); 
         students.Add(new Student { FirstName = "Linda", LastName = "Hamerski" });
			
         Students = students; 
      } 
   } 
} 

**步驟 5** - 透過右鍵單擊**Views**資料夾並選擇**新增新項…**來新增**Silverlight 使用者控制元件**。

Silverlight User Control

**步驟 6** - 點選新增。現在您將看到 XAML 檔案。將以下程式碼新增到**StudentView.xaml**檔案中,其中包含不同的 UI 元素。

<UserControl x:Class = "SilverlightMVVMDemo.Views.StudentView" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   mc:Ignorable = "d" 
   d:DesignHeight = "300" d:DesignWidth = "400">
   
   <Grid x:Name = "LayoutRoot" Background = "White">
	
      <StackPanel HorizontalAlignment = "Left">
		
         <ItemsControl ItemsSource = "{Binding Path=Students}">
			
            <ItemsControl.ItemTemplate>
				
               <DataTemplate> 
					
                  <StackPanel Orientation = "Horizontal"> 
                     <TextBox Text = "{Binding Path = FirstName, Mode = TwoWay}" 
                        Width = "100" Margin = "3 5 3 5"/> 
								
                     <TextBox Text = "{Binding Path = LastName, Mode = TwoWay}"  
                        Width = "100" Margin = "0 5 3 5"/> 
								
                     <TextBlock  Text = "{Binding Path = FullName, Mode=OneWay}" 
                        Margin = "0 5 3 5"/> 
								
                  </StackPanel>
						
               </DataTemplate> 
					
            </ItemsControl.ItemTemplate>
				
         </ItemsControl> 
			
      </StackPanel> 
		
   </Grid> 
	
</UserControl>

**步驟 7** - 現在將**StudentView**新增到您的**MainPage.xaml**檔案中,如下所示。

<UserControl x:Class = "SilverlightMVVMDemo.MainPage" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   xmlns:views = "clr-namespace:SilverlightMVVMDemo.Views" 
   mc:Ignorable = "d" 
   d:DesignHeight = "576.316" d:DesignWidth = "863.158"> 
   
   <Grid x:Name = "LayoutRoot" Background = "White"> 
      <views:StudentView x:Name = "StudentViewControl" Loaded = "StudentViewControl_Loaded"/> 
   </Grid> 
	
</UserControl>

**步驟 8** - 這是**MainPage.xaml.cs**檔案中**Loaded**事件的實現,它將從**ViewModel**更新**View**。

using System.Windows; 
using System.Windows.Controls; 
 
namespace SilverlightMVVMDemo { 

   public partial class MainPage : UserControl { 
	
      public MainPage() { 
         InitializeComponent();
      }
   } 
	
   private void StudentViewControl_Loaded(object sender, RoutedEventArgs e) { 
      SilverlightMVVMDemo.ViewModel.StudentViewModel 
      studentViewModelObject = new SilverlightMVVMDemo.ViewModel.
      StudentViewModel(); 
      studentViewModelObject.LoadStudents();  
      StudentViewControl.DataContext = studentViewModelObject;  
   } 
}

**步驟 9** - 當以上程式碼編譯並執行時,您將在網頁上看到以下輸出。

Add Student View

UI 與檢視模型

MVVM 方法中最難的部分之一是確定分界線應該在哪裡。哪些東西屬於哪裡並不總是顯而易見的。

  • 特別是,一些使用者介面元素提供了功能,根據嚴格的檢視,這些功能可以說應該屬於檢視模型。

  • 一般來說,並非在**檢視**中實現的所有行為都那麼**檢視模型**友好。

  • 部分原因是,沒有標準的方式來打包檢視模型行為以供重用,尤其是在您想要使用設計環境(如 Visual Studio 或 Blend)時。

MVVM 的優點

MVVM 提供以下優點 -

  • 分離表示關注點(檢視、檢視模型、模型)

  • 乾淨的可測試和可管理的程式碼。可以在單元測試中包含表示層邏輯。

  • 沒有程式碼隱藏程式碼,因此表示層和邏輯是松耦合的。

  • 更好的資料繫結方式。

MVVM 的缺點

對於簡單的 UI,MVVM 可能有點過頭了。當我們有複雜的資料繫結時,除錯會有點困難。

Silverlight - 輸入處理

在本節中,我們將學習如何在 Silverlight 應用程式中處理使用者輸入。Silverlight 提供了一個強大的 API,應用程式可以透過該 API 獲取來自各種裝置(如滑鼠、鍵盤和觸控等)的輸入。

輸入型別

使用者可以透過多種不同的方式與您的應用程式互動。最明顯的方式是使用滑鼠。Silverlight 提供了用於跟蹤以下內容的事件 -

  • 滑鼠移動
  • 按鈕點選,以及
  • 滾輪活動

當然還有鍵盤,Silverlight 還支援觸控式螢幕輸入。如果您熟悉 Windows 中的觸控支援,您就會知道觸控輸入可以表示為提供詳細資訊的低階事件,也可以將其總結為稱為手勢的高階事件。

滑鼠事件

讓我們從檢視 Silverlight 提供的滑鼠輸入事件開始。一些事件與滑鼠指標的移動有關。

  • 只要指標在您已附加處理程式的元素上移動,就會引發MouseMove 事件。

  • 您還可以獲得MouseEnterMouseLeave 事件,以通知您滑鼠何時移入和移出元素。

以下是新增橢圓和文字塊的 XAML 程式碼。

<UserControl x:Class="MouseInput.MainPage" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   mc:Ignorable = "d" 
   d:DesignHeight = "300" d:DesignWidth = "400">  
   
   <Grid x:Name = "LayoutRoot" Background = "White">
	
      <TextBlock x:Name = "mouseText" FontSize = "40" 
         VerticalAlignment = "Top" Height = "76" Margin = "0,10,0,0" />
			 
      <Ellipse
         Name = "myEllipse"  
         Width = "320" Height = "150" HorizontalAlignment = "Left" 
         VerticalAlignment = "Top" Margin = "27,103,0,0" 
         Stroke = "Black" StrokeThickness = "10" Fill = "#00FF0000" 
         MouseEnter = "myEllipse_MouseEnter" 
         MouseLeave = "myEllipse_MouseLeave" 
         MouseMove = "myEllipse_MouseMove" /> 
			
   </Grid> 
	
</UserControl>

以下是不同滑鼠輸入事件的實現。

using System.Windows.Controls; 
using System.Windows.Input; 
using System.Windows.Media; 
 
namespace MouseInput { 

   public partial class MainPage : UserControl { 
	
      public MainPage() { 
         InitializeComponent(); 
      } 
     
      private void myEllipse_MouseEnter(object sender, MouseEventArgs e) { 
         mouseText.Text = "Mouse Enter"; 
         myEllipse.Stroke = new SolidColorBrush(Colors.Blue); 
      }  
      
      private void myEllipse_MouseLeave(object sender, MouseEventArgs e) { 
         mouseText.Text = "Mouse Leave"; 
         myEllipse.Stroke = new SolidColorBrush(Colors.Black);  
      }  
      
      private void myEllipse_MouseMove(object sender, MouseEventArgs e) { 
         mouseText.Text = "Mouse Move: " + e.GetPosition(myEllipse);  
      }  
   } 
}

編譯並執行上述程式碼後,您將看到以下輸出。

Mouse Input

當滑鼠進入橢圓時,您將看到顏色和座標的變化。

Change Coordinates

當滑鼠離開橢圓時,它將顯示訊息“mouse leave”,並更改為預設顏色。

Mouse Leave

鍵盤

使用者向您的應用程式輸入文字資料的最簡單方法是透過鍵盤(如果可用)。請記住,並非所有移動裝置都配備鍵盤,除了筆記型電腦和桌上型電腦。

  • Silverlight 提供了兩個用於鍵盤輸入的簡單事件,KeyUpKeyDown

  • 這兩個事件都將KeyEventArgs 傳遞給處理程式,而 Key 屬性指示按下的是哪個鍵。

  • 在下面的示例中,處理了一些鍵盤輸入。

  • 以下示例定義了 Click 事件的處理程式和KeyDown 事件的處理程式。

以下是新增不同 UI 元素的 XAML 程式碼。

<UserControl x:Class = "KeyboardInput.MainPage" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   mc:Ignorable = "d" 
   d:DesignHeight = "300" d:DesignWidth = "400">
	
   <Grid x:Name = "LayoutRoot" Background = "White">
	
      <StackPanel Orientation = "Horizontal" KeyDown = "OnTextInputKeyDown"> 
         <TextBox Width = "400" Height = "30" Margin = "10"/> 
			
         <Button Click = "OnTextInputButtonClick" 
            Content = "Open" Margin = "10" Width = "50" Height = "30"/> 
				
      </StackPanel>
		
   </Grid> 
	
</UserControl>

以下是處理不同鍵盤和單擊事件的 C# 程式碼。

using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Input;
  
namespace KeyboardInput {

   public partial class MainPage : UserControl { 
	
      public MainPage() { 
         InitializeComponent(); 
      } 
		
      private void OnTextInputKeyDown(object sender, KeyEventArgs e) { 
         if (e.Key == Key.O) { 
            handle(); 
            e.Handled = true; 
         } 
      } 
		
      private void OnTextInputButtonClick(object sender, RoutedEventArgs e) { 
         handle(); 
         //e.Handled = true; 
      } 
		
      public void handle() { 
         MessageBox.Show("Do you want to open a file?"); 
      }  
   } 
} 

編譯並執行上述程式碼後,您將看到以下內容:

KeyEventArgs

如果單擊開啟按鈕或在文字框中單擊並單擊確定,則它將顯示相同的訊息。

Display the Same Message

我們建議您執行以上示例以更好地理解。

Silverlight - 隔離儲存

第三種檔案訪問機制是Isolated Storage 機制,它提供與登入使用者關聯的儲存。API 透過來自.NET System.IO 名稱空間的Stream 類呈現資料。因此,與我們迄今為止檢視的其他機制一樣,您可以使用System.IO 中的其他型別來處理流,從而使您能夠儲存文字或二進位制資料。

一些重要的特性是:

  • 這種儲存機制稱為Isolated Storage,因為儲存是分割槽的,Silverlight 應用程式只能訪問某些部分。

  • 您無法訪問任何舊的儲存資料。首先,儲存按使用者分割槽。Silverlight 應用程式無法訪問與登入和執行應用程式的使用者不同的使用者的儲存。

  • 這與您的 Web 應用程式可能使用的任何身份驗證機制無關。這一點很重要,因為一些共享計算機的人不使用單獨的 Windows 帳戶,並且習慣於僅登入和登出他們使用的網站。

使用 Isolated Storage

Isolated Storage 並非 Silverlight 獨有。該 API 最初是為了Windows 窗體而引入的,以便從 Web 啟動的應用程式能夠在部分信任場景中本地儲存資料。實現方式不同,無法從 Silverlight 訪問完整的.NET Framework 的 Isolated Storage,反之亦然。

但是,如果您使用過它,這裡的步驟看起來會非常熟悉。

  • 您首先請求使用者特定的儲存。在這種情況下,我們請求應用程式的儲存。如果我們想要由站點上的所有 XAP 共享的每個站點的儲存,我們將呼叫GetUserStoreForSite 而不是此方法。

  • 這兩種方法都會返回一個IsolatedStorageFile 物件,這是一個非常無用的名稱,因為它表示一個目錄,而不是一個檔案。

  • 要訪問檔案,您需要向IsolatedStorageFile 請求一個Stream

  • 我們使用IsolatedStorageFileStream 類,其建構函式要求您將IsolatedStorageFile 物件作為引數傳遞。

  • 因此,我們正在儲存中建立新檔案。檔案在磁碟上的確切位置未知。

  • 包含目錄包含隨機元素,以使其無法猜測檔名稱。

  • 如果沒有此功能,惡意網站可能會將檔案放置在使用者的計算機上,然後構建檔案 URL 以開啟它,希望誘騙使用者單擊本地執行程式的連結。

  • Windows 中內建了各種其他安全措施來防止這種情況發生,但這是另一層防禦措施,以防其他措施被停用或繞過。

  • 該檔案將儲存在使用者配置檔案的某個位置,但您只能知道這一點。您的IsolatedStorageFileStream 不會報告其真實位置。

讓我們來看一個簡單的示例,該示例跟蹤應用程式執行的次數。以下是 XAML 程式碼。

<UserControl x:Class = "StoreRunCount.MainPage" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   mc:Ignorable = "d" 
   d:DesignHeight = "300" d:DesignWidth = "400"> 
   
   <Grid x:Name = "LayoutRoot" Background = "White"> 
      <TextBlock x:Name = "runCountText" FontSize = "20" /> 
   </Grid> 
	
</UserControl>

以下是使用Isolated storage 的 C# 程式碼。

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Net; 

using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Documents; 
using System.Windows.Input; 
using System.Windows.Media; 
using System.Windows.Media.Animation; 
using System.Windows.Shapes; 

using System.IO.IsolatedStorage; 
using System.IO;

namespace StoreRunCount { 

   public partial class MainPage : UserControl {
	
      const string RunCountFileName = "RunCount.bin"; 
		
      public MainPage() { 
         InitializeComponent();  
         int runCount = 0;  
			
         using (var store = IsolatedStorageFile.GetUserStoreForApplication()) { 
			
            if (store.FileExists(RunCountFileName)) { 
               using (var stm = store.OpenFile(RunCountFileName, 
                  FileMode.Open, FileAccess.Read)) 
               using (var r = new BinaryReader(stm)) { 
                  runCount = r.ReadInt32(); 
               }  
            } 
			
            runCount += 1;  
            using (var stm = store.OpenFile(RunCountFileName, 
               FileMode.Create, FileAccess.Write)) 
					
            using (var w = new BinaryWriter(stm)) { 
               w.Write(runCount); 
            } 
         }  
			
         runCountText.Text = "You have run this application " + runCount.ToString() + " time(s)"; 
      } 
   }
}

編譯並執行上述程式碼後,您將看到以下網頁,它將向您顯示執行此應用程式的次數。

Isolated storage

增加配額

如果初始空間不足,應用程式可能會請求更多空間。無法保證請求一定會成功。Silverlight 將詢問使用者是否同意為應用程式提供更多空間。

順便說一句,您只能響應使用者輸入(例如單擊)時才能請求更多儲存空間。如果您嘗試在其他時間(例如外掛載入時或在計時器處理程式中)請求它,Silverlight 將自動失敗該請求,甚至不會提示使用者。額外的配額僅適用於使用者正在與之互動的應用程式。

IsolatedStorageFile 物件提供三個用於管理配額的成員:

  • AvailableFreeSpace
  • IncreaseQuotaTo
  • Quota

AvailableFreeSpace

AvailableFreeSpace 屬性告訴您剩餘多少配額。

請注意,即使是空子目錄也會佔用一些配額,因為作業系統需要在磁碟上分配空間來表示該目錄。因此,可用空間可能小於總配額減去所有檔案的大小總和。

IncreaseQuotaTo

如果您沒有足夠的空間繼續,則可以透過呼叫IncreaseQuotaTo 方法來請求更多空間。

Quota

這裡我們使用第三個屬性Quota 來發現當前配額大小,然後新增我們需要獲得新請求配額的額外數量。

該方法返回TrueFalse 以指示我們是否分配了我們請求的內容。請注意,Silverlight 可能會決定分配比您請求的更多空間。

以下是一個簡單的示例,用於在單擊按鈕時增加配額。以下是 XAML 程式碼。

<UserControl x:Class = "ChangeQuota.MainPage" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   mc:Ignorable = "d" 
   d:DesignHeight = "300" d:DesignWidth = "400"> 
   
   <Grid x:Name = "LayoutRoot" Background = "White"> 
      <TextBlock x:Name = "infoText" FontSize = "20" TextWrapping = "Wrap" />  
      <Button x:Name = "increaseQuota" Content = "Increase" HorizontalAlignment = "Center" 
         FontSize = "20" 
         VerticalAlignment = "Center" Click = "increaseQuota_Click" /> 
   </Grid>
	
</UserControl>

以下是增加配額的click 事件的實現。

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Net; 

using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Documents; 
using System.Windows.Input;
using System.Windows.Media; 
using System.Windows.Media.Animation; 
using System.Windows.Shapes; 

using System.IO.IsolatedStorage;
  
namespace ChangeQuota { 

   public partial class MainPage : UserControl { 
	
      public MainPage() { 
         InitializeComponent(); 
      } 
	  
      private void increaseQuota_Click(object sender, RoutedEventArgs e) { 
         using (IsolatedStorageFile isoStore = 
            IsolatedStorageFile.GetUserStoreForApplication()) { 
               long newQuota = isoStore.Quota + 10240; 
					
               if (isoStore.IncreaseQuotaTo(newQuota)) { 
                  infoText.Text = "Quota is " + isoStore.Quota + ", free space: " + 
                  isoStore.AvailableFreeSpace; 
               } else { 
                  infoText.Text = "Meanie!"; 
               } 
         } 
      } 
   } 
} 

編譯並執行上述程式碼後,您將看到以下輸出。

Isolated storage Quota

單擊增加時,將顯示提示。它要求將配額增加到比其當前值大 10KB。

Isolated Increase Quota

單擊後,它將打印出可用的配額數量。

Increase Quota

我們建議您執行以上示例以更好地理解。

Silverlight - 文字

在本章中,我們將瞭解 Silverlight 提供了哪些功能來顯示文字。文字塊用於所有文字呈現和 Silverlight。其他重要功能包括:

  • 它可以用於簡單的純文字,也可以應用各種格式樣式的混合。
  • Silverlight 支援一組標準的內建字型。
  • 當您的應用程式視覺樣式需要一些不尋常的東西時,您還可以下載自定義字型。

TextBlock

要顯示文字,我們使用 Silverlight 文字框元素,它是一個輕量級控制元件,用於顯示少量只讀文字。事實上,我們已經多次看到它,因為它的基本用法實際上不需要太多解釋。您只需設定 text 屬性,它就會為您顯示該文字。

<TextBlock Text = "Print Testing" HorizontalAlignment Center" FontFamily = "Georgia"/> 

TextBlock 類的層次繼承如下:

TextBlock

以下是TextBlock 類常用的屬性

序號 屬性和描述
1

ContentEnd

獲取 TextBlock 中文字內容末尾的 TextPointer 物件。

2

ContentStart

獲取 TextBlock 中文字內容開頭的 TextPointer 物件。

3

IsTextSelectionEnabled

獲取或設定一個值,該值指示是否在 TextBlock 中啟用了文字選擇,無論是透過使用者操作還是呼叫與選擇相關的 API。

4

IsTextSelectionEnabledProperty

標識 IsTextSelectionEnabled 依賴項屬性。

5

LineHeight

獲取或設定內容每一行的高度。

6

MaxLines

獲取或設定 TextBlock 中顯示的最大文字行數。

7

SelectedText

獲取所選文字的文字範圍。

8

SelectionEnd

獲取 TextBlock 中所選文字的結束位置。

9

SelectionHighlightColor

獲取或設定用於突出顯示所選文字的畫刷。

10

SelectionStart

獲取 TextBlock 中所選文字的起始位置。

11

Text

獲取或設定 TextBlock 的文字內容。

12

TextAlignment

獲取或設定一個值,該值指示文字內容的水平對齊方式。

13

TextTrimming

獲取或設定當內容超出內容區域時要採用的文字修剪行為。

14

TextWrapping

獲取或設定 TextBlock 如何換行文字。

以下是TextBlock 類常用的事件

序號 事件及說明
1

ContextMenuOpening

當系統處理顯示上下文選單的互動時發生。

2

SelectionChanged

文字選擇發生更改時發生。

以下是TextBlock 類常用的方法

序號 方法及描述
1

Focus

將焦點設定到 TextBlock 上,就像它是常規的可聚焦控制元件一樣。

2

Select

選擇 TextBlock 中的一段文字。

3

SelectAll

選擇 TextBlock 中的全部內容。

Run

有時您希望對格式進行細粒度控制,併為整個文字塊設定一種樣式。有時對單個單詞甚至字母進行格式化很有用,如果您想要這樣做,那麼不要使用Text 屬性,而是將文字作為內容放在TextBlock 中。如果您使用程式碼,則對應於向TextBlock 內聯屬性新增項。

使用這種方法,您可以新增一系列 run 元素。每個 Run 都支援相同的字體系列、字型粗細、前景色等屬性來控制文字樣式。儘管 Run 是一個單獨的元素,但這不會中斷流程。

讓我們來看一個簡單的示例,它包含TextBlock 內部的多個Run 元素。以下是 XAML 程式碼。

<UserControl x:Class = "SilverlightRunDemo.MainPage" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   mc:Ignorable = "d" 
   d:DesignHeight = "300" d:DesignWidth = "400">
	
   <Grid x:Name = "LayoutRoot" Background = "White"> 
	
      <TextBlock Width = "192" TextWrapping = "Wrap" FontFamily = "Verdana"> 
         <Run Text = "Hello, " /> 
         <Run FontWeight = "Bold" Text = "world!" /> 
         <Run Text = "You" /> 
         <Run FontStyle = "Italic" Text = " are  " /> 
         <Run Text = "learning" FontSize = "40" FontFamily = "01d English Text MT" /> 
         <Run Text = "   the " /> 
         <Run Text = "basics of " Foreground = "Blue" /> 
         <Run Text = " Silverlight." FontSize = "30" /> 
      </TextBlock> 
		
   </Grid> 
	
</UserControl>

編譯並執行上述程式碼後,您將看到以下輸出。

Run Inside TextBlock

如您所見,此文字塊透過使用Run 元素以不同的格式樣式進行排列。

順便說一句,您不需要將每一小段文字都包裝在 run 中。您可以將文字塊的大部分內容保留為純文字,只需對需要不同格式的部分應用run,如下所示。

<TextBlock> Hello,  
   <Run FontWeight = "Bold" Text =" world!"/> 
</TextBlock> 

LineBreak

Silverlight 通常會忽略 XAML 中的換行符。它假設大多數空格是為了使它們更易於閱讀,因為您實際上希望該空格出現。

讓我們來看一下這段 XAML 程式碼,它包含三行單獨的文字。

<TextBlock>  
   This is not the end. 
   It is not even the beginning of the end. 
   But it is, perhaps, the end of the beginning 
</TextBlock> 

編譯並執行上述程式碼後,您將看到以下輸出。

LineBreak

如您所見,它忽略了換行符,並將所有文字一起執行。

  • 如果啟用文字換行,它將在需要換行以使文字適合的地方插入換行符,但它會忽略示例中的換行符。

  • 如果您只想新增顯式換行符,則需要在文字塊內新增換行符標記。其後的文字將從新行開始。

讓我們再次檢視相同的示例,方法是新增LineBreak 標記。

<TextBlock FontSize = "16">  
   This is not the end. 
   <LineBreak/> 
	
   It is not even the beginning of the end. 
   <LineBreak/> 
	
   But it is, perhaps, the end of the beginning
</TextBlock> 

執行上述程式碼後,您將看到它現在看起來與 XAML 中指定的相同。

Add LineBreak Tag

內建字型

Silverlight 有一組固定的內建字體系列。由於歷史原因,這些字型的字體系列名稱實際上有所不同。預設字體系列在 Mac OS 和 Windows 上在技術上是不同的,例如在 Mac OS 上它是 Lucida Grande,而在 Windows 上它是幾乎相同但命名為 Lucida Sans Unicode 的字型。

下面給出了一些最常用的字型。

字型
Arial
Arial Black
Comic Sans MS
Courier New
Georgia
Lucida Grande (Mac) 或 Lucida Sans Unicode (Windows)
Times New Roman
Trebuchet MS
Verdana

Silverlight - 動畫

動畫允許您建立真正動態的使用者介面。它通常用於應用效果,例如,您移動滑鼠時增大的圖示、旋轉的徽標、滾動到檢視中的文字等等。

有時,這些效果看起來像是過度的炫耀。如果使用得當,動畫可以多種方式增強應用程式。它們可以讓應用程式看起來更具響應性、更自然和更直觀。

例如,當您單擊時滑入的按鈕感覺像一個真實的物理按鈕,而不僅僅是另一個灰色的矩形。動畫還可以吸引使用者注意重要元素,並指導使用者過渡到新內容。

Silverlight 的動畫方法是宣告式的,而不是專注於幀動畫的序列。

定義動畫

動畫通常在資源部分定義。實際上,它們通常包裝在一個故事板元素中,我們很快就會詳細瞭解。

  • 它提供了一個 Begin() 方法,因此可以從程式碼中呼叫動畫。

  • 動畫也可以放在控制元件模板中的視覺狀態元素內部。

宣告式動畫

Silverlight 中的動畫是宣告式的。它們描述了您希望發生的事情。讓 Silverlight 自己解決如何實現它。因此,動畫通常遵循以下模式:我們告訴 Silverlight 我們希望更改什麼。

這始終是某些命名元素上的一些屬性,即 **TargetName** 和 **TargetProperty**。

<DoubleAnimation 
   Storyboard.TargetName = "myRectangle" 
   Storyboard.TargetProperty = "Opacity" 
   From = "0" To = "1" 
   Duration = "0:0:5"  
/>
  • 我們說明我們希望該屬性如何更改,在這種情況下,我們將不透明度從值 0 更改為值 1。換句話說,我們希望目標元素從不透明淡化為透明。

  • 最後,我們說明我們希望這需要多長時間,在這種情況下,將需要 5 秒。

  • 此雙動畫中的雙精度數的意義在於它針對一個型別為雙精度數的屬性,即浮點值。

  • 如果您想動畫化表示顏色的屬性,則可以使用顏色動畫。

讓我們來看一個雙動畫的簡單示例。下面是 XAML 程式碼,其中添加了兩個按鈕、一個矩形和兩個故事板。

<UserControl x:Class = "DoubleAnimationExample.MainPage" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008"  
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006"  
   mc:Ignorable = "d" d:DesignWidth = "640" d:DesignHeight = "480">
   
   <UserControl.Resources> 
	
      <Storyboard x:Name = "fadeDown"> 
         <DoubleAnimation  
            Storyboard.TargetName = "myRectangle" 
            Storyboard.TargetProperty = "Opacity" 
            From = "1" To = "0" 
            Duration = "0:0:5" /> 
      </Storyboard> 
		
      <Storyboard x:Name = "fadeUp"> 
         <DoubleAnimation 
            Storyboard.TargetName = "myRectangle" 
            Storyboard.TargetProperty = "Opacity" 
            From = "0" To = "1" 
            Duration = "0:0:5" /> 
      </Storyboard> 
		
   </UserControl.Resources> 
	
   <Grid x:Name = "LayoutRoot"> 
      <Rectangle x:Name = "myRectangle" 
         Fill = "Blue" Width = "300" Height = "100"  
         HorizontalAlignment = "Center" 
         VerticalAlignment = "Top" Margin = "0,30" /> 
			
      <Button x:Name = "fadeUpButton" Content = "Up" Width = "80"  
         Height = "30" HorizontalAlignment = "Left" 
         VerticalAlignment = "Top" Margin = "50,140,0,0"  
         Click = "fadeUpButton_Click" /> 
			
      <Button x:Name = "fadeDownButton" Content = "Down"  
         Width = "80" Height = "30" HorizontalAlignment = "Left" 
         VerticalAlignment = "Top" Margin = "50,180,0,0"  
         Click = "fadeDownButton_Click" />
			
   </Grid>
	
</UserControl> 

以下是 C# 中不同事件的實現。

using System.Windows; 
using System.Windows.Controls;  

namespace DoubleAnimationExample { 

   public partial class MainPage : UserControl { 
	
      public MainPage() { 
         InitializeComponent(); 
      } 
	  
      private void fadeUpButton_Click(object sender, RoutedEventArgs e) { 
         fadeUp.Begin(); 
      }
	  
      private void fadeDownButton_Click(object sender, RoutedEventArgs e) { 
         fadeDown.Begin(); 
      } 
   } 
}

編譯並執行上述程式碼後,您將看到以下輸出。

Declarative Animation

重複和反轉

動畫提供了一些屬性來自動重複和全部反轉動畫。

  • 如果將 RepeatBehavior 屬性設定為時間跨度,則動畫將迴圈重複,直到指定的持續時間過去,或者您也可以只告訴它希望它重複多少次。

  • 這支援小數點,因此您可以重複 4.5 次。

  • 您可以永遠重複,也可以告訴動畫,一旦它到達結尾,它應該反向執行回到開始。

關鍵幀動畫

通常,從 A 到 B 的簡單動畫過於簡單。例如,您想動畫化一個球彈離地面。這不是簡單的點到點運動。球體下降,速度逐漸加快,然後在觸底時反轉方向。在回到其行程的頂部時再次減速。

讓我們來看一個 **關鍵幀動畫** 的簡單示例。

下面是 XAML 程式碼,其中包含一個橢圓和帶有關鍵幀的雙動畫。

<UserControl x:Class = "LinearKeyFrames.MainPage" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006"  
   mc:Ignorable = "d" 
   Width = "400" Height = "300">
   
   <UserControl.Resources> 
	
      <Storyboard x:Name = "ballAnim" SpeedRatio = "0.2"> 
         <DoubleAnimation From = "0" Duration = "00:00:03" To = "96" 
            Storyboard.TargetName = "ellipse" 
            Storyboard.TargetProperty = "(Canvas.Left)" />
				
         <DoubleAnimationUsingKeyFrames  
            Storyboard.TargetName = "ellipse" 
            Storyboard.TargetProperty = "(Canvas.Top)"> 

            <LinearDoubleKeyFrame KeyTime = "00:00:00"   Value = "0"/> 
            <LinearDoubleKeyFrame KeyTime = "00:00:00.5" Value = "16" /> 
            <LinearDoubleKeyFrame KeyTime = "00:00:01"   Value = "48"/> 
            <LinearDoubleKeyFrame KeyTime = "00:00:01.5" Value = "112"/> 
            <LinearDoubleKeyFrame KeyTime = "00:00:02"   Value = "48"/> 
            <LinearDoubleKeyFrame KeyTime = "00:00:02.5" Value = "16"/> 
            <LinearDoubleKeyFrame KeyTime = "00:00:03"   Value = "0"/> 
				
         </DoubleAnimationUsingKeyFrames> 
			
      </Storyboard>
		
   </UserControl.Resources>
	
   <Grid x:Name = "LayoutRoot" Background = "White"> 
      <Canvas> 
         <Ellipse x:Name = "ellipse" Fill = "Aqua" Width = "50" Height = "50" /> 
      </Canvas> 
   </Grid> 
	
</UserControl> 

以下是 **滑鼠左鍵** 按下事件的實現,當用戶在網頁上按下滑鼠左鍵時,它將開始動畫。

using System.Windows.Controls; 
using System.Windows.Input; 
 
namespace LinearKeyFrames { 

   public partial class MainPage : UserControl {
	
      public MainPage() { 
         InitializeComponent();  
         this.MouseLeftButtonDown += new MouseButtonEventHandler(Page_MouseLeftButtonDown); 
      } 
	  
      void Page_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { 
         ballAnim.Begin(); 
      } 
   } 
} 

編譯並執行上述程式碼後,您將看到以下輸出。

Key Frame Animation

當您單擊網頁時,您將看到球開始移動。

Key Frame Animation Move

Silverlight - 影片和音訊

在本章中,我們將瞭解 Silverlight 功能如何播放影片和音訊。**MediaElement** 是 Silverlight 中所有影片和音訊的核心。這允許您在應用程式中整合音訊和影片。**MediaElement** 類的工作方式類似於 **Image** 類。您只需將其指向媒體,它就會呈現音訊和影片。

主要區別在於它將是移動影像,但如果您將其指向僅包含音訊而不包含影片的檔案(例如 MP3),它將在不顯示任何螢幕內容的情況下播放該音訊。

MediaElement 作為 UI 元素

**MediaElement** 派生自框架元素,它是所有 Silverlight 使用者介面元素的基類。這意味著它提供了所有標準屬性,因此您可以修改其不透明度,可以設定剪輯或對其進行轉換等等。

讓我們來看一個 **MediaElement** 的簡單示例。

開啟 Microsoft Blend for Visual Studio 並建立一個新的 Silverlight 應用程式專案。

MediaElement App

現在將影片或音訊檔案拖放到 Blend 設計圖面。

MediaElement Application

它將向圖面新增一個 MediaElement,並在您的專案中新增影片檔案的副本。您可以在解決方案資源管理器中看到它。

MediaElement To Surface

您可以將其移動到周圍,更改其大小,您可以執行諸如應用旋轉等操作。

Rotation

現在,它將在 **MainPage.xaml** 檔案中為您生成相關的 XAML,如下所示。

<UserControl x:Class = "MediaElementDemo.MainPage" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   mc:Ignorable = "d" 
   d:DesignHeight = "300" d:DesignWidth = "400">
   
   <Grid x:Name = "LayoutRoot" Background = "White">
	
      <MediaElement x:Name = "Microsoft_Silverlight_DEMO_mp4"  
         Margin = "51,49,53,53"  
         Source = "/Microsoft Silverlight DEMO.mp4"  
         Stretch = "Fill" RenderTransformOrigin = "0.5,0.5">
			
         <MediaElement.RenderTransform> 
            <CompositeTransform Rotation = "-18.384"/>
         </MediaElement.RenderTransform> 
			
      </MediaElement>  
		
   </Grid> 
	
</UserControl>

編譯並執行上述應用程式後,您將看到影片正在您的網頁上播放。

XAML Generate

控制

**MediaElement** 僅呈現媒體。它不提供任何標準播放器控制元件。它自動開始播放並在到達結尾時停止,使用者無法執行暫停或其他控制操作。因此,在實踐中,大多數應用程式都希望為使用者提供更多控制權。

您可以透過將 **AutoPlay** 設定為 **False** 來停用自動播放。這意味著媒體播放器在您要求之前不會播放任何內容。

<MediaElement x:Name = "Microsoft_Silverlight_DEMO_mp4" 
   AutoPlay = "False" 
   Margin = "51,49,53,53"  
   Source = "/Microsoft Silverlight DEMO.mp4"  
   Stretch = "Fill" RenderTransformOrigin = "0.5,0.5">

因此,當您想播放影片時,您可以直接呼叫 **MediaElement Play() 方法**。它還提供停止和暫停方法。

讓我們再次檢視相同的示例,並對其進行一些修改以允許一些控制。在 **MediaElement** 中附加 **MouseLeftButtonDown** 處理程式,如以下 XAML 程式碼所示。

<UserControl x:Class = "MediaElementDemo.MainPage" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   mc:Ignorable = "d" 
   d:DesignHeight = "300" d:DesignWidth = "400">
   
   <Grid x:Name = "LayoutRoot" Background = "White"> 
	
      <MediaElement x:Name = "Microsoft_Silverlight_DEMO_mp4" 
         AutoPlay = "False" 
         MouseLeftButtonDown = "Microsoft_Silverlight_DEMO_mp4_MouseLeftButtonDown" 
         Margin = "51,49,53,53"  
         Source = "/Microsoft Silverlight DEMO.mp4"  
         Stretch = "Fill" RenderTransformOrigin = "0.5,0.5"> 
      </MediaElement>  
		
   </Grid> 
	
</UserControl>

以下是 **MouseLeftButtonDown** 事件處理程式的實現,它將檢查媒體元素的當前狀態是否正在播放,如果是則暫停影片,否則開始播放影片。

using System.Windows.Controls; 
using System.Windows.Input; 
using System.Windows.Media;

namespace MediaElementDemo { 

   public partial class MainPage : UserControl {
	
      public MainPage() { 
         InitializeComponent(); 
      }  
		
      private void Microsoft_Silverlight_DEMO_mp4_MouseLeftButtonDown
         (object sender, MouseButtonEventArgs e) {
		
         if (Microsoft_Silverlight_DEMO_mp4.CurrentState == MediaElementState.Playing) { 
            Microsoft_Silverlight_DEMO_mp4.Pause(); 
         } else { 
            Microsoft_Silverlight_DEMO_mp4.Play(); 
         } 
      } 
   } 
}

編譯並執行上述程式碼後,您將看到空白的網頁,因為我們已將 **AutoPlay** 屬性設定為 **False**。當您單擊網頁時,它將開始播放影片。

AutoPlay Generate

當您再次單擊網頁時,它將暫停影片。

Silverlight - 列印

列印對於某些型別的應用程式而言是一項重要的功能。在本章中,我們將瞭解 Silverlight 中的相關功能。

  • 列印 API,以及所有 Silverlight 應用程式如果要列印必須執行的基本步驟。選擇水印的各種選項。

  • 最簡單的方法是列印螢幕上已有的使用者介面元素的副本。

  • 大多數應用程式都希望比這更高階,並生成專門用於列印的內容,在某些情況下,需要將內容拆分為多個頁面。

列印步驟

無論您是列印螢幕截圖還是螢幕上已有的內容,還是進行完全自定義的多頁列印輸出,都需要執行相同的基本步驟。

  • 列印 API 的核心是 PrintDocument 類。

  • 您首先構造其中一個,當您呼叫其 Print 方法時,它將顯示啟動列印作業的標準使用者介面。

Steps for Printing
  • 使用者可以像往常一樣選擇印表機並配置設定。如果使用者隨後透過單擊 **列印** 決定繼續,則 **PrintDocument** 將立即引發其 **PrintPage** 事件,並且您對該事件的處理程式將提供要列印的內容。

  • 事件引數為此目的提供了一個 **PageVisual** 屬性。

  • 您可以將其設定為任何 Silverlight 使用者介面元素,無論是螢幕上已可見的元素,還是專門為列印建立的新元素。

列印現有元素

元素最簡單的選項是列印 Silverlight 應用程式中螢幕上已有的內容。由於 **PrintPage** 事件引數 **PageVisual** 接受任何使用者介面元素,因此您可以選擇使用者介面中的任何內容並進行列印。

  • 這與使用 PrintScreen 鍵擷取螢幕截圖僅有一小步之遙。它比這稍微好一點,因為使用者不必手動將螢幕截圖貼上到其他程式中進行裁剪和列印。它仍然只是一次輕微的改進。

  • 列印螢幕上已有的內容存在問題。

  • 首先,無法保證在螢幕上有效的佈局在紙張上也能很好地工作。

讓我們來看一個簡單的示例,其中 **ScrollViewer** 包含一些 UI 元素,其佈局適合螢幕。它根據瀏覽器視窗大小調整大小,並提供捲軸以確保即使不適合也能訪問所有內容。

下面是 XAML 程式碼。

<UserControl 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   xmlns:sdk = "http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" 
   x:Class = "SilverlightPrinting.MainPage" 
   mc:Ignorable = "d" 
   d:DesignHeight = "300" d:DesignWidth = "500">
	
   <Grid x:Name = "LayoutRoot" Background = "White">
	
      <Button x:Name = "print" Content = "Print" Click = "print_Click" Width = "60" 
         Height = "20" Margin = "10,10,430,270"/>
			
      <ScrollViewer x:Name = "myScrollViewer" 
         HorizontalScrollBarVisibility = "Auto" 
         VerticalScrollBarVisibility = "Auto" 
         Width = "400" Margin = "90,0,10,0">
			
         <StackPanel>
            <Rectangle Fill = "Gray" Width = "100" Height = "100" /> 
            <Button x:Name = "button" Content = "Button" Width = "75"/> 
            <sdk:Calendar Height = "169" Width = "230"/> 
            <Rectangle Fill = "AliceBlue" Width = "475" Height = "100" /> 
         </StackPanel> 
				
      </ScrollViewer> 
		
   </Grid> 
	
</UserControl>

以下是 **列印** 按鈕的單擊事件實現,它將列印 **ScrollViewer** 及其可見資料。

using System; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Printing; 
 
namespace SilverlightPrinting { 

   public partial class MainPage : UserControl { 
	
      public MainPage() { 
         InitializeComponent(); 
      }
	  
      private void print_Click(object sender, RoutedEventArgs e) { 
         PrintDocument pd = new PrintDocument(); 
         pd.PrintPage += new System.EventHandler<PrintPageEventArgs>(pd_PrintPage);  
         pd.Print("Print Screen Content"); 
      }
	  
      private void pd_PrintPage(object sender, PrintPageEventArgs e) { 
         e.PageVisual = myScrollViewer; 
      } 
   } 
}
  • 如您所見,在 **列印按鈕單擊事件** 中建立了 **PrintDocument** 物件,我們將一個處理程式附加到其 PrintPage 事件。

  • 您可以將 **PageVisual** 屬性設定為引用 **ScrollViewer**。

  • 然後呼叫 **Print 方法**。這將採用一個字串,該字串將在列印佇列中顯示為作業名稱。

編譯並執行上述程式碼後,您將看到以下輸出。

PrintDocument

當您單擊 **列印** 按鈕時,您將看到標準的列印對話方塊。

PrintDocument OneNote

現在,選擇預設印表機。為了演示目的,讓我們選擇 **OneNote** 並單擊 **列印** 按鈕。您將看到 **ScrollViewer** 已列印。

Print ScrollViewer

請注意,捲軸仍顯示在 **ScrollViewer** 上。

自定義 UI 樹

與其列印螢幕上已有的內容,通常更有意義的是專門為列印構建一個使用者介面元素樹。這樣,您可以確保在紙上只使用非互動式元素,並且可以建立更適合紙張形狀和尺寸的專用佈局。您可以建立一個專門用於列印的 UserControl。

讓我們來看一個簡單的例子,建立一個 Silverlight 專案並新增一個名為PrintLayoutUserControl

PrintLayout

將設計時寬度和高度設定為大約紙張的形狀。以下是PrintLayout.xaml檔案的 XAML 程式碼。

<UserControl x:Class = "PrintCustomUI.PrintLayout" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   mc:Ignorable = "d" 
   d:DesignHeight = "768" d:DesignWidth = "960">
   
   <Grid x:Name = "LayoutRoot" Background = "White"> 
	
      <Grid.RowDefinitions> 
         <RowDefinition Height = "Auto" /> 
         <RowDefinition /> 
         <RowDefinition Height = "Auto" /> 
      </Grid.RowDefinitions> 
		
      <TextBlock Text = "Silverlight" HorizontalAlignment = "Center"
         FontSize = "60" FontWeight = "Bold" FontFamily = "Georgia" />
				
      <TextBlock Grid.Row = "2" Text = "Print Testing" 
         HorizontalAlignment = "Center" FontFamily = "Georgia" 
         FontSize = "24" Margin = "0,10"/> 
				
      <Rectangle Grid.Row = "2" Height = "1" Fill = "Black" 
         VerticalAlignment = "Top"/> 
				
      <Ellipse Grid.Row = "1" Stroke = "Black" StrokeThickness = "10" Margin = "10">
				
         <Ellipse.Fill>
			
            <RadialGradientBrush 
               GradientOrigin = "0.2,0.2" 
               Center = "0.4,0.4"> 
               <GradientStop Color = "Aqua" Offset = "0.006" /> 
               <GradientStop Color = "AntiqueWhite" Offset = "1" /> 
            </RadialGradientBrush>
				
         </Ellipse.Fill>
			
      </Ellipse> 
		
   </Grid> 
	
</UserControl> 

以下是MainPage.xaml檔案中的程式碼,其中僅包含一個Print按鈕。

<UserControl x:Class = "PrintCustomUI.MainPage" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   mc:Ignorable = "d" 
   d:DesignHeight = "300" d:DesignWidth = "400">
   
   <Grid x:Name = "LayoutRoot" Background = "White"> 
	
      <Button Content = "Print..." Height = "23" HorizontalAlignment = "Left"  
         Margin = "12,28,0,0" Name = "printButton"  
         VerticalAlignment = "Top" Width = "75"  
         Click = "printButton_Click" />
			
   </Grid> 
	
</UserControl>

以下是列印按鈕的Click 事件實現。

using System; 
using System.Collections.Generic; 
using System; 

using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Printing;
  
namespace PrintCustomUI { 

   public partial class MainPage : UserControl { 
	
      public MainPage() { 
         InitializeComponent(); 
      }
	  
      private void printButton_Click(object sender, RoutedEventArgs e) { 
         PrintDocument pd = new PrintDocument(); 
         pd.PrintPage += new EventHandler<PrintPageEventArgs>(pd_PrintPage);
         pd.Print("Custom"); 
      }
	  
      void pd_PrintPage(object sender, PrintPageEventArgs e) { 
         var pl = new PrintLayout(); 
         pl.Width = e.PrintableArea.Width; 
         pl.Height = e.PrintableArea.Height; 
         e.PageVisual = pl; 
      } 
   } 
}

編譯並執行上述程式碼後,您將在網頁上看到以下輸出。

Print Button

點選Print並選擇OneNote列印佈局。您將看到佈局已列印。

Select OneNote to Print

您可以看到它已經填充了可用空間。我們建議您執行以上示例以更好地理解。

廣告