XAML - 快速指南


XAML - 概述

XAML 代表可扩展应用程序标记语言。它是一种基于 XML 的简单声明性语言。

  • 在XAML中,很容易创建、初始化和设置具有层次关系的对象的属性。

  • 它主要用于设计GUI。

  • 它也可用于其他目的,例如,在 Workflow Foundation 中声明工作流。

XAML可用于不同的平台,例如WPF(Windows Presentation Foundation)、Silverlight、移动开发和Windows Store App。它可以跨不同的.Net框架和CLR(公共语言运行时)版本使用。

XAML 的工作原理

XAML 是一种声明性语言,它定义了您想要做什么如何做。XAML 处理器负责找出HOW部分。让我们看一下下面的架构。它总结了 XAML 方面的内容 -

XAML 工作

该图说明了以下操作 -

  • XAML 文件由特定于平台的 XAML 处理器解释。

  • XAML 处理器将 XAML 转换为描述 UI 元素的内部代码。

  • 内部代码和 C# 代码通过部分类定义链接在一起,然后 .NET 编译器构建应用程序。

XAML 的优点

我们所有人在 GUI 设计方面长期面临的问题之一可以通过使用 XAML 来解决。它可用于设计 Windows 窗体应用程序中的 UI 元素。

在早期的 GUI 框架中,应用程序的外观和Behave之间没有真正的分离。GUI 及其Behave都是使用相同的语言(例如C# 或VB.net)创建的,这需要开发人员付出更多努力来实现UI 及其关联的Behave。

图形用户界面框架

使用 XAML,可以很容易地将Behave与设计器代码分开。因此,XAML 程序员和设计人员可以并行工作。XAML 代码非常容易阅读和理解。

XAML框架

XAML - 环境设置

Microsoft 为 XAML 提供了两个重要的工具 -

  • 视觉工作室
  • 表达混合

目前,这两种工具都可以创建 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 Store App。因此,为此目的,您将需要 Visual Studio 的许可版本。

安装

按照下面给出的步骤在您的系统上安装 Visual Studio -

  • 下载文件后,运行安装程序。将显示以下对话框。

Visual Studio 对话框
  • 单击“安装”按钮,它将开始安装过程。

安装
  • 安装过程成功完成后,您将看到以下屏幕。

Visual Studio 安装完成
  • 如果需要,关闭此对话框并重新启动计算机。

  • 现在从“开始”菜单打开 Visual studio,它将显示以下对话框。第一次需要一些时间,只是为了准备。

Visual Studio 开始菜单

一切完成后,您将看到 Visual Studio 的主窗口。

主窗口

实施的第一步

让我们从一个简单的实现开始。请按照以下步骤操作 -

  • 单击“文件”→“新建”→“项目”菜单选项。

项目菜单
  • 将显示以下对话框 -

对话框
  • 在“模板”下,选择“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 元素下添加一个按钮和一个文本块。这称为对象元素语法,左尖括号后跟我们要实例化的名称,例如按钮,然后定义内容属性。分配给内容的字符串将显示在按钮上。现在将按钮的高度和宽度分别设置为 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> 

当您编译并执行上述代码时,您将看到以下窗口。

第一个按钮

恭喜!您已经设计了第一个按钮。

在 MAC 操作系统上编写 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

<窗口

它是根的开放对象元素或容器。

2

x:Class="Resources.MainWindow"

它是分部类声明,将标记连接到其中定义的分部类代码。

3

xmlns

映射 WPF 客户端/框架的默认 XAML 命名空间

4

xmlns:x

XAML 语言的 XAML 命名空间,将其映射到 x: 前缀

5

>

根对象元素的结尾。

6

<网格>

</网格>

空网格对象的开始和结束标签。

7

</窗口>

关闭对象元素

对象元素的语法规则

XAML 的语法规则几乎与 XML 类似。如果您查看 XAML 文档,您会发现它实际上是一个有效的 XML 文件。但是,XML 文件不能是有效的 XAML 文件。这是因为在 XML 中,属性的值必须是字符串,而在 XAML 中,它可以是不同的对象,称为 Property 元素语法。

  • Object 元素的语法以左尖括号(<) 开头,后跟对象的名称,例如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# 代码

现在看一下用 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# 代码输出

现在您可以看到使用和理解 XAML 是多么简单。

XAML 对比 网络

在本章中,我们将在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 中实现该Behave。

在此示例中,主窗口中添加了一个按钮。当用户单击此按钮时,它会在消息框中显示一条消息。下面是 XAML 中的代码,其中使用一些属性声明了按钮对象。

<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中,实现了按钮点击事件(Behave)。此事件在消息框中显示消息。

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 

当上面的代码被编译并执行时,它将显示以下屏幕 -

留言箱

现在单击上面的“Click Me”按钮。它将显示以下消息 -

点我

XAML - 构建块

本章将描述 XAML 应用程序的一些基本且重要的构建块。它将解释如何

  • 创建并初始化一个对象,
  • 可以使用资源、样式和模板轻松修改对象,
  • 通过使用变换和动画使对象具有交互性。

对象

XAML 是一种典型的声明性语言,可以创建和实例化对象。这是基于XML 描述对象的另一种方式,即在程序执行之前需要创建哪些对象以及如何初始化它们。对象可以是

  • 容器(堆栈面板、停靠面板)
  • UI 元素/控件(按钮、文本框等)
  • 资源词典

资源

资源通常是与某些您希望多次使用的对象相关的定义。它能够在本地存储控件或当前窗口的数据,或者为整个应用程序全局存储数据。

风格

XAML 框架提供了多种策略来个性化和自定义应用程序的外观。样式使我们能够灵活地设置对象的某些属性,并在多个对象之间重复使用这些特定设置以获得一致的外观。

  • 在样式中,您只能设置对象的现有属性,例如高度、宽度、字体大小等。
  • 只能指定控件的默认Behave。
  • 可以将多个属性添加到样式中。

在第一个图中,您可以看到三个按钮分别设置了相同的高度和宽度属性;但在第二张图中,您可以看到所有按钮都相同的高度和宽度被添加到样式中,然后该样式与所有按钮相关联。

风格 款式1

模板

模板描述了控件的整体外观和视觉外观。对于每个控件,都有一个与其关联的默认模板,该模板为该控件提供外观。在 XAML 中,当您想要自定义控件的视觉Behave和视觉外观时,可以轻松创建自己的模板。

在下面的屏幕截图中,有两个按钮,一个是模板按钮,另一个是默认按钮。

默认按钮

现在,当您将鼠标悬停在按钮上时,它也会更改颜色,如下所示。

默认按钮 1

使用模板,您可以访问比样式更多的控件部分。您可以指定控件的现有Behave和新Behave。

动画和转换

Windows 运行时内的动画和转换可以通过构建交互性和移动来改进 XAML 应用程序。通过使用 Windows 运行时动画库中的动画,您可以轻松地将交互式外观集成到 XAML 应用程序中。使用了动画

  • 增强用户界面或使其更具吸引力。
  • 吸引用户对更改的注意。

在下面的屏幕截图中,您可以看到一个正方形 -

正方形

当您将鼠标悬停在该方块上时,它将向各个方向扩展,如下所示。

方格1

XAML - 控件

XAML 用户界面框架提供了广泛的控件库,支持 Windows 的 UI 开发。其中一些具有视觉表示,例如 Button、Textbox、TextBlock 等;而其他控件则用作其他控件或内容(例如图像)的容器。所有 XAML 控件均继承自System.Windows.Controls.Control

控件的完整继承层次结构如下 -

控制层次结构

这是我们将在本章中一一讨论的控件列表。

先生。 控制和说明
1 按钮

响应用户输入的控件。

2 日历

表示一个控件,使用户能够使用可视日历显示来选择日期。

3 复选框

用户可以选择或清除的控件。

4 组合框

用户可以从中选择项目的下拉列表。

5 上下文菜单

获取或设置每当通过用户界面 (UI) 从此元素内请求上下文菜单时应显示的上下文菜单元素。

6 数据网格

表示在可自定义网格中显示数据的控件。

7 日期选择器

允许用户选择日期的控件。

8 对话框

应用程序还可以向用户显示附加窗口以收集或显示重要信息。

9 网格视图

一种按行和列显示项目集合的控件,可以水平滚动。

10 图像

呈现图像的控件。

11 列表框

一个控件,显示用户可以从中选择的内联项目列表。

12 菜单

表示 Windows 菜单控件,使您能够分层组织与命令和事件处理程序关联的元素。

13 密码盒

用于输入密码的控件。

14 弹出窗口

在应用程序窗口范围内的现有内容之上显示内容。

15 进度条

通过显示条来指示进度的控件。

16 进度环

通过显示环来指示不确定进度的控件。

17 号 单选按钮

允许用户从一组选项中选择单个选项的控件。

18 富编辑框

一种控件,允许用户编辑包含格式化文本、超链接和图像等内容的富文本文档。

19 滚动查看器

允许用户平移和缩放其内容的容器控件。

20 搜索框

允许用户输入搜索查询的控件。

21 滑块

一种控件,允许用户通过沿轨道移动 Thumb 控件来从一系列值中进行选择。

22 文本块

显示文本的控件。

23 时间选择器

允许用户设置时间值的控件。

24 切换按钮

可以在两种状态之间切换的按钮。

25 工具提示

显示元素信息的弹出窗口。

26 窗户

根窗口提供最小化/最大化选项、标题栏、边框和关闭按钮。

在本章中,我们将讨论所有这些控制及其实现。

XAML - 布局

控件的布局对于应用程序的可用性非常重要且至关重要。需要在您的应用程序中排列一组 GUI 元素。选择布局面板时需要考虑一些重要事项;

  • 子元素的位置。
  • 子元素的大小。
  • 将重叠的子元素分层。

当应用程序在不同的屏幕分辨率上使用时,控件的固定像素排列不起作用。XAML 提供了一组丰富的内置布局面板,可以以适当的方式排列 GUI 元素。一些最常用和流行的布局面板如下 -

先生编号 面板和说明
1 堆栈面板

Stack面板是XAML中的一个简单且有用的布局面板。在堆栈面板中,子元素可以根据方向属性水平或垂直排列在一行中。

2 包裹面板

在WrapPanel 中,子元素根据orientation 属性按从左到右或从上到下的顺序放置。

3 停靠面板

DockPanel 定义一个区域来相对于彼此排列子元素,无论是水平还是垂直。使用 DockPanel,您可以使用 Dock 属性轻松地将子元素停靠到顶部、底部、右侧、左侧和中心。

4 画布面板

Canvas 面板是基本布局面板,可以使用相对于 Canvas 任意一侧(例如左、右、上、下)的坐标显式定位子元素。

5 网格面板

网格面板提供了一个由行和列组成的灵活区域。在网格中,子元素可以以表格形式排列。

XAML - 事件处理

XAML 中事件的一般概念与其他流行编程语言(例如 .NET 和 C++)中的事件类似。在 XAML 中,所有控件都会公开一些事件,以便可以出于特定目的订阅它们。

每当事件发生时,应用程序都会收到通知,并且程序可以对其做出反应,例如,使用关闭按钮来关闭对话框。

根据应用程序的要求,可以为应用程序的不同Behave订阅多种类型的事件,但最常用的事件是与鼠标和键盘相关的事件,例如:

  • 点击
  • 鼠标按下
  • 鼠标输入
  • 鼠标离开
  • 鼠标按下
  • 按键按下
  • 按键向上

在本章中,我们将使用一些基本和最常用的事件来了解如何将特定控件的事件链接到背后的代码,其中将根据特定事件时用户想要执行的操作来实现Behave发生。

让我们看一个按钮单击事件的简单示例。下面给出的是 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事件,您可以添加任何类型的Behave作为对单击的响应。让我们看一下 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!"); 
      } 
   }
}

当您编译并执行上述代码时,它将产生以下输出 -

事件处理

当您单击该按钮时,将触发单击 (OnClick) 事件并显示以下消息。

事件处理函数

现在让我们看一下处理多个事件的稍微复杂的示例。

例子

以下示例包含一个带有 ContextMenu 的文本框,可操作文本框中的文本。

以下 XAML 代码创建一个 TextBox、一个 ContextMenu 和 MenuItems,其中包含一些属性和事件(例如 Checked、Unchecked 和 Click)。

<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; 
         } 
      }
   }
}

当您编译并执行上述代码时,它将产生以下输出 -

上下文菜单输出

我们建议您执行上面的示例代码并尝试一些其他事件。

活动

先生。 控制和说明
1

已检查

当选中 ToggleButton 时触发。(继承自ToggleButton)

2

点击

单击按钮控件时发生。(继承自ButtonBase)

3

上下文菜单关闭

在关闭元素上的任何上下文菜单之前发生。(继承自 FrameworkElement。)

4

上下文菜单打开

打开元素上的任何上下文菜单时发生。(继承自 FrameworkElement。)

5

数据上下文改变

当 FrameworkElement.DataContext 属性的值更改时发生。(继承自FrameworkElement)

6

拖拽输入

当输入系统报告以此元素为目标的基础拖动事件时发生。(继承自 UIElement)。

7

拖动离开

当输入系统报告以此元素为原点的基础拖动事件时发生。(继承自UIElement)

8

拖拽

当输入系统报告将此元素作为潜在放置目标的基础拖动事件时发生。(继承自UIElement)

9

拖动启动

当启动拖动操作时发生。(继承自UIElement)

10

删除完成

当拖放操作结束时发生。(继承自UIElement)

11

下拉关闭

当组合框的下拉部分关闭时发生。

12

下拉打开

当组合框的下拉部分打开时发生。

13

获得焦点

当 UIElement 获得焦点时发生。(继承自UIElement)

14

保持

当在此元素的命中测试区域上发生未处理的保持交互时发生。(继承自UIElement)

15

中间的

当 ToggleButton 的状态切换到不确定状态时触发。(继承自ToggleButton)

16

已启用更改

当 IsEnabled 属性更改时发生。(继承自Control)

17 号

按键按下

当 UIElement 具有焦点时按下键盘按键时发生。(继承自UIElement)

18

按键向上

当 UIElement 具有焦点时释放键盘按键时发生。(继承自UIElement)

19

失去焦点

当 UIElement 失去焦点时发生。(继承自UIElement)

20

操作完成

当对 UIElement 的操作完成时发生。(继承自UIElement)

21

操纵三角洲

当输入设备在操作期间改变位置时发生。(继承自UIElement)

22

操纵惯性启动

当输入设备在操作期间失去与 UIElement 对象的接触并且惯性开始时发生。(继承自UIElement)

23

操纵开始

当输入设备开始对 UIElement 进行操作时发生。(继承自UIElement)

24

操纵启动

首次创建操纵处理器时发生。(继承自UIElement)

25

选择已更改

当文本选择发生更改时发生。

26

尺寸已改变

当 FrameworkElement 上的 ActualHeight 或 ActualWidth 属性更改值时发生。(继承自FrameworkElement)

27

未选中

当未选中 ToggleButton 时发生。(继承自ToggleButton)

28

值改变

当范围值更改时发生。(继承自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> 

两个文本块的文本属性静态设置为“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; 
      }
   }
}

在此类中,我们只有两个变量:NameTitle,以及一个静态方法,在该方法中初始化 Employee 对象,该方法将返回该雇员对象。因此,我们绑定到属性“名称”和“标题”,但我们尚未选择该属性属于哪个对象。最简单的方法是将一个对象分配给 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(); 
      } 
   }
}

让我们运行这个应用程序,您可以立即在主窗口中看到我们已成功绑定到该 Employee 对象的名称和标题。

单向数据绑定

双向数据绑定

在双向绑定中,用户可以通过用户界面修改数据并在源中更新该数据。如果在用户查看视图时源发生变化,您可能需要更新视图。

例子

让我们看一下下面的示例,其中创建了一个包含三个组合框项目的组合框和一个带有一些属性的文本框。在此示例中,我们没有任何标准数据源,但 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> 

当您编译并执行上述代码时,它将产生以下输出。当用户从组合框中选择一个项目时,文本框文本和背景颜色将相应更新。

双向绑定

同样,当用户在文本框中键入有效的颜色名称时,组合框和文本框的背景颜色也会更新。

双向绑定2

XAML - 标记扩展

在 XAML 应用程序中,标记扩展是一种获取既不是特定 XAML 对象也不是基元类型的值的方法/技术。标记扩展可以通过打开和关闭花括号来定义,并且在花括号内定义标记扩展的范围。

数据绑定和静态资源是标记扩展。System.xaml中有一些预定义的 XAML 标记扩展可供使用。

让我们看一个简单的示例,其中使用了StaticResources标记扩展,它是预定义的 XAML 标记扩展。

以下 XAML 代码创建两个具有某些属性的文本块,它们的前景在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。您可以看到两个前景色为蓝色的文本块。

标记扩展

在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 代码中,使用一些属性创建了一个按钮,对于内容值,使用了自定义标记扩展(my:MyMarkupExtension),并使用了两个值“Markup”和“Extension”,分别分配给 FirstStr 和 SecondStr。

实际上,MyMarkupExtension它是一个派生自MarkupExtensionC# 实现的类,如下所示。此类包含两个字符串变量 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; 
      } 
   }
}

让我们运行这个应用程序,您可以立即在主窗口中看到“标记扩展”已成功用作按钮的内容。

标记扩展 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。当鼠标悬停在按钮上时,会改变按钮的前景色。当鼠标离开按钮时,它会变回原来的颜色。

依赖属性

依赖属性和其他 CLR 属性之间的主要区别是 -

  • CLR 属性可以使用gettersetter直接从类的私有成员中读取/写入。对于依赖属性,它不会存储在本地对象中。

  • 依赖属性存储在 DependencyObject 类提供的键/值对字典中。

  • 它还可以节省大量内存,因为它会在更改时存储属性。

  • 它也可以绑定在 XAML 中。

在.NET框架中,还可以定义自定义依赖属性。以下是在 C# 中定义自定义依赖属性的步骤。

  • 使用系统调用寄存器声明并注册您的依赖属性。

  • 提供属性的 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>

让我们运行这个应用程序,您可以立即在主窗口中看到用户控件的依赖属性已成功用作文本。

你好世界示例

XAML - 资源

资源通常是与某些您希望多次使用的对象相关的定义。它能够在本地存储控件或当前窗口的数据,或者为整个应用程序全局存储数据。

将对象定义为资源允许我们从另一个地方访问它。因此,它允许可重用​​性。资源在资源字典中定义,任何对象都可以定义为资源,有效地使其成为可共享的资产。为 XAML 资源指定唯一键,并且可以使用该键通过使用 StaticResource 标记扩展来引用它。

让我们再次看一个简单的示例,其中使用一些属性创建两个文本块,并且它们的前景色在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。您可以看到两个前景色为蓝色的文本块。该资源的优点是,如果有多个文本块并且您想更改它们的背景颜色,那么您只需在资源字典中更改它即可。

资源

资源范围

资源是在资源字典中定义的,但是有很多地方可以定义资源字典。在上面的示例中,资源字典是在窗口/页面级别定义的。在哪个字典中定义资源会立即限制该资源的范围。因此,范围(即您可以在哪里使用资源)取决于您定义它的位置。

  • 在网格的资源字典中定义资源,并且该资源只能由该网格及其子元素访问。

  • 在窗口/页面上定义它,该窗口/页面上的所有元素都可以访问它。

  • App根目录可以在App.xaml资源字典中找到。它是我们应用程序的根,因此此处定义的资源范围仅限于整个应用程序。

就资源的范围而言,最常见的是应用程序级别、页面级别和特定元素级别(如 Grid、StackPanel 等)。

资源范围

资源词典

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>

当上面的代码被编译并执行时,它将产生以下输出 -

资源

我们建议您执行上面的代码并尝试更多的资源,例如背景颜色等。

XAML - 模板

模板描述了控件的整体外观和视觉外观。对于每个控件,都有一个与其关联的默认模板,该模板为该控件提供外观。

在 XAML 中,当您想要自定义控件的视觉Behave和视觉外观时,可以轻松创建自己的模板。逻辑和模板之间的连接可以通过数据绑定来实现。

样式和模板之间的主要区别是 -

  • 样式只能更改具有该控件的默认属性的控件的外观。

  • 使用模板,您可以访问比样式更多的控件部分。您还可以指定控件的现有Behave和新Behave。

最常用的模板有两种类型。

  • 控制模板
  • 数据模板

控制模板

控件模板定义或指定控件的视觉外观和结构。所有UI元素都具有某种外观和Behave,例如,按钮具有外观和Behave。单击事件或鼠标悬停事件是响应单击和悬停而触发的Behave,并且还有可以通过控件模板更改的按钮的默认外观。

让我们再次看一个简单的示例,其中创建了两个带有一些属性的按钮。一种是使用模板,另一种是使用默认按钮。

<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 =