XAML 快速指南



XAML - 概述

XAML 代表可擴充套件應用程式標記語言 (Extensible Application Markup Language)。它是一種基於 XML 的簡單宣告式語言。

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

  • 它主要用於設計 GUI。

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

XAML 可用於不同的平臺,例如 WPF(Windows Presentation Foundation)、Silverlight、移動開發和 Windows 應用商店應用。它可以在不同的 .NET 框架和 CLR(公共語言執行時)版本中使用。

XAML 的工作原理

XAML 是一種宣告式語言,因為它定義了您想要做什麼的目標方法。XAML 處理器負責找出方法部分。讓我們看一下下面的模式。它總結了 XAML 的方面:

XAML Works

該圖說明了以下操作:

  • XAML 檔案由特定於平臺的 XAML 處理器解釋。

  • XAML 處理器將 XAML 轉換為描述 UI 元素的內部程式碼。

  • 內部程式碼和 C# 程式碼透過部分類定義連結在一起,然後 .NET 編譯器構建應用程式。

XAML 的優點

使用 XAML 可以解決我們在 GUI 設計中長期面臨的一個問題。它可以用於設計 Windows 窗體應用程式中的 UI 元素。

在早期的 GUI 框架中,應用程式的外觀和行為之間沒有真正的分離。GUI 和其行為都在同一種語言(例如 C# 或 VB.net)中建立,這需要開發人員付出更多努力來實現 UI 及其相關的行為。

GUI Frameworks

使用 XAML,很容易將行為與設計程式碼分離。因此,XAML 程式設計師和設計師可以並行工作。XAML 程式碼非常易於閱讀和理解。

Xaml Framework

XAML - 環境設定

Microsoft 提供了兩個重要的 XAML 工具:

  • Visual Studio
  • Expression Blend

目前,這兩個工具都可以建立 XAML,但事實是 Visual Studio 更受開發人員使用,而 Expression Blend 仍然更常被設計師使用。

Microsoft 提供了 Visual Studio 的免費版本,可以從 https://www.visualstudio.com/en-us/downloads/download-visual-studio-vs.aspx 下載

注意 -在本教程中,我們將主要使用 WPF 專案和 Windows 應用商店應用。但是 Visual Studio 的免費版本不支援 Windows 應用商店應用。因此,為此目的,您需要 Visual Studio 的許可版本。

安裝

按照以下步驟在您的系統上安裝 Visual Studio:

  • 下載檔案後,執行安裝程式。將顯示以下對話方塊。

Visual Studio Dialog Box
  • 單擊“安裝”按鈕,它將啟動安裝過程。

Install
  • 安裝過程成功完成後,您將看到以下螢幕。

Visual Studio Setup Completed
  • 關閉此對話方塊,如果需要,重新啟動計算機。

  • 現在從“開始”選單開啟 Visual Studio,它將顯示以下對話方塊。第一次需要一些時間,僅用於準備。

Visual Studio Start Menu

完成後,您將看到 Visual Studio 的主視窗。

Main Window

實現的第一步

讓我們從一個簡單的實現開始。請按照以下步驟操作:

  • 單擊“檔案”→“新建”→“專案”選單選項。

Project Menu
  • 將顯示以下對話方塊:

Dialog Box
  • 在“模板”下,選擇 Visual C# 並選擇 WPF 應用程式。為專案命名,然後單擊“確定”按鈕。

  • 在 mainwindow.xaml 檔案中,預設情況下會編寫以下 XAML 標記。您將在本教程的後面部分了解所有這些標記。

<Window x:Class = "FirstStepDemo.MainWindow"
   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:local = "clr-namespace:FirstStepDemo" 
   mc:Ignorable = "d" Title = "MainWindow" Height = "350" Width = "604"> 
	
   <Grid> 
         
   </Grid> 
</Window> 

預設情況下,網格被設定為頁面後的第一個元素。

讓我們在 Grid 元素下新增一個按鈕和一個文字塊。這稱為物件元素語法,左尖括號後跟我們要例項化的內容的名稱,例如按鈕,然後定義一個內容屬性。分配給 Content 的字串將顯示在按鈕上。現在將按鈕的高度和寬度分別設定為 30 和 50。同樣初始化文字塊的屬性。

現在檢視設計視窗。您將看到一個按鈕。現在按 F5 執行此 XAML 程式碼。

<Window x:Class = "FirstStepDemo.MainWindow" 
   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:local = "clr-namespace:FirstStepDemo" 
   mc:Ignorable = "d" Title = "MainWindow" Height = "350" Width = "604"> 
	
   <Grid> 
      <Button Content = "First Button" Height = "30" Width = "80"/> 
      <TextBlock Text = "Congratulations you have successfully build your first app" 
         Height = "30" Margin = "162,180,122,109"/> 
   </Grid> 
	
</Window> 

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

First Button

恭喜!您已經設計了您的第一個按鈕。

在 macOS 上編寫 XAML 應用程式

XAML 應用程式也可以在 Mac 上開發。在 Mac 上,XAML 可用作 iOS 和 Android 應用程式。要在 Mac 上設定環境,請訪問 www.xamarin.com。單擊“產品”,然後選擇 Xamarin 平臺。下載並安裝 Xamarin Studio。它將允許您為各種平臺開發應用程式。

XAML – C# 語法

本章將學習編寫 XAML 應用程式的基本 XAML 語法/規則。讓我們來看一個簡單的 XAML 檔案。

<Window x:Class = "Resources.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" Title = "MainWindow" Height = "350" Width = "525"> 
	
   <Grid> 
         
   </Grid> 
</Window> 

正如您在上面的 XAML 檔案中看到的,有不同型別的標記和元素。下表簡要描述了所有元素。

序號 元素和描述
1

<Window

它是根的起始物件元素或容器。

2

x:Class="Resources.MainWindow"

它是部分類宣告,它將標記連線到在其中定義的程式碼隱藏部分類。

3

xmlns

對映 WPF 客戶端/框架的預設 XAML 名稱空間

4

xmlns:x

XAML 語言的 XAML 名稱空間,將其對映到 x: 字首

5

>

根物件的元素結束。

6

<Grid>

</Grid>

空網格物件的起始和結束標記。

7

</Window>

關閉物件元素

物件元素的語法規則

XAML 的語法規則幾乎與 XML 相同。如果您檢視 XAML 文件,您會注意到它實際上是一個有效的 XML 檔案。但是,XML 檔案不可能是有效的 XAML 檔案。這是因為在 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> 

XAML 與 C# 程式碼對比

您可以使用 XAML 建立、初始化和設定物件的屬性。相同的活動也可以使用程式設計程式碼執行。

XAML 只是一種簡單易用的設計 UI 元素的方法。使用 XAML,您可以決定是在 XAML 中宣告物件還是使用程式碼宣告它們。

讓我們來看一個簡單的例子,演示如何在 XAML 中編寫:

<Window x:Class = "XAMLVsCode.MainWindow"
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" Title = "MainWindow" Height = "350" Width = "525"> 
	
   <StackPanel> 
      <TextBlock Text = "Welcome to XAML Tutorial" Height = "20" Width = "200" Margin = "5"/>
      <Button Content = "Ok" Height = "20" Width = "60" Margin = "5"/> 
   </StackPanel> 
	
</Window> 

在這個例子中,我們建立了一個包含按鈕和文字塊的堆疊面板,並定義了按鈕和文字塊的一些屬性,例如高度、寬度和邊距。編譯並執行上述程式碼後,將生成以下輸出:

XAML C# Code

現在來看一下用 C# 編寫的相同程式碼。

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

namespace XAMLVsCode { 
   /// <summary> 
      /// Interaction logic for MainWindow.xaml 
   /// </summary> 
	
   public partial class MainWindow : Window {
      public MainWindow() { 
         InitializeComponent();  
         
         // Create the StackPanel 
         StackPanel stackPanel = new StackPanel();
         this.Content = stackPanel; 
			
         // Create the TextBlock 
         TextBlock textBlock = new TextBlock(); 
         textBlock.Text = "Welcome to XAML Tutorial"; 
         textBlock.Height = 20;
         textBlock.Width = 200; 
         textBlock.Margin = new Thickness(5); 
         stackPanel.Children.Add(textBlock);  
			
         // Create the Button 
         Button button = new Button(); 
         button.Content = "OK"; 
         button.Height = 20; 
         button.Width = 50; 
         button.Margin = new Thickness(20); 
         stackPanel.Children.Add(button); 
      } 
   }
}

編譯並執行上述程式碼後,將生成以下輸出。請注意,它與 XAML 程式碼的輸出完全相同。

C# Code Output

現在您可以看到使用和理解 XAML 是多麼簡單。

XAML 與 VB.NET 對比

本章將用 VB.Net 編寫相同的示例,以便熟悉 VB.Net 的人也可以理解 XAML 的優點。

讓我們再次來看一下用 XAML 編寫的相同示例:

<Window x:Class = "XAMLVsCode.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" Title = "MainWindow" Height = "350" Width = "604"> 
	
   <StackPanel> 
      <TextBlock Text = "Welcome to XAML Tutorial with VB.net" Height = "20" Width = "220" Margin = "5"/> 
      <Button Content = "Ok" Height = "20" Width = "60" Margin = "5"/> 
   </StackPanel> 
	
</Window> 

在這個例子中,我們建立了一個包含按鈕和文字塊的堆疊面板,並定義了按鈕和文字塊的一些屬性,例如高度、寬度和邊距。編譯並執行上述程式碼後,將生成以下輸出:

Xaml Vb.net

現在來看一下用 VB.Net 編寫的相同程式碼:

Public Class MainWindow
   Private Sub Window_Loaded(sender As Object, e As RoutedEventArgs) 
      Dim panel As New StackPanel() 
      panel.Orientation = Orientation.Vertical 
      Me.Content = panel 
      Dim txtInput As New TextBlock 
		
      txtInput.Text = "Welcome to XAML Tutorial with VB.net" 
      txtInput.Width = 220 
      txtInput.Height = 20 
      txtInput.Margin = New Thickness(5) 
		
      panel.Children.Add(txtInput)  
      Dim btn As New Button()
		
      btn.Content = "Ok" 
      btn.Width = 60 
      btn.Height = 20 
      btn.Margin = New Thickness(5) 
		
      panel.Children.Add(btn)
   End Sub 
End Class 

編譯並執行上述程式碼後,輸出與 XAML 程式碼的輸出完全相同。

Xaml Vb.Net

現在您可以看到與 VB.Net 相比,使用 XAML 是多麼簡單。

在上面的示例中,我們看到在 XAML 中可以完成的操作也可以在其他過程語言(如 C# 和 VB.Net)中完成。

讓我們來看另一個示例,在這個示例中我們將同時使用 XAML 和 VB.Net。我們將使用 XAML 設計 GUI,並在 VB.Net 中實現行為。

在這個示例中,一個按鈕被新增到主視窗。當用戶單擊此按鈕時,它會在訊息框上顯示一條訊息。以下是 XAML 中的程式碼,其中聲明瞭一個帶有某些屬性的 Button 物件。

<Window x:Class="MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" Title = "MainWindow" Height = "350" Width = "604"> 
	
   <Grid> 
      <Button Name = "btn" HorizontalAlignment = "Center" Width = "60" Height = "30" Content = "Click Me" /> 
   </Grid> 
	
</Window> 

在 VB.Net 中,實現了按鈕單擊事件(行為)。此事件在訊息框上顯示訊息。

Public Class MainWindow
   Private Sub btn_Click(sender As Object, e As RoutedEventArgs) Handles btn.Click 
      MessageBox.Show("Button is Clicked") 
   End Sub 
End Class 

編譯並執行上述程式碼後,將顯示以下螢幕:

Message Box

現在單擊上面顯示“單擊我”的按鈕。它將顯示以下訊息:

Click Me

XAML - 構建塊

本章將介紹 XAML 應用程式的一些基本和重要的構建塊。它將解釋如何

  • 建立和初始化物件,
  • 使用資源、樣式和模板可以輕鬆修改物件,
  • 使用變換和動畫使物件具有互動性。

物件

XAML 是一種典型的宣告式語言,可以建立和例項化物件。它是基於 XML 描述物件的另一種方式,即需要建立哪些物件以及在程式執行之前如何初始化這些物件。物件可以是

  • 容器 (Stack Panel,Dock Panel)
  • UI 元素/控制元件 (Button,TextBox 等)
  • 資源字典

資源

資源通常是與某個物件關聯的定義,你預期會多次使用它。它能夠為控制元件或當前視窗本地儲存資料,或為整個應用程式全域性儲存資料。

樣式

XAML 框架提供了幾種策略來個性化和定製應用程式的外觀。樣式使我們能夠靈活地設定物件的某些屬性,並在多個物件中重用這些特定設定,以保持一致的外觀。

  • 在樣式中,你只能設定物件的現有屬性,例如高度、寬度、字型大小等。
  • 只能指定控制元件的預設行為。
  • 可以在一個樣式中新增多個屬性。

在第一個圖中,你可以看到相同的 height 和 width 屬性分別為所有三個按鈕設定;但在第二個圖中,你可以看到所有按鈕都相同的 height 和 width 被新增到一個樣式中,然後這個樣式與所有按鈕關聯。

Styles Styles 1

模板

模板描述了控制元件的整體外觀和視覺外觀。每個控制元件都關聯一個預設模板,它賦予該控制元件外觀。在 XAML 中,當你想自定義控制元件的視覺行為和視覺外觀時,可以輕鬆建立自己的模板。

在下面的螢幕截圖中,有兩個按鈕,一個是帶有模板的按鈕,另一個是預設按鈕。

Default Button

現在,當滑鼠懸停在按鈕上時,它還會更改顏色,如下所示。

Default Button 1

使用模板,你可以訪問比樣式中更多的控制元件部分。你可以指定控制元件的現有行為和新行為。

動畫和變換

Windows 執行時中的動畫和變換可以透過構建互動性和移動性來改進你的 XAML 應用程式。透過使用 Windows 執行時動畫庫中的動畫,你可以輕鬆地在你的 XAML 應用程式中整合互動式外觀和感覺。動畫用於

  • 增強使用者介面或使其更具吸引力。
  • 吸引使用者注意變化。

在下面的螢幕截圖中,你可以看到一個正方形 -

Square

當滑鼠懸停在這個正方形上時,它會向所有方向擴充套件,如下所示。

Square1

XAML - 控制元件

XAML 使用者介面框架提供了一個廣泛的控制元件庫,支援 Windows 的 UI 開發。其中一些具有視覺化表示,例如 Button、Textbox、TextBlock 等;而其他控制元件用作其他控制元件或內容的容器,例如影像。所有 XAML 控制元件都繼承自 **System.Windows.Controls.Control**。

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

Controls Hierarchy

以下是我們將在本章中逐一討論的控制元件列表。

序號 控制元件和描述
1 Button

響應使用者輸入的控制元件。

2 Calendar

表示一個控制元件,允許使用者使用視覺化日曆顯示來選擇日期。

3 CheckBox

使用者可以選擇或清除的控制元件。

4 ComboBox

使用者可以選擇的下拉列表。

5 ContextMenu

獲取或設定上下文選單元素,當透過使用者介面 (UI) 從此元素內部請求上下文選單時,該元素應該出現。

6 DataGrid

表示一個控制元件,以可自定義的網格顯示資料。

7 DatePicker

允許使用者選擇日期的控制元件。

8 Dialogs

應用程式還可以向用戶顯示其他視窗,以收集或顯示重要資訊。

9 GridView

一個控制元件,以可以水平滾動的行和列顯示專案集合。

10 Image

顯示影像的控制元件。

11 ListBox

一個控制元件,顯示使用者可以選擇的行內專案列表。

12 Menus

表示一個 Windows 選單控制元件,使你能夠分層組織與命令和事件處理程式關聯的元素。

13 PasswordBox

用於輸入密碼的控制元件。

14 Popup

在應用程式視窗的邊界內,在現有內容之上顯示內容。

15 ProgressBar

透過顯示進度條來指示進度的控制元件。

16 ProgressRing

透過顯示圓環來指示不確定進度的控制元件。

17 RadioButton

允許使用者從一組選項中選擇單個選項的控制元件。

18 RichEditBox

允許使用者編輯富文字文件的控制元件,其內容包括格式化文字、超連結和影像。

19 ScrollViewer

一個容器控制元件,允許使用者平移和縮放其內容。

20 SearchBox

允許使用者輸入搜尋查詢的控制元件。

21 Slider

一個控制元件,允許使用者透過沿軌道移動 Thumb 控制元件來從一系列值中進行選擇。

22 TextBlock

顯示文字的控制元件。

23 TimePicker

允許使用者設定時間值的控制元件。

24 ToggleButton

可以在兩種狀態之間切換的按鈕。

25 ToolTip

一個彈出視窗,顯示元素的資訊。

26 Window

提供最小化/最大化選項、標題欄、邊框和關閉按鈕的根視窗。

本章將討論所有這些控制元件的實現。

XAML - 佈局

控制元件的佈局對於應用程式可用性非常重要和關鍵。需要在應用程式中排列一組 GUI 元素。選擇佈局面板時需要考慮某些要點;

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

當應用程式在不同的螢幕解析度上使用時,固定的畫素排列控制元件不起作用。XAML 提供了一套豐富的內建佈局面板來以適當的方式排列 GUI 元素。一些最常用和流行的佈局面板如下所示 -

序號 面板和描述
1 StackPanel

Stack panel 是 XAML 中一個簡單而有用的佈局面板。在 Stack panel 中,子元素可以根據 orientation 屬性在一個單行中水平或垂直排列。

2 WrapPanel

在 WrapPanel 中,子元素根據 orientation 屬性按順序從左到右或從上到下排列。

3 DockPanel

DockPanel 定義一個區域,用於相對於彼此排列子元素,無論是水平還是垂直。使用 DockPanel,你可以輕鬆地將子元素停靠到頂部、底部、右側、左側和中心,使用 Dock 屬性。

4 CanvasPanel

Canvas panel 是一個基本佈局面板,其中子元素可以使用相對於 Canvas 任何側面的座標(例如左、右、上、下)顯式定位。

5 GridPanel

Grid 面板提供了一個靈活的區域,該區域由行和列組成。在 Grid 中,子元素可以以表格形式排列。

XAML - 事件處理

XAML 中事件的通用概念類似於其他流行程式語言(如 .NET 和 C++)中的事件。在 XAML 中,所有控制元件都公開了一些事件,以便可以訂閱它們以用於特定目的。

每當發生事件時,應用程式都會收到通知,並且程式可以對其做出反應,例如,關閉按鈕用於關閉對話方塊。

可以訂閱許多型別的事件,以實現基於應用程式需求的不同應用程式行為,但最常用的事件是那些與滑鼠和鍵盤相關的事件,例如:

  • Click
  • MouseDown
  • MouseEnter
  • MouseLeave
  • MouseUp
  • KeyDown
  • KeyUp

在本章中,我們將使用一些基本且最常用的事件來了解如何將特定控制元件的事件連結到程式碼隱藏,在程式碼隱藏中,將根據使用者希望在發生特定事件時執行的操作來實現行為。

讓我們來看一個簡單的按鈕單擊事件示例。下面是 Button 控制元件的 XAML 實現,該控制元件已建立並初始化了一些屬性和 Click 事件 (Click="OnClick")。

<Window x:Class = "XAMLEventHandling.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "MainWindow" Height = "350" Width = "604"> 
	
   <Grid> 
      <Button x:Name = "button1" Content = "Click" Click = "OnClick" 
         Width = "150" Height = "30" HorizontalAlignment = "Center" /> 
   </Grid>
   
</Window> 

每當單擊此按鈕時,它都會觸發 **OnClick** 事件,你可以新增任何型別的行為作為對 Click 的響應。讓我們來看一下 OnClick 事件實現,它會在單擊此按鈕時顯示一條訊息。

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

namespace XAMLEventHandling {
   /// <summary> 
      /// Interaction logic for MainWindow.xaml 
   /// </summary> 
	
   public partial class MainWindow : Window {
      public MainWindow() { 
         InitializeComponent(); 
      }
      private void OnClick(object sender, RoutedEventArgs e) { 
         MessageBox.Show("Button is clicked!"); 
      } 
   }
}

編譯並執行上述程式碼後,將產生以下輸出 -

Event Handling

單擊按鈕時,將觸發單擊 (OnClick) 事件,並將顯示以下訊息。

Event Handling Function

現在讓我們來看一個稍微複雜的示例,其中處理多個事件。

示例

以下示例包含一個帶有 ContextMenu 的文字框,用於操作文字框內的文字。

以下 XAML 程式碼建立了一個 TextBox、一個 ContextMenu 和一些具有屬性和事件(例如 Checked、Unchecked 和 Click)的 MenuItem。

<Window x:Class = "XAMLContextMenu.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "MainWindow" Height = "350" Width = "604"> 
	
   <Grid> 
      <TextBox Name = "textBox1" TextWrapping = "Wrap" Margin = "10" Grid.Row = "7"> 
         Hi, this is XAML tutorial. 
         <TextBox.ContextMenu>
         
            <ContextMenu>
               <MenuItem Header = "_Bold" IsCheckable = "True" 
                  Checked = "Bold_Checked" Unchecked = "Bold_Unchecked" /> 
               <MenuItem Header = "_Italic" IsCheckable = "True" 
                  Checked = "Italic_Checked" Unchecked = "Italic_Unchecked" /> 
               <Separator /> 
               <MenuItem Header = "Increase Font Size" Click = "IncreaseFont_Click" />
               <MenuItem Header = "_Decrease Font Size" Click = "DecreaseFont_Click" /> 
            </ContextMenu> 
				
         </TextBox.ContextMenu>
      </TextBox>
   </Grid> 
	
</Window> 

以下是 C# 中不同事件的實現,每當選中、取消選中或單擊選單項時,這些事件都會觸發。

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Data;  

namespace XAMLContextMenu { 
   /// <summary> 
      /// Interaction logic for MainWindow.xaml 
   /// </summary>
	
   public partial class MainWindow : Window {
      public MainWindow() { 
         InitializeComponent(); 
      }
      private void Bold_Checked(object sender, RoutedEventArgs e) { 
         textBox1.FontWeight = FontWeights.Bold; 
      }
      private void Bold_Unchecked(object sender, RoutedEventArgs e) { 
         textBox1.FontWeight = FontWeights.Normal; 
      }
      private void Italic_Checked(object sender, RoutedEventArgs e) { 
         textBox1.FontStyle = FontStyles.Italic; 
      }
      private void Italic_Unchecked(object sender, RoutedEventArgs e) { 
         textBox1.FontStyle = FontStyles.Normal; 
      }
      private void IncreaseFont_Click(object sender, RoutedEventArgs e) { 
         if (textBox1.FontSize < 18) { 
            textBox1.FontSize += 2; 
         } 
      }
      private void DecreaseFont_Click(object sender, RoutedEventArgs e) { 
         if (textBox1.FontSize > 10) { 
            textBox1.FontSize -= 2; 
         } 
      }
   }
}

編譯並執行上述程式碼後,將產生以下輸出 -

ContextMenu Output

我們建議你執行上述示例程式碼並嘗試其他一些事件。

事件

序號 控制元件和描述
1

Checked

當 ToggleButton 被選中時觸發。(繼承自 ToggleButton)

2

Click

當單擊按鈕控制元件時發生。(繼承自 ButtonBase)

3

ContextMenuClosing

在元素上的任何上下文選單關閉之前發生。(繼承自 FrameworkElement。)

4

ContextMenuOpening

當元素上的任何上下文選單開啟時發生。(繼承自 FrameworkElement。)

5

DataContextChanged

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

6

DragEnter

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

7

DragLeave

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

8

DragOver

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

9

DragStarting

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

10

DropCompleted

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

11

DropDownClosed

當 ComboBox 的下拉部分關閉時發生。

12

DropDownOpened

當 ComboBox 的下拉部分開啟時發生。

13

GotFocus

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

14

Holding

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

15

中間狀態

當ToggleButton的狀態切換到不確定狀態時觸發。(繼承自ToggleButton)

16

IsEnabledChanged

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

17

KeyDown

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

18

KeyUp

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

19

LostFocus

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

20

ManipulationCompleted

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

21

ManipulationDelta

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

22

ManipulationInertiaStarting

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

23

ManipulationStarted

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

24

ManipulationStarting

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

25

SelectionChanged

文字選擇更改時發生。

26

SizeChanged

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

27

Unchecked

當ToggleButton取消選中時發生。(繼承自ToggleButton)

28

ValueChanged

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

XAML - 資料繫結

資料繫結是XAML應用程式中的一種機制,它為使用部分類的Windows執行時應用程式提供了一種簡單易用的方法來顯示和互動資料。在此機制中,資料的管理與資料顯示方式完全分離。

資料繫結允許資料在UI元素和使用者介面上的資料物件之間流動。當建立繫結並且資料或業務模型發生更改時,它將自動將更新反映到UI元素,反之亦然。也可以繫結到頁面上的另一個元素,而不是標準資料來源。資料繫結可以分為兩種型別:

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

單向資料繫結

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

讓我們來看一個簡單的單向資料繫結示例。以下XAML程式碼建立了四個文字塊,並具有一些屬性。

<Window x:Class = "DataBindingOneWay.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "MainWindow" Height = "350" Width = "604"> 
	
   <Grid>
      <StackPanel Name = "Display">
         <StackPanel Orientation = "Horizontal" Margin = "50, 50, 0, 0"> 
            <TextBlock Text = "Name: " Margin = "10" Width = "100" /> 
            <TextBlock Margin = "10" Width = "100" Text = "{Binding Name}" />
         </StackPanel> 
		
         <StackPanel Orientation = "Horizontal" Margin = "50,0,50,0"> 
            <TextBlock Text = "Title: " Margin = "10" Width = "100" /> 
            <TextBlock Margin = "10" Width = "100" Text = "{Binding Title}" /> 
         </StackPanel>
      </StackPanel>
   </Grid> 
	
</Window> 

兩個文字塊的Text屬性靜態設定為“Name”和“Title”,而其他兩個文字塊的Text屬性繫結到“Name”和“Title”,它們是Employee類的類變數,如下所示。

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
 
namespace DataBindingOneWay {
   public class Employee {
      public string Name { get; set; } 
      public string Title { get; set; }  
		
      public static Employee GetEmployee() {
         var emp = new Employee() { 
            Name = "Ali Ahmed", Title = "Developer" 
         }; 
         return emp; 
      }
   }
}

在這個類中,我們只有兩個變數,**Name**和**Title**,以及一個靜態方法,其中初始化Employee物件並將返回該Employee物件。因此,我們繫結到一個屬性Name和Title,但我們沒有選擇該屬性屬於哪個物件。最簡單的方法是將一個物件分配給DataContext,我們在下面的C#程式碼中繫結其屬性:

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

namespace DataBindingOneWay { 
   /// <summary> 
      /// Interaction logic for MainWindow.xaml 
   /// </summary> 
	
   public partial class MainWindow : Window {
      public MainWindow() { 
         InitializeComponent(); 
         DataContext = Employee.GetEmployee(); 
      } 
   }
}

讓我們執行此應用程式,您可以在我們的MainWindow中立即看到我們已成功繫結到該Employee物件的Name和Title。

One-Way Data Binding

雙向資料繫結

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

示例

讓我們來看下面的例子,其中建立了一個帶三個組合框項的組合框和一個文字框,並具有一些屬性。在這個例子中,我們沒有任何標準的資料來源,但是UI元素繫結到其他UI元素。

<Window x:Class = "XAMLTestBinding.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "MainWindow" Height = "350" Width = "604"> 
	
   <StackPanel>
      <ComboBox Name = "comboBox"  Margin = "50" Width = "100"> 
         <ComboBoxItem Content = "Green" /> 
         <ComboBoxItem Content = "Yellow" IsSelected = "True" /> 
         <ComboBoxItem Content = "Orange" /> 
      </ComboBox>
		
      <TextBox  Name = "textBox" Margin = "50" 
         Width = "100" Height = "23" VerticalAlignment = "Top" 
         Text  = "{Binding ElementName = comboBox, Path = SelectedItem.Content, 
         Mode = TwoWay, UpdateSourceTrigger = PropertyChanged}" 
         Background = "{Binding ElementName = comboBox, Path = SelectedItem.Content}"> 
      </TextBox>
   </StackPanel> 
	
</Window> 

編譯並執行上述程式碼後,將生成以下輸出。當用戶從組合框中選擇一個專案時,文字框文字和背景顏色將相應更新。

Two-Way Binding

同樣,當用戶在文字框中鍵入有效的顏色名稱時,組合框和文字框的背景顏色也將更新。

Two-Way Binding 2

XAML - 標記擴充套件

在XAML應用程式中,標記擴充套件是一種獲取既不是特定XAML物件也不是原始型別的值的方法/技術。標記擴充套件可以透過開啟和關閉大括號來定義,在大括號內定義標記擴充套件的範圍。

資料繫結和靜態資源是標記擴充套件。**System.xaml**中有一些預定義的XAML標記擴充套件可以使用。

讓我們來看一個簡單的例子,其中使用了**StaticResources**標記擴充套件,它是一個預定義的XAML標記擴充套件。

以下XAML程式碼建立了兩個具有某些屬性的文字塊,它們的foregroundColor在**Window.Resources**中定義。

<Window x:Class = "XAMLStaticResourcesMarkupExtension.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "MainWindow" Height = "350" Width = "525"> 
	
   <Window.Resources> 
      <SolidColorBrush Color = "Blue" x:Key = "myBrush"></SolidColorBrush> 
   </Window.Resources> 
	
   <Grid> 
      <StackPanel Orientation = "Vertical"> 
         <TextBlock Foreground = "{StaticResource myBrush}" Text = "First Name" 
            Width = "100" Margin = "10" /> 
         <TextBlock Foreground = "{StaticResource myBrush}" Text = "Last Name" 
            Width = "100" Margin = "10" /> 
      </StackPanel> 
   </Grid> 
	
</Window> 

在**Window.Resources**中,您可以看到使用了**x:Key**,它唯一標識在XAML定義的字典中建立和引用的元素,以在資源字典中標識資源。

編譯並執行上述程式碼後,將生成以下MainWindow。您可以看到兩個帶有藍色前景色的文字塊。

Markup Extensions

在XAML中,也可以透過繼承MarkupExtension類並覆蓋ProvideValue方法(它是MarkupExtension類中的抽象方法)來定義自定義標記擴充套件。

讓我們來看一個自定義標記擴充套件的簡單示例。

<Window x:Class = "XAMLMarkupExtension.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:my = "clr-namespace:XAMLMarkupExtension" 
   Title = "MainWindow" Height = "350" Width = "525"> 
	
   <Grid> 
      <Button Content = "{my:MyMarkupExtension FirstStr = Markup, SecondStr = Extension}" 
         Width = "200" Height = "20" /> 
   </Grid> 
	
</Window>

在上面的XAML程式碼中,建立了一個具有某些屬性的按鈕,並且對於content值,使用了自定義標記擴充套件**(my:MyMarkupExtension)**,其中有兩個值“Markup”和“Extension”,分別分配給FirstStr和SecondStr。

實際上,MyMarkupExtension是一個從MarkupExtension派生的類,如下面的C#實現所示。此類包含兩個字串變數FirstStr和SecondStr,它們被連線起來,並將該字串從ProvideValue方法返回到按鈕的Content。

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks;
 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Data; 
using System.Windows.Documents; 
using System.Windows.Input; 
using System.Windows.Markup; 
using System.Windows.Media; 
using System.Windows.Media.Imaging; 
using System.Windows.Navigation; 
using System.Windows.Shapes;  

namespace XAMLMarkupExtension { 
   /// <summary> 
      /// Interaction logic for MainWindow.xaml 
   /// </summary> 
	
   public partial class MainWindow : Window { 
      public MainWindow() { 
         InitializeComponent(); 
      } 
   }
   public class MyMarkupExtension : MarkupExtension { 
      public MyMarkupExtension() { } 
      public String FirstStr { get; set; } 
      public String SecondStr { get; set; }  
		
      public override object ProvideValue(IServiceProvider serviceProvider) { 
        return FirstStr + " " + SecondStr; 
      } 
   }
}

讓我們執行此應用程式,您可以在我們的MainWindow中立即看到“markup extension”已成功用作按鈕的內容。

MarkupExtension 1

XAML - 依賴屬性

依賴屬性是一種特定型別的屬性,其值由一個敏銳的屬性系統跟蹤,該系統也是Windows執行時應用程式的一部分。定義依賴屬性的類必須繼承自DependencyObject類。

在XAML中使用的許多UI控制元件類都派生自DependencyObject類並支援依賴屬性。以下XAML程式碼建立了一個具有某些屬性的按鈕。

<Window x:Class = "XAMLDependencyProperty.MainWindow"
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:local = "clr-namespace:XAMLDependencyProperty"
   Title = "MainWindow" Height = "350" Width = "604">
	
   <Grid>
      <Button Height = "40" Width = "175" Margin = "10" Content = "Dependency Property">
         <Button.Style>
            <Style TargetType = "{x:Type Button}">
               <Style.Triggers> 
                  <Trigger Property = "IsMouseOver" Value = "True">
                     <Setter Property = "Foreground" Value = "Red" />
                  </Trigger>
               </Style.Triggers>
            </Style>
         </Button.Style>
      </Button>
   </Grid>
   
</Window>

XAML中的x:Type標記擴充套件具有與C#中的typeof()類似的功能。當指定採用物件型別的屬性時使用它,例如<Style TargetType = "{x:Type Button}">

編譯並執行上述程式碼後,將生成以下MainWindow。當滑鼠懸停在按鈕上時,它將更改按鈕的前景色。當滑鼠離開按鈕時,它將恢復到原來的顏色。

Dependency Property

依賴屬性與其他CLR屬性的主要區別在於:

  • CLR屬性可以使用**getter**和**setter**直接從類的私有成員讀取/寫入。對於依賴屬性,它不會儲存在本地物件中。

  • 依賴屬性儲存在DependencyObject類提供的鍵/值對字典中。

  • 它還節省了大量記憶體,因為它只在屬性更改時才儲存。

  • 它也可以在XAML中繫結。

在.NET框架中,也可以定義自定義依賴屬性。以下是C#中定義自定義依賴屬性的步驟。

  • 使用系統呼叫register宣告和註冊您的依賴屬性。

  • 為屬性提供setter和getter。

  • 定義一個靜態處理程式來處理全域性發生的任何更改。

  • 定義一個例項處理程式來處理發生在此特定例項的任何更改。

以下是C#中依賴屬性的程式碼,該屬性用於設定使用者控制元件的SetText屬性。

using System; 
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApplication3 {
   /// <summary> 
      /// Interaction logic for UserControl1.xaml 
   /// </summary> 
	
   public partial class UserControl1 : UserControl {
      public UserControl1() {
         InitializeComponent();
      }
      public static readonly DependencyProperty
         SetTextProperty = DependencyProperty.Register("SetText", typeof(string), 
         typeof(UserControl1), new PropertyMetadata("", 
         new PropertyChangedCallback(OnSetTextChanged)));
      public string SetText {
         get {return(string) GetValue(SetTextProperty); }
         set {SetValue(SetTextProperty, value);}
      }
      private static void OnSetTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
         UserControl1 UserControl1Control = d as UserControl1;
         UserControl1Control.OnSetTextChanged(e);
      }
      private void OnSetTextChanged(DependencyPropertyChangedEventArgs e) {
         tbTest.Text = e.NewValue.ToString();
      }
   }
}

這是XAML檔案,其中TextBlock被定義為使用者控制元件,並且Text屬性將由SetText依賴屬性分配給它。

以下XAML程式碼建立了一個使用者控制元件,並初始化其SetText依賴屬性和其他一些屬性。

<Window x:Class = "WpfApplication3.MainWindow"
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:views = "clr-namespace:WpfApplication3" 
   Title = "MainWindow" Height = "350" Width = "604">
	
   <Grid>
      <views:UserControl1 SetText = "Hellow World" />
   </Grid>
	
</Window>

讓我們執行此應用程式,您可以在我們的MainWindow中立即看到使用者控制元件的依賴屬性已成功用作文字。

Hello World Example

XAML - 資源

資源通常是與某些物件相關的定義,您只希望多次使用它。它能夠為控制元件或當前視窗本地儲存資料,或者為整個應用程式全域性儲存資料。

將物件定義為資源允許我們從另一個位置訪問它。因此,它允許可重用性。資源在資源字典中定義,任何物件都可以有效地定義為資源,使其成為可共享的資產。一個唯一的鍵被指定給XAML資源,並且可以使用該鍵透過使用StaticResource標記擴充套件來引用它。

讓我們再次來看一個簡單的例子,其中建立了兩個具有某些屬性的文字塊,它們的foregroundColor在**Window.Resources**中定義。

<Window x:Class = "XAMLResources.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "MainWindow" Height = "350" Width = "604"> 
	
   <Window.Resources> 
      <SolidColorBrush Color = "Blue" x:Key = "myBrush"></SolidColorBrush> 
   </Window.Resources>  
	
   <StackPanel Orientation = "Vertical"> 
      <TextBlock Foreground = "{StaticResource myBrush}" 
         Text = "First Name" Width = "100" Margin = "10" /> 
      <TextBlock Foreground = "{StaticResource myBrush}" 
         Text = "Last Name" Width = "100" Margin = "10" /> 
   </StackPanel> 
	
</Window> 

編譯並執行上述程式碼後,將生成以下MainWindow。您可以看到兩個帶有藍色前景色的文字塊。資源的優點是,如果有多個文字塊並且您想更改它們的背景顏色,則只需要在資源字典中更改它。

Resources

資源範圍

資源在資源字典中定義,但是可以在許多地方定義資源字典。在上面的示例中,資源字典是在視窗/頁面級別定義的。資源在哪個字典中定義會立即限制該資源的範圍。因此,範圍(即可以使用資源的位置)取決於您定義資源的位置。

  • 在網格的資源字典中定義資源,並且只有該網格及其子元素可以訪問它。

  • 在視窗/頁面上定義它,並且該視窗/頁面上的所有元素都可以訪問它。

  • App根可以在App.xaml資源字典中找到。它是我們應用程式的根,因此此處定義的資源的作用域為整個應用程式。

就資源的範圍而言,最常見的是應用程式級別、頁面級別和特定元素級別,如Grid、StackPanel等。

Resource Scope

資源字典

XAML應用程式中的資源字典意味著單獨檔案中的資源字典。這幾乎在所有XAML應用程式中都是遵循的。在單獨的檔案中定義資源具有以下優點:

  • 在資源字典和UI相關程式碼之間分離。

  • 在單獨的檔案(例如App.xaml)中定義所有資源將使它們在整個應用程式中可用。

那麼,我們如何在單獨的檔案中的資源字典中定義資源呢?這很容易,只需透過以下步驟透過Visual Studio新增一個新的資源字典:

  • 在您的解決方案中,新增一個新資料夾並將其命名為**ResourceDictionaries**。

  • 右鍵單擊此資料夾,然後從“新增”子選單項中選擇“資源字典”,並將其命名為**DictionaryWithBrush.xaml**

讓我們來看一下同一個應用程式;資源字典現在在應用程式級別定義。

這是MainWindow.xaml的XAML程式碼。

<Window x:Class = "XAMLResources.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "MainWindow" Height = "350" Width = "604"> 
	
   <StackPanel Orientation = "Vertical"> 
      <TextBlock Foreground = "{StaticResource myBrush}" Text = "First Name" 
         Width = "100" Margin = "10" /> 
      <TextBlock Foreground = "{StaticResource myBrush}" Text = "Last Name" 
         Width = "100" Margin = "10"/> 
   </StackPanel> 
	
</Window> 

這是DictionaryWithBrush.xaml中的實現:

<ResourceDictionary 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"> 
	
   <SolidColorBrush Color = "Blue" x:Key = "myBrush"></SolidColorBrush> 
	
</ResourceDictionary> 

這是app.xaml中的實現:

<Application x:Class = "XAMLResources.App" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   StartupUri = "MainWindow.xaml"> 
	
   <Application.Resources> 
      <ResourceDictionary Source = " XAMLResources\ResourceDictionaries\DictionaryWithBrush.xaml" /> 
   </Application.Resources> 
	
</Application>

編譯並執行上述程式碼後,將生成以下輸出:

Resources

我們建議您執行上述程式碼並嘗試更多資源,例如背景顏色等。

XAML - 模板

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

在XAML中,當您想要自定義控制元件的視覺行為和視覺外觀時,可以輕鬆建立您自己的模板。邏輯和模板之間的連線可以透過資料繫結來實現。

樣式和模板的主要區別在於:

  • 樣式只能更改控制元件的預設屬性外觀。

  • 使用模板,您可以訪問比樣式中更多控制元件的部分。您還可以指定控制元件的現有和新行為。

最常用的模板有兩種。

  • 控制元件模板
  • 資料模板

控制元件模板

控制元件模板定義或指定控制元件的視覺外觀和結構。所有UI元素都具有一定的外觀和行為,例如,按鈕具有外觀和行為。單擊事件或滑鼠懸停事件是響應單擊和懸停而觸發的行為,並且還有一個可以由控制元件模板更改的按鈕預設外觀。

讓我們再次看看一個簡單的示例,其中建立了兩個具有某些屬性的按鈕。一個是帶模板的,另一個是帶預設按鈕的。

<Window x:Class = "TemplateDemo.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "MainWindow" Height = "350" Width = "604"> 
	
   <Window.Resources>
      <ControlTemplate x:Key = "ButtonTemplate" TargetType = "Button">
         <Grid>
            <Ellipse x:Name = "ButtonEllipse" Height = "100" Width = "150" >
               <Ellipse.Fill> 
                  <LinearGradientBrush StartPoint = "0,0.2" EndPoint = "0.2,1.4"> 
                     <GradientStop Offset = "0" Color = "Red"/>
                     <GradientStop Offset = "1" Color = "Orange"/>
                  </LinearGradientBrush> 
               </Ellipse.Fill>
            </Ellipse>
            <ContentPresenter Content = "{TemplateBinding Content}"
               HorizontalAlignment = "Center" VerticalAlignment = "Center" />
         </Grid>
         <ControlTemplate.Triggers> 
            <Trigger Property = "IsMouseOver" Value = "True">
               <Setter TargetName = "ButtonEllipse" Property = "Fill" >
                  <Setter.Value> 
                     <LinearGradientBrush StartPoint = "0,0.2" EndPoint="0.2,1.4"> 
                        <GradientStop Offset = "0" Color = "YellowGreen"/>
                        <GradientStop Offset = "1" Color = "Gold"/>
                     </LinearGradientBrush> 
                  </Setter.Value> 
               </Setter>
            </Trigger> 
				
            <Trigger Property = "IsPressed" Value = "True"> 
               <Setter Property = "RenderTransform"> 
                  <Setter.Value> 
                     <ScaleTransform ScaleX = "0.8" ScaleY = "0.8" CenterX = "0" CenterY = "0" /> 
                  </Setter.Value> 
               </Setter> 
					
               <Setter Property = "RenderTransformOrigin" Value = "0.5,0.5" /> 
            </Trigger>
         </ControlTemplate.Triggers>
      </ControlTemplate> 
   </Window.Resources>
	
   <StackPanel> 
      <Button Content = "Round Button!" Template = "{StaticResource ButtonTemplate}" 
         Width = "150" Margin = "50" />
      <Button Content = "Default Button!" Height = "40" Width = "150" Margin = "5" /> 
   </StackPanel> 
	
</Window>

編譯並執行上述程式碼後,將生成以下MainWindow:

Control Template

當您將滑鼠懸停在帶有自定義模板的按鈕上時,它也會更改顏色,如下所示:

Control Template1

資料模板

資料模板定義和指定資料集合的外觀和結構。它提供了靈活地格式化和定義任何UI元素上資料的呈現方式。它主要用於與資料相關的專案控制元件,例如ComboBox、ListBox等。

讓我們看看資料模板的一個簡單示例。以下XAML程式碼建立了一個帶有資料模板和文字塊的組合框。

<Window x:Class = "XAMLDataTemplate.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "MainWindow" Height = "350" Width = "604"> 
	
   <Grid VerticalAlignment = "Top">
      <ComboBox Name = "Presidents" ItemsSource = "{Binding}" Height = "30" Width = "400"> 
         <ComboBox.ItemTemplate> 
            <DataTemplate>
               <StackPanel Orientation = "Horizontal" Margin = "2">
                  <TextBlock Text = "Name: " Width = "95" Background = "Aqua" Margin = "2" /> 
                  <TextBlock Text = "{Binding Name}" Width = "95" Background = "AliceBlue" Margin = "2" /> 
                  <TextBlock Text = "Title: " Width = "95" Background = "Aqua" Margin = "10,2,0,2" />
                  <TextBlock Text = "{Binding Title}" Width = "95" Background = "AliceBlue" Margin = "2" /> 
               </StackPanel>
            </DataTemplate>
         </ComboBox.ItemTemplate> 
      </ComboBox> 
   </Grid>
   
</Window>

這是C#中的實現,其中employee物件被賦值給DataContext:

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

namespace XAMLDataTemplate { 
   /// <summary> 
      /// Interaction logic for MainWindow.xaml 
   /// </summary> 
	
   public partial class MainWindow : Window {
      public MainWindow() {
         InitializeComponent(); 
         DataContext = Employee.GetEmployees(); 
      }
   }
}

這是C#中Employee類的實現:

using System; 
using System.Collections.Generic; 
using System.Collections.ObjectModel; 
using System.ComponentModel; 
using System.Linq; 
using System.Runtime.CompilerServices; 
using System.Text; 
using System.Threading.Tasks;

namespace XAMLDataTemplate { 
   public class Employee : INotifyPropertyChanged {
      private string name; public string Name {
         get { return name; } 
         set { name = value; RaiseProperChanged(); } 
      }
      private string title; public string Title { 
         get { return title; } 
         set { title = value; RaiseProperChanged(); } 
      }
      public static Employee GetEmployee() {
         var emp = new Employee() { 
            Name = "Waqas", Title = "Software Engineer" };
         return emp; 
      }
      public event PropertyChangedEventHandler PropertyChanged;
      private void RaiseProperChanged( [CallerMemberName] string caller = ""){
         if (PropertyChanged != null) { 
            PropertyChanged(this, new PropertyChangedEventArgs(caller)); 
         } 
      }
      public static ObservableCollection<Employee> GetEmployees() {
         var employees = new ObservableCollection<Employee>();
         employees.Add(new Employee() { Name = "Ali", Title = "Developer" }); 
         employees.Add(new Employee() { Name = "Ahmed", Title = "Programmer" });
         employees.Add(new Employee() { Name = "Amjad", Title = "Desiner" });
         employees.Add(new Employee() { Name = "Waqas", Title = "Programmer" }); 
         employees.Add(new Employee() { Name = "Bilal", Title = "Engineer" });
         employees.Add(new Employee() { Name = "Waqar", Title = "Manager" }); 
         return employees; 
      }
   }
}

編譯並執行上述程式碼後,將生成以下輸出。它包含一個組合框,當您單擊組合框時,您會看到在Employee類中建立的資料集合作為組合框專案列出。

Data Template

我們建議您執行上述程式碼並進行試驗。

XAML - 樣式

XAML 框架提供了幾種策略來個性化和定製應用程式的外觀。樣式使我們能夠靈活地設定物件的某些屬性,並在多個物件中重用這些特定設定,以保持一致的外觀。

  • 在樣式中,您只能設定物件的現有屬性,例如高度、寬度和字型大小。

  • 只能指定控制元件的預設行為。

  • 可以在單個樣式中新增多個屬性。

樣式用於為一組控制元件提供統一的外觀。隱式樣式用於將外觀應用於給定型別的全部控制元件並簡化應用程式。

假設我們有三個按鈕,並且它們的外觀必須相同:相同的寬度和高度、相同的字型大小和相同的文字顏色。我們可以在按鈕元素本身設定所有這些屬性,對於所有按鈕來說,這仍然是可以的,如下面的圖所示。

XAML Styles

但在實際應用程式中,通常會有更多需要看起來完全相同的按鈕。當然,不僅僅是按鈕,您通常希望文字塊、文字框和組合框等在您的應用程式中看起來相同。當然必須有更好的方法來實現這一點——這就是所謂的樣式。您可以將樣式視為一種方便的方法,可以將一組屬性值應用於多個元素,如下面的圖所示。

Styling

讓我們看看包含三個在XAML中建立並具有某些屬性的按鈕的示例。

<Window x:Class = "XAMLStyle.MainWindow" 
   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:local = "clr-namespace:XAMLStyle" mc:Ignorable = "d" 
   Title = "MainWindow" Height = "350" Width = "604"> 
	
   <StackPanel> 
      <Button Content = "Button1" Height = "30" Width = "80" Foreground = "Blue" 
         FontSize = "12" Margin = "10"/>
      
      <Button Content = "Button2" Height = "30" Width = "80" Foreground = "Blue" 
         FontSize = "12" Margin = "10"/>
      
      <Button Content = "Button3" Height = "30" Width = "80" Foreground = "Blue" 
         FontSize = "12" Margin = "10"/> 
   </StackPanel> 
	
</Window>

檢視上面的程式碼,您將看到對於所有按鈕,高度、寬度、前景色、字型大小和邊距屬性都保持不變。編譯並執行上述程式碼後,將顯示以下輸出:

Button

現在讓我們看看相同的示例,但這次我們將使用樣式

<Window x:Class = "XAMLStyle.MainWindow" 
   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:local = "clr-namespace:XAMLStyle" mc:Ignorable = "d" 
   Title = "MainWindow" Height = "350" Width = "604">
	
   <Window.Resources> 
      <Style x:Key = "myButtonStyle" TargetType = "Button">
         <Setter Property = "Height" Value = "30"/> 
         <Setter Property = "Width" Value = "80"/> 
         <Setter Property = "Foreground" Value = "Blue"/> 
         <Setter Property = "FontSize" Value = "12"/> 
         <Setter Property = "Margin" Value = "10"/> 
      </Style>
   </Window.Resources> 
	
   <StackPanel> 
      <Button Content = "Button1" Style = "{StaticResource myButtonStyle}"/>
      <Button Content = "Button2" Style = "{StaticResource myButtonStyle}"/>
      <Button Content = "Button3" Style = "{StaticResource myButtonStyle}"/>
   </StackPanel>
	
</Window>

樣式在資源字典中定義,每個樣式都有一個唯一的鍵識別符號和一個目標型別。在<style>內部,您可以看到為將包含在樣式中的每個屬性定義了多個setter標籤。

在上面的示例中,每個按鈕的所有公共屬性現在都在樣式中定義,然後透過使用StaticResource標記擴充套件設定style屬性,將樣式分配給每個按鈕。

編譯並執行上述程式碼後,將生成以下視窗,該視窗與輸出相同。

Button

這樣做的優勢是顯而易見的。我們可以在其作用域內的任何位置重複使用該樣式,如果需要更改它,我們只需在樣式定義中更改一次,而無需在每個元素上更改。

樣式的定義級別會立即限制該樣式的作用域。因此,作用域(即可以使用樣式的位置)取決於您定義樣式的位置。樣式可以在以下級別定義:

序號 級別和說明
1 控制元件級別

在控制元件級別定義的樣式只能應用於該特定控制元件。

2 佈局級別

在任何佈局級別定義的樣式只能被該佈局及其子元素訪問。

3 視窗級別

在視窗級別定義的樣式可以被該視窗上的所有元素訪問。

4 應用程式級別

在應用程式級別定義的樣式可以在整個應用程式中訪問。

XAML - 觸發器

基本上,觸發器使您可以根據屬性的值來更改屬性值或執行操作。因此,它基本上允許您動態更改控制元件的外觀和/或行為,而無需建立新的控制元件。

觸發器用於在滿足某些條件時更改任何給定屬性的值。觸發器通常在樣式中或應用於特定控制元件的文件根中定義。觸發器有三種類型:

  • 屬性觸發器
  • 資料觸發器
  • 事件觸發器

屬性觸發器

在屬性觸發器中,當一個屬性發生更改時,它將導致另一個屬性發生立即或動畫更改。例如,如果您想在滑鼠懸停在按鈕上時更改按鈕外觀,可以使用屬性觸發器。

示例

以下示例演示如何在滑鼠進入按鈕區域時更改按鈕的前景色。

<Window x:Class = "XAMLPropertyTriggers.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "MainWindow" Height = "350" Width = "604">
	
   <Window.Resources>
      <Style x:Key = "TriggerStyle" TargetType = "Button">
         <Setter Property = "Foreground" Value = "Blue" />
         <Style.Triggers>
            <Trigger Property = "IsMouseOver" Value = "True">
               <Setter Property = "Foreground" Value = "Green" />
            </Trigger> 
         </Style.Triggers>
      </Style>
   </Window.Resources>
	
   <Grid>
      <Button Width = "100" Height = "70" Style = "{StaticResource TriggerStyle}" 
         Content = "Trigger"/>
   </Grid>
	
</Window>

編譯並執行上述程式碼後,將產生以下輸出 -

Trigger

當滑鼠進入按鈕區域時,前景色將更改為綠色。

Trigger Color

資料觸發器

當繫結資料滿足某些條件時,資料觸發器將執行某些操作。讓我們看看以下XAML程式碼,其中建立了一個複選框和一個文字塊以及一些屬性。選中複選框時,它會將前景色更改為紅色。

<Window x:Class = "XAMLDataTrigger.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "Data Trigger" Height = "350" Width = "604">
	
   <StackPanel HorizontalAlignment = "Center">
      <CheckBox x:Name = "redColorCheckBox" Content = "Set red as foreground color" Margin = "20"/>
		
      <TextBlock Name = "txtblock" VerticalAlignment = "Center" 
         Text = "Event Trigger" FontSize = "24" Margin = "20">
         <TextBlock.Style>
            <Style>
               <Style.Triggers>
                  <DataTrigger Binding = "{Binding ElementName = redColorCheckBox, Path = IsChecked}" 
                     Value = "true">
                     <Setter Property = "TextBlock.Foreground" Value = "Red"/>
                     <Setter Property = "TextBlock.Cursor" Value = "Hand" />
                  </DataTrigger>
               </Style.Triggers>
            </Style>
         </TextBlock.Style>
      </TextBlock>
   </StackPanel>
	
</Window>		

編譯並執行上述程式碼後,將產生以下輸出 -

Event Trigger

選中複選框時,文字塊的前景色將更改為紅色。

Trigger Foreground Color

事件觸發器

觸發事件將在觸發特定事件時執行某些操作。它通常用於完成某些動畫,例如DoubleAnimation、ColorAnimation等。以下程式碼塊建立了一個簡單的按鈕。觸發單擊事件時,它將擴充套件按鈕的寬度和高度。

<Window x:Class = "XAMLEventTrigger.MainWindow"
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "MainWindow" Height = "350" Width = "604">
	
   <Grid>
      <Button Content = "Click Me" Width = "60" Height = "30">
         <Button.Triggers>
            <EventTrigger RoutedEvent = "Button.Click">
               <EventTrigger.Actions>
                  <BeginStoryboard>
                     <Storyboard>
                     
                        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty = "Width" Duration = "0:0:4">
                           <LinearDoubleKeyFrame Value = "60" KeyTime = "0:0:0"/>
                           <LinearDoubleKeyFrame Value = "120" KeyTime = "0:0:1"/>
                           <LinearDoubleKeyFrame Value = "200" KeyTime = "0:0:2"/>
                           <LinearDoubleKeyFrame Value = "300" KeyTime = "0:0:3"/>
                        </DoubleAnimationUsingKeyFrames>
							
                        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty = "Height" Duration = "0:0:4">
                           <LinearDoubleKeyFrame Value = "30" KeyTime = "0:0:0"/>
                           <LinearDoubleKeyFrame Value = "40" KeyTime = "0:0:1"/>
                           <LinearDoubleKeyFrame Value = "80" KeyTime = "0:0:2"/>
                           <LinearDoubleKeyFrame Value = "150" KeyTime = "0:0:3"/>
                        </DoubleAnimationUsingKeyFrames>
							
                     </Storyboard>
                  </BeginStoryboard>
               </EventTrigger.Actions>
            </EventTrigger>
         </Button.Triggers>
      </Button>
   </Grid>
</Window>

編譯並執行上述程式碼後,將產生以下輸出 -

Events Triggers

現在,單擊按鈕,您將觀察到它將開始在兩個維度上擴充套件。

Events Triggers1

XAML - 除錯

如果您熟悉任何過程語言(如C#、C/C++等)中的除錯以及`break`的使用,並且期望在XAML中進行相同型別的除錯,那麼您會驚訝地發現,目前還無法像除錯其他過程語言程式碼那樣除錯XAML程式碼。除錯XAML應用程式意味著嘗試查詢錯誤;

  • 在資料繫結中,您的資料沒有顯示在螢幕上,您不知道原因

  • 或者問題與複雜的佈局有關。

  • 或者對齊問題或邊距顏色、疊加層等問題,以及一些擴充套件模板,如ListBox和組合框。

XAML中的除錯通常用於檢查繫結是否有效,如果無效,則檢查問題所在。不幸的是,除了Silverlight之外,無法在XAML繫結中設定斷點,但我們可以使用輸出視窗檢查資料繫結錯誤。讓我們看看以下XAML程式碼以查詢資料繫結中的錯誤。

<Window x:Class = "DataBindingOneWay.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "MainWindow" Height = "350" Width = "604">
	
   <Grid>
      <StackPanel Name = "Display">
         <StackPanel Orientation = "Horizontal" Margin = "50, 50, 0, 0">
            <TextBlock Text = "Name: " Margin = "10" Width = "100"/>
            <TextBlock Margin = "10" Width = "100" Text = "{Binding FirstName}"/>
         </StackPanel>
			
         <StackPanel Orientation = "Horizontal" Margin = "50,0,50,0">
            <TextBlock Text = "Title: " Margin = "10" Width = "100"/>
            <TextBlock Margin = "10" Width="100" Text = "{Binding Title}" />
         </StackPanel>
      </StackPanel>
   </Grid>
	
</Window>

兩個文字塊的Text屬性靜態設定為“Name”和“Title”,而其他兩個文字塊的Text屬性繫結到“FirstName”和“Title”。但是,類變數在Employee類中故意取為Name和Title,這是不正確的變數名。現在讓我們嘗試瞭解在未顯示所需輸出時可以在哪裡找到這種型別的錯誤。

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks;

namespace DataBindingOneWay {
   public class Employee {
      public string Name { get; set; } 
      public string Title { get; set; }
		
      public static Employee GetEmployee() {
         var emp = new Employee() {
            Name = "Ali Ahmed", 
            Title = "Developer"
         };
         return emp; 
      }
   }
}

這是C#程式碼中MainWindow類的實現:

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

namespace DataBindingOneWay {
   /// <summary> 
      /// Interaction logic for MainWindow.xaml 
   /// </summary> 
	
   public partial class MainWindow : Window {
      public MainWindow() {
         InitializeComponent(); 
         DataContext = Employee.GetEmployee(); 
      }
   }
}

讓我們執行此應用程式,您可以在我們的MainWindow中立即看到我們已成功繫結到該Employee物件的Title,但名稱未繫結。

Employee Details

要檢查名稱發生了什麼,讓我們看看生成大量日誌的輸出視窗。

查詢錯誤的最簡單方法是搜尋錯誤,您將找到以下提到的錯誤,該錯誤顯示為“BindingExpression path error: 'FirstName' property not found on 'object' ''Employe”

System.Windows.Data Error: 40 : BindingExpression path error: 'FirstName'
   property not found on 'object' ''Employee' (HashCode = 11611730)'.
BindingExpression:Path = FirstName; 
DataItem = 'Employee' (HashCode = 11611730); target element is 'TextBlock' (Name = ''); 
target property is 'Text' (type 'String')

這清楚地表明FirstName不是Employee類的成員,因此它有助於修復應用程式中的此類問題。

再次將FirstName更改為Name後,您將看到所需的輸出。

XAML的UI除錯工具

XAML的UI除錯工具在Visual Studio 2015中引入,用於檢查執行時的XAML程式碼。藉助這些工具,XAML程式碼以正在執行的WPF應用程式的視覺化樹的形式呈現,以及樹中不同的UI元素屬性。要啟用此工具,請按照以下步驟操作。

  • 步驟1 - 轉到“工具”選單,然後從“工具”選單中選擇“選項”。

  • 步驟2 - 您將看到以下對話方塊。

Debugging Dialog Box
  • 步驟3 - 轉到左側“除錯”項下的“常規選項”。

  • 步驟4 - 選中突出顯示的選項,即“為XAML啟用UI除錯工具”。

  • 步驟5 - 按“確定”按鈕。

現在執行任何XAML應用程式或使用以下XAML程式碼:

<Window x:Class = "XAMLTestBinding.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "MainWindow" Height = "350" Width = "604">
	
   <StackPanel>
      <ComboBox Name = "comboBox" Margin = "50" Width = "100">
         <ComboBoxItem Content = "Green"/>
         <ComboBoxItem Content = "Yellow" IsSelected = "True"/>
         <ComboBoxItem Content = "Orange" />
      </ComboBox>
		
      <TextBox Name = "textBox" Margin = "50" Width = "100" 
         Height = "23" VerticalAlignment = "Top" Text = "{
         Binding ElementName = comboBox, Path = SelectedItem.Content, 
         Mode = TwoWay, UpdateSourceTrigger = PropertyChanged}" 
         Background = "{Binding ElementName = comboBox, Path = SelectedItem.Content}"> 
      </TextBox>
   </StackPanel>
	
</Window>

應用程式執行時,將顯示即時視覺化樹,其中所有元素都以樹的形式顯示。

Visual Tree

此即時視覺化樹顯示完整的佈局結構,以瞭解UI元素放置的位置。但此選項僅在Visual Studio 2015中可用。如果您使用的是舊版本的Visual Studio,則無法使用此工具;但是,還有另一個工具可以與Visual Studio整合,例如適用於Visual Studio的XAML Spy。您可以從http://xamlspy.com/download下載它。如果您使用的是舊版本的Visual Studio,我們建議您下載此工具。

XAML - 自定義控制元件

XAML提供建立自定義控制元件的最強大的功能之一,這使得建立功能豐富且可自定義的控制元件變得非常容易。當Microsoft提供的全部內建控制元件無法滿足您的標準或您不想支付第三方控制元件的費用時,可以使用自定義控制元件。

在本節中,您將學習如何建立自定義控制元件。在開始檢視自定義控制元件之前,讓我們快速瞭解一下使用者控制元件。

使用者控制元件

使用者控制元件提供了一種技術,可以將不同的內建控制元件收集並組合在一起,並將其打包到可重複使用的XAML中。使用者控制元件用於以下場景:

  • 如果控制元件包含現有控制元件,即您可以建立多個現有控制元件的單個控制元件。

  • 如果控制元件不需要主題支援。使用者控制元件不支援複雜的自定義、控制元件模板,並且難以設定樣式。

  • 如果開發人員更喜歡使用程式碼隱藏模型編寫控制元件,其中編寫檢視,然後編寫直接程式碼來處理事件。

  • 您不會在應用程式之間共享控制元件。

讓我們以使用者控制元件為例,並按照以下步驟操作:

  • 步驟 1 − 建立一個新的 WPF 專案,然後右鍵單擊您的解決方案並選擇新增 > 新建項…

WPF Project
  • 步驟 2 − 將開啟以下對話方塊,現在選擇使用者控制元件 (WPF) 並將其命名為MyUserControl

User Control
  • 步驟 3 − 單擊“新增”按鈕,您將看到兩個新檔案 (MyUserControl.xaml 和 MyUserControl.cs) 將新增到您的解決方案中。

下面是在 MyUserControl.xaml 檔案中建立按鈕和文字框以及一些屬性的 XAML 程式碼。

<UserControl x:Class = "XAMLUserControl.MyUserControl" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006"
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008"
   mc:Ignorable = "d" d:DesignHeight = "300" d:DesignWidth = "300">
	
   <Grid>
      <TextBox Height = "23" HorizontalAlignment = "Left" 
         Margin = "80,49,0,0" Name = "txtBox" VerticalAlignment = "Top" Width = "200" />
      <Button Content = "Click Me" Height = "23" 
         HorizontalAlignment = "Left" Margin = "96,88,0,0" Name = "button" 
         VerticalAlignment = "Top" Width = "75" Click = "button_Click" />
   </Grid>
	
</UserControl>

下面是在 MyUserControl.cs 檔案中用於按鈕單擊事件的 C# 程式碼,該程式碼更新文字框。

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

namespace XAMLUserControl {
   /// <summary> 
      /// Interaction logic for MyUserControl.xaml
   /// </summary> 
	
   public partial class MyUserControl : UserControl {
      public MyUserControl() {
         InitializeComponent(); 
      }
      private void button_Click(object sender, RoutedEventArgs e) { 
         txtBox.Text = "You have just clicked the button"; 
      } 
   }
}

以下是 MainWindow.xaml 中新增使用者控制元件的實現。

<Window x:Class = "XAMLUserControl.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:control = "clr-namespace:XAMLUserControl" 
   Title = "MainWindow" Height = "350" Width = "525">
	
   <Grid>
      <control:MyUserControl/>
   </Grid>
	
</Window>

編譯並執行上述程式碼後,將產生以下輸出 -

Click Me1

現在單擊“單擊我”按鈕,您將看到文字框文字已更新。

Click Me2

自定義控制元件

自定義控制元件是一個類,它提供自己的樣式和模板,這些樣式和模板通常在generic.xaml中定義。自定義控制元件用於以下場景:

  • 如果控制元件不存在,並且您必須從頭建立它。

  • 如果您想透過新增額外屬性或額外功能來擴充套件或新增現有控制元件的功能以適應您的特定場景。

  • 如果您的控制元件需要支援主題和樣式。

  • 如果您想跨應用程式共享您的控制元件。

讓我們以自定義控制元件為例,並按照以下步驟操作。

  • 步驟 1 − 建立一個新的 WPF 專案,然後右鍵單擊您的解決方案並選擇新增 > 新建項…

WPF Project
  • 步驟 2 − 將開啟以下對話方塊。現在選擇自定義控制元件 (WPF) 並將其命名為MyCustomControl

Custom Control
  • 步驟 3 − 單擊“新增”按鈕,您將看到兩個新檔案 (Themes/Generic.xaml 和 MyCustomControl.cs) 將新增到您的解決方案中。

下面是在 Generic.xaml 檔案中為自定義控制元件設定樣式的 XAML 程式碼。

<ResourceDictionary 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:local = "clr-namespace:XAMLCustomControls">
	
   <Style TargetType = "{x:Type local:MyCustomControl}"
      BasedOn = "{StaticResource {x:Type Button}}"> 
      <Setter Property = "Background" Value = "LightSalmon"/>
      <Setter Property = "Foreground" Value = "Blue"/>
   </Style>
	
</ResourceDictionary>

下面是 MyCustomControl 類的 C# 程式碼,它繼承自按鈕類,並且在建構函式中,它重寫了元資料。

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

namespace XAMLCustomControls {
   public class MyCustomControl : Button {
      static MyCustomControl() {
         DefaultStyleKeyProperty.OverrideMetadata(typeof(MyCustomControl), 
            new FrameworkPropertyMetadata(typeof(MyCustomControl)));
      }
   }
}

下面是在 C# 中自定義控制元件單擊事件的實現,它更新文字塊的文字。

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

namespace XAMLCustomControls {
   /// <summary> 
      /// Interaction logic for MainWindow.xaml 
   /// </summary> 
	
   public partial class MainWindow : Window {
      public MainWindow() { 
         InitializeComponent(); 
      }
      private void customControl_Click(object sender, RoutedEventArgs e) {
         txtBlock.Text = "You have just click your custom control"; 
      } 
   }
}

以下是 MainWindow.xaml 中新增自定義控制元件和文字塊的實現。

<Window x:Class = "XAMLCustomControls.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:control = "clr-namespace:XAMLCustomControls" Title = "MainWindow"
   Height = "350" Width = "604">
	
   <StackPanel>
      <control:MyCustomControl x:Name = "customControl" 
         Content = "Click Me" Width = "70" Margin = "10" Click = "customControl_Click"/>
      <TextBlock Name = "txtBlock" Width = "250" Height = "30"/>
   </StackPanel>
	
</Window>

編譯並執行上述程式碼後,它將產生以下輸出。請注意,輸出包含一個自定義控制元件,它是一個自定義按鈕。

Customized Button

現在單擊自定義按鈕。您將看到文字塊文字已更新。

Customized Button 1
廣告
© . All rights reserved.