用户通过窗口与 Windows Presentation Foundation (WPF) 应用程序进行交互。 窗口的主要用途是托管可视化数据的内容,并使用户能够与数据进行交互。 WPF 应用程序使用 Window 类提供自己的窗口。 本文在介绍创建和管理窗口的基础知识之前先介绍Window。
重要
本文使用从 C# 项目生成的 XAML。 如果使用 Visual Basic,XAML 看起来可能略有不同。 这些差异通常存在于属性值上 x:Class
。 C# 包括项目的根命名空间,而 Visual Basic 则不包含该命名空间。
C# 项目模板会创建一种类型,该类型包含在 app.xaml 文件中。 在 Visual Basic 中,类型命名 Application
,文件命名 Application.xaml
。
Window 类
在 WPF 中,窗口由用于执行以下操作的 Window 类封装:
- 显示窗口。
- 配置窗口的大小、位置和外观。
- 托管应用程序特定的内容。
- 管理窗口的生命周期。
下图说明了窗口的构成部分:
窗口分为两个区域:非客户区和客户区。
窗口 的非工作区 由 WPF 实现,包括大多数窗口通用的窗口部分,包括以下内容:
- 标题栏(1-5)。
- 图标(1)。
- 标题(2)。
- 最小化 (3)、最大化 (4) 和关闭 (5) 按钮。
- 包含菜单项的系统菜单 (6)。 单击图标(1)时出现。
- 边框(7)。
窗口的 工作区 是窗口非工作区中的区域,开发人员使用它添加特定于应用程序的内容,例如菜单栏、工具栏和控件。
- 客户端区域(8)
- 调整手柄(9)。 这是添加到客户区(8)的控件。
创建窗口
典型窗口的实现包括外观和行为,其中 外观 定义窗口对用户的外观和 行为 定义窗口在用户与其交互时的工作方式。 在 WPF 中,可以使用代码或 XAML 标记实现窗口的外观和行为。
但是,一般情况下,窗口的外观是使用 XAML 标记实现的,其行为是使用代码隐藏实现的,如以下示例所示。
<Window x:Class="WindowsOverview.Window1"
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:WindowsOverview"
>
<!-- Client area containing the content of the window -->
</Window>
以下代码是 XAML 的后置代码。
using System.Windows;
namespace WindowsOverview
{
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
}
}
Public Class Window1
End Class
若要使 XAML 标记文件和代码隐藏文件能够协同工作,需要满足以下条件:
在标记中,
Window
元素必须包含x:Class
属性。 生成应用程序时,x:Class
属性的存在会导致 Microsoft 构建引擎(MSBuild)生成一个从 Window 派生的x:Class
类,该类的名称由x:Class
属性指定。 这需要为 XAML 架构添加 XML 命名空间声明(xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
)。 生成的partial
类实现InitializeComponent
该方法,该方法被调用以注册事件并设置在标记中实现的属性。在代码隐藏中,类必须是一个与标记中由
partial
属性指定的同名的x:Class
类,并且还必须派生自 Window。 这样,代码隐藏文件就可以与在应用程序构建时为标记文件生成的partial
类相关联。有关详细信息,请参阅编译 WPF 应用程序。在代码隐藏中,Window 类必须实现一个构造函数,该构造函数调用
InitializeComponent
方法。InitializeComponent
由标记文件的生成的partial
类实现,用于注册事件并设置标记中定义的属性。
有了此配置,可以专注于在 XAML 标记中定义窗口的界面,并在代码后台中实现其行为。 以下示例显示了一个窗口,其中包含一个按钮,用于定义事件的 Click 事件处理程序。 这在 XAML 中实现,而处理程序在后台代码中实现。
<Window x:Class="WindowsOverview.Window1"
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:WindowsOverview"
>
<!-- Client area containing the content of the window -->
<Button Click="Button_Click">Click This Button</Button>
</Window>
以下代码是 XAML 的后置代码。
using System.Windows;
namespace WindowsOverview
{
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("Button was clicked.");
}
}
}
Public Class Window1
Private Sub Button_Click(sender As Object, e As RoutedEventArgs)
MessageBox.Show("Button was clicked.")
End Sub
End Class
为 MSBuild 配置窗口
窗口的实现方式决定了它在 MSBuild 中的配置。 对于通过 XAML 标记和后置代码定义的窗口:
- XAML 标记文件被配置为 MSBuild
Page
项。 - 代码隐藏文件被配置为 MSBuild
Compile
项目。
.NET SDK 项目会为您自动导入正确的 Page
和 Compile
项,您无需声明这些项。 为 WPF 配置项目时,XAML 标记文件会自动作为 Page
项导入,相应的代码隐藏文件将导入为 Compile
。
MSBuild 项目不会自动导入类型,必须自行声明:
<Project>
...
<Page Include="MarkupAndCodeBehindWindow.xaml" />
<Compile Include=" MarkupAndCodeBehindWindow.xaml.cs" />
...
</Project>
有关生成 WPF 应用程序的信息,请参阅 编译 WPF 应用程序。
窗口生存期
与任何类一样,窗口的生存期从第一次实例化时开始,之后该窗口会打开、激活/停用,并最终关闭。
打开窗口
若要打开窗口,首先创建它的实例,以下示例演示了该实例:
using System.Windows;
namespace WindowsOverview
{
public partial class App : Application
{
private void Application_Startup(object sender, StartupEventArgs e)
{
// Create the window
Window1 window = new Window1();
// Open the window
window.Show();
}
}
}
Class Application
Private Sub Application_Startup(sender As Object, e As StartupEventArgs)
' Create the window
Dim window As New Window1
' Open the window
window.Show()
End Sub
End Class
在此示例中,当引发 Startup 事件时,应用程序启动,并且 Window1
在应用程序启动时被实例化。 有关启动窗口的详细信息,请参阅 如何获取或设置主应用程序窗口。
实例化窗口时,会自动将对窗口的引用添加到由Application对象管理的窗口列表中。 要实例化的第一个窗口由Application主应用程序窗口自动设置。
最后,通过调用 Show 方法打开窗口,如下图所示:
通过调用 Show 打开的窗口是无 模式 窗口,应用程序不会阻止用户与应用程序中的其他窗互。 打开一个窗口,将 ShowDialog 设为 模态,并限制用户只能在该窗口内进行交互。 有关详细信息,请参阅 对话框概述。
当调用 Show 时,窗口会在显示之前执行初始化工作,以建立能够接收用户输入的基础结构。 初始化窗口时, SourceInitialized 将引发该事件,并显示该窗口。
有关详细信息,请参阅 “如何打开窗口或对话框”。
启动窗口
前面的示例使用了该 Startup
事件来运行显示初始应用程序窗口的代码。 作为一种快捷方式,请使用 StartupUri 指定应用程序中 XAML 文件的路径。 应用程序会自动创建并显示该属性指定的窗口。
<Application x:Class="WindowsOverview.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WindowsOverview"
StartupUri="ClippedWindow.xaml">
<Application.Resources>
</Application.Resources>
</Application>
窗口所有权
使用 Show 该方法打开的窗口与创建它的窗口没有隐式关系。 用户可以独立于另一个窗口与任一窗口互动,这意味着任一窗口可以执行以下操作:
- 覆盖另一个窗口(除非其中一个窗口的属性 Topmost 设置为
true
)。 - 最小化、最大化和还原,不影响另一个。
某些窗口需要与打开它们的窗口建立关系。 例如,集成开发环境(IDE)应用程序可能会打开属性窗口和工具窗口,其典型行为是覆盖创建它们的窗口。 此外,此类窗口应始终与创建它们的窗口一起关闭、最小化、最大化和还原。 可以通过将一个窗口拥有另一个窗口来建立这种关系,并通过在被拥有的窗口中设置其属性以引用拥有者窗口来实现。 下面的示例演示了此操作。
private void Button_Click(object sender, RoutedEventArgs e)
{
// Create a window and make the current window its owner
var ownedWindow = new ChildWindow1();
ownedWindow.Owner = this;
ownedWindow.Show();
}
Private Sub Button_Click(sender As Object, e As RoutedEventArgs)
' Create a window and make the current window its owner
Dim ownedWindow As New ChildWindow1
ownedWindow.Owner = Me
ownedWindow.Show()
End Sub
建立所有权后:
- 拥有的窗口可以通过检查其Owner属性的值来引用其所有者窗口。
- 所有者窗口可以通过检查其 OwnedWindows 属性的值来发现它所拥有的所有窗口。
窗口激活
首次打开窗口时,它将成为活动窗口。 活动窗口是当前正在捕获用户输入的窗口,例如键笔划和鼠标单击。 当窗口变为活动状态时,它会引发 Activated 该事件。
注释
首次打开窗口时,Activated事件首先被引发,然后才会引发Loaded和ContentRendered事件。 考虑到这一点,当ContentRendered被引发时,可以认为窗口已打开。
窗口激活后,用户可以在同一应用程序中激活另一个窗口,或激活另一个应用程序。 发生这种情况时,当前活动窗口将停用并引发 Deactivated 事件。 同样,当用户选择当前停用的窗口时,该窗口将再次激活并被置于最前面。
处理 Activated 和 Deactivated 的一个常见原因是启用和禁用功能,以便仅在窗口处于活动状态时才运行。 例如,某些窗口显示需要持续用户输入或关注的交互式内容,包括游戏和视频播放器。 以下示例是一个简化的视频播放器,演示如何处理 Activated 和 Deactivated 实现此行为。
<Window x:Class="WindowsOverview.CustomMediaPlayerWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Activated="Window_Activated"
Deactivated="Window_Deactivated"
Title="CustomMediaPlayerWindow" Height="450" Width="800">
<Grid>
<MediaElement x:Name="mediaElement" Stretch="Fill"
LoadedBehavior="Manual" Source="numbers.mp4" />
</Grid>
</Window>
以下代码是 XAML 的后台代码。
using System;
using System.Windows;
namespace WindowsOverview
{
public partial class CustomMediaPlayerWindow : Window
{
public CustomMediaPlayerWindow() =>
InitializeComponent();
private void Window_Activated(object sender, EventArgs e)
{
// Continue playing media if window is activated
mediaElement.Play();
}
private void Window_Deactivated(object sender, EventArgs e)
{
// Pause playing if media is being played and window is deactivated
mediaElement.Pause();
}
}
}
Public Class CustomMediaPlayerWindow
Private Sub Window_Activated(sender As Object, e As EventArgs)
' Continue playing media if window Is activated
mediaElement.Play()
End Sub
Private Sub Window_Deactivated(sender As Object, e As EventArgs)
' Pause playing if media is being played and window is deactivated
mediaElement.Pause()
End Sub
End Class
停用窗口时,其他类型的应用程序仍可能在后台运行代码。 例如,当用户使用其他应用程序时,邮件客户端可能会继续轮询邮件服务器。 当主窗口停用时,此类应用程序通常会提供不同的或额外的行为。 对于邮件程序,这可能意味着将新邮件项添加到收件箱和向系统托盘添加通知图标。 仅当邮件窗口未处于活动状态时,才需要显示通知图标,这可以通过检查IsActive属性来确定。
如果后台任务完成,窗口可能希望通过调用 Activate 方法更紧急地通知用户。 如果用户正在与调用时 Activate 激活的另一个应用程序进行交互,窗口的任务栏按钮会闪烁。 但是,如果用户正在与当前应用程序交互,调用 Activate 会将窗口带到前台。
注释
可以使用Application.Activated和Application.Deactivated事件处理应用程序范围激活。
阻止窗口激活
在某些情况下,显示窗口时不应激活,例如聊天应用程序的聊天窗口或电子邮件应用程序的通知窗口。
如果您的应用程序有一个在显示时不应被激活的窗口,您可以在第一次调用Show方法之前,将该窗口的ShowActivated属性设置为false
。 因此:
- 窗口未激活。
- 窗口的Activated事件没有触发。
- 当前激活的窗口将保持激活状态。
一旦用户通过点击客户端区域或非客户端区域来激活它,该窗口就会被激活。 在这种情况下:
- 窗口已激活。
- 窗口的Activated事件被引发。
- 以前激活的窗口已停用。
- 然后,窗口的 Deactivated 和 Activated 事件将按预期触发,以响应用户动作。
关闭窗口
当用户关闭窗口时,窗口的生活将开始结束。 关闭窗口后,无法重新打开它。 可以通过使用非客户区中的元素来关闭窗口,包括:
- “系统”菜单的“关闭”项。
- 按 Alt + F4。
- 按 “关闭 ”按钮。
- 当一个按钮在模态窗口中设置IsCancel属性为
true
时,按下ESC。
可以向客户区域提供更多机制来关闭窗口,其中更常见的包括:
- “文件”菜单中的“退出”项,通常用于主应用程序窗口。
- “文件”菜单中的“关闭”项,通常位于辅助应用程序窗口中。
- “ 取消” 按钮,通常位于模式对话框中。
- 关闭按钮,通常位于无模式对话框中。
若要关闭窗口以响应其中一种自定义机制,需要调用该方法 Close 。 以下示例通过从文件菜单中选择“退出”来实现关闭窗口的功能。
<Window x:Class="WindowsOverview.ClosingWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ClosingWindow" Height="450" Width="800">
<StackPanel>
<Menu>
<MenuItem Header="_File">
<MenuItem Header="E_xit" Click="fileExitMenuItem_Click" />
</MenuItem>
</Menu>
</StackPanel>
</Window>
以下代码是 XAML 的后台代码。
using System.Windows;
namespace WindowsOverview
{
public partial class ClosingWindow : Window
{
public ClosingWindow() =>
InitializeComponent();
private void fileExitMenuItem_Click(object sender, RoutedEventArgs e)
{
// Close the current window
this.Close();
}
}
}
Public Class ClosingWindow
Private Sub fileExitMenuItem_Click(sender As Object, e As RoutedEventArgs)
' Close the current window
Me.Close()
End Sub
End Class
注释
当主应用程序窗口关闭(见 MainWindow)或最后一个窗口关闭时,可以将应用程序配置为自动关闭。 有关详细信息,请参阅 ShutdownMode。
虽然窗口可以通过非客户端和客户端区域中提供的机制显式关闭,但窗口也可能因应用程序或 Windows 的其他部分的行为而隐式关闭,包括以下内容:
- 用户注销或关闭 Windows。
- 窗口关闭 Owner 。
- 主应用程序窗口已关闭,并且 ShutdownMode 是 OnMainWindowClose。
- 调用 Shutdown。
重要
窗口关闭后无法重新打开。
取消窗口关闭
当窗口关闭时,它会引发两个事件: Closing 和 Closed。
Closing 在窗口关闭之前引发,它提供一种机制,通过该机制可以阻止窗口关闭。 阻止窗口关闭的一个常见原因是窗口内容包含修改的数据。 在这种情况下, Closing 可以处理事件以确定数据是否脏,如果是,则询问用户是否继续关闭窗口而不保存数据或取消窗口关闭。 以下示例显示了处理 Closing的关键方面。
<Window x:Class="WindowsOverview.DataWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="DataWindow" Height="450" Width="800"
Closing="Window_Closing">
<Grid>
<TextBox x:Name="documentTextBox" TextChanged="documentTextBox_TextChanged" />
</Grid>
</Window>
以下代码是 XAML 的后置代码。
using System.Windows;
using System.Windows.Controls;
namespace WindowsOverview
{
public partial class DataWindow : Window
{
private bool _isDataDirty;
public DataWindow() =>
InitializeComponent();
private void documentTextBox_TextChanged(object sender, TextChangedEventArgs e) =>
_isDataDirty = true;
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
// If data is dirty, prompt user and ask for a response
if (_isDataDirty)
{
var result = MessageBox.Show("Document has changed. Close without saving?",
"Question",
MessageBoxButton.YesNo);
// User doesn't want to close, cancel closure
if (result == MessageBoxResult.No)
e.Cancel = true;
}
}
}
}
Public Class DataWindow
Private _isDataDirty As Boolean
Private Sub documentTextBox_TextChanged(sender As Object, e As TextChangedEventArgs)
_isDataDirty = True
End Sub
Private Sub Window_Closing(sender As Object, e As ComponentModel.CancelEventArgs)
' If data is dirty, prompt user and ask for a response
If _isDataDirty Then
Dim result = MessageBox.Show("Document has changed. Close without saving?",
"Question",
MessageBoxButton.YesNo)
' User doesn't want to close, cancel closure
If result = MessageBoxResult.No Then
e.Cancel = True
End If
End If
End Sub
End Class
Closing事件处理程序接收到一个CancelEventArgs,该对象实现了Cancel属性,你可以将该属性设置为true
以阻止窗口关闭。
如果 Closing 未被处理,或已被处理但未取消,窗口将关闭。 在窗口实际关闭之前,Closed 将被触发。 此时,无法阻止窗口关闭。
窗口生命周期事件
下图显示了窗口生存期内主体事件的序列:
显示窗口生命周期事件的示意图。
下图显示了在未激活的情况下显示的窗口生存期内主体事件的序列(ShowActivated 在显示窗口之前设置为 false
):
窗口位置
当窗口打开时,它具有相对于桌面的 x 和 y 维度中的位置。 可以通过分别检查Left和Top属性来确定此位置。 设置这些属性以更改窗口的位置。
首次出现时,还可以通过使用下列WindowStartupLocation枚举值之一来设置WindowStartupLocation属性,以指定Window的初始位置。
如果已指定Manual启动位置,并且Left和Top属性尚未设置,Window则会要求操作系统显示一个位置。
最上层的窗口和 z 顺序
除了具有 x 和 y 位置外,窗口还具有 z 维度中的一个位置,用于确定其相对于其他窗口的垂直位置。 这称为窗口的 z 顺序,有两种类型: normal z-order 和 topmost z-order。 以 正常 z 顺序 排列的窗口位置取决于窗口当前是否处于活动状态。 默认情况下,窗口位于普通 z 顺序中。 窗口在 最顶层 z 顺序 中的位置也取决于窗口当前是否处于活动状态。 此外,最顶层 z 顺序的窗口始终位于普通 z 顺序的窗口上方。 通过将窗口的Topmost属性设置为true
,可以将其置于最高的 z 顺序位置。
在每个 z 顺序类型中,当前活动窗口以相同的 z 顺序显示在所有其他窗口上方。
窗口大小
除了具有桌面位置外,窗口的大小由多个属性决定,包括各种宽度和高度属性以及 SizeToContent。
MinWidth,Width和MaxWidth用于管理窗口在整个生命周期内可以具有的宽度范围。
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
MinWidth="300" Width="400" MaxWidth="500">
</Window>
窗口高度由 MinHeight、Height 和 MaxHeight 管理。
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
MinHeight="300" Height="400" MaxHeight="500">
</Window>
由于每个宽度值和高度值都指定一个范围,因此,可调整大小的窗口的宽度和高度可以在相应维度的指定范围内的任何位置。 若要检测其当前宽度和高度,请分别检查ActualWidth和ActualHeight。
如果希望窗口的宽度和高度大小适合窗口内容的大小,可以使用 SizeToContent 具有以下值的属性:
-
内容大小.手动
无效果(默认值)。 -
SizeToContent.Width
设置符合内容宽度,其效果与将 MinWidth 和 MaxWidth 均设置为内容宽度相同。 -
SizeToContent.Height
适应内容高度,其效果与将 MinHeight 和 MaxHeight 都设置为内容高度相同。 -
SizeToContent.WidthAndHeight
同时设置 MinHeight 和 MaxHeight 为内容的高度,MinWidth 和 MaxWidth 为内容的宽度,这与适应内容宽度和高度的效果相同。
以下示例显示了一个窗口,该窗口在首次显示时自动调整大小以适应其内容(垂直和水平)。
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
SizeToContent="WidthAndHeight">
</Window>
下面的示例演示如何在代码中设置 SizeToContent 属性,以指定窗口调整大小以适应其内容的方式。
// Manually alter window height and width
this.SizeToContent = SizeToContent.Manual;
// Automatically resize width relative to content
this.SizeToContent = SizeToContent.Width;
// Automatically resize height relative to content
this.SizeToContent = SizeToContent.Height;
// Automatically resize height and width relative to content
this.SizeToContent = SizeToContent.WidthAndHeight;
' Manually alter window height and width
Me.SizeToContent = SizeToContent.Manual
' Automatically resize width relative to content
Me.SizeToContent = SizeToContent.Width
' Automatically resize height relative to content
Me.SizeToContent = SizeToContent.Height
' Automatically resize height and width relative to content
Me.SizeToContent = SizeToContent.WidthAndHeight
大小调整属性的优先级顺序
实质上,窗口的各种大小属性组合在一起,以定义可调整大小的窗口的宽度和高度范围。 若要确保保持某个范围有效,Window 使用以下优先顺序评估大小属性的值。
对于高度属性:
- FrameworkElement.MinHeight
- FrameworkElement.MaxHeight
- SizeToContent.Height / SizeToContent.WidthAndHeight
- FrameworkElement.Height
对于宽度属性:
- FrameworkElement.MinWidth
- FrameworkElement.MaxWidth
- SizeToContent.Width / SizeToContent.WidthAndHeight
- FrameworkElement.Width
优先级顺序还可以确定窗口在最大化时的大小,该窗口是使用 WindowState 属性管理的。
窗口状态
在可调整大小的窗口生存期内,它可以有三种状态:正常、最小化和最大化。 具有 正常 状态的窗口是窗口的默认状态。 具有此状态的窗口允许用户通过使用调整大小手柄或边框来移动和调整其大小(如果大小可调整)。
如果ShowInTaskbar设置为true
,处于“最小化”状态的窗口会折叠到其任务栏按钮,否则,它将折叠为最小可能的大小,并将自身移动到桌面的左下角。 不能使用边框或调整手柄来调整任何类型的最小化窗口的大小,尽管任务栏中未显示的最小化窗口可以在桌面上拖动。
具有最大化状态的窗口会扩展到其能达到的最大尺寸,而这个最大尺寸将由窗口的MaxWidth、MaxHeight和SizeToContent属性决定。 与最小化窗口一样,无法使用调整大小手柄或拖动边框来调整最大化窗口的大小。
可以通过设置窗口 WindowState 的属性来配置窗口的状态,该属性可以具有以下枚举值之一 WindowState :
以下示例演示如何创建一个窗口,该窗口在打开时显示为最大化。
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
WindowState="Maximized">
</Window>
通常,应设置为 WindowState 配置窗口的初始状态。 显示 可调整大小的 窗口后,用户可以按窗口标题栏上的最小化、最大化和还原按钮来更改窗口状态。
窗口外观
通过向其添加特定于窗口的内容(例如按钮、标签和文本框),可以更改窗口工作区的外观。 要配置非工作区,Window 提供了多个属性,包括用于设置窗口图标的 Icon 和用于设置其标题的 Title。
还可以通过配置窗口的大小模式、窗口样式以及它是否显示为桌面任务栏中的按钮来更改非工作区边框的外观和行为。
调整大小模式
根据WindowStyle属性,你可以控制用户能否调整窗口大小,以及调整方式。 窗口样式影响以下各项:
- 通过拖动窗口边框启用或禁用鼠标调整大小。
- “最小化”、“最大化”和“关闭”按钮是否显示在非工作区上。
- 是否启用 “最小化”、“ 最大化”和 “关闭 ”按钮。
可以通过设置窗口的 ResizeMode 属性来配置窗口的调整方式,该属性可以是以下 ResizeMode 枚举值之一:
与WindowStyle情况类似,窗口的大小调整模式在其整个生命周期内不太可能更改,这意味着您很可能会在 XAML 标记中设置它。
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
ResizeMode="CanResizeWithGrip">
</Window>
请注意,可以通过检查 WindowState 属性来检测窗口是最大化、最小化还是还原。
窗口样式
从窗口的非工作区外露的边框适用于大多数应用程序。 但是,在某些情况下,需要不同类型的边框,或者根本不需要边框,具体取决于窗口的类型。
若要控制窗口将获取的边框类型,请将其WindowStyle属性设置为以下WindowStyle枚举的值之一:
应用窗口样式的效果如下图所示:
请注意,上图不显示两者之间SingleBorderWindow
ThreeDBorderWindow
的任何明显差异。 在 Windows XP 中,ThreeDBorderWindow
确实影响了窗口的绘制方式,向客户区添加了 3D 边框。 从 Windows 7 开始,这两种样式之间的差异很小。
可以使用 XAML 标记或代码进行设置 WindowStyle 。 由于窗口生存期不太可能更改,因此很可能使用 XAML 标记对其进行配置。
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
WindowStyle="ToolWindow">
</Window>
非矩形窗口样式
在某些情况下, WindowStyle 允许你拥有的边框样式是不够的。 例如,你可能想要创建一个具有非矩形边框的应用程序,就像微软的 Windows Media Player 那样。
例如,请考虑下图中显示的语音气泡窗口:
可以通过将 WindowStyle 属性设置为 None以及使用具有透明度的特殊支持 Window 来创建这种类型的窗口。
<Window x:Class="WindowsOverview.ClippedWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ClippedWindow" SizeToContent="WidthAndHeight"
WindowStyle="None" AllowsTransparency="True" Background="Transparent">
<Grid Margin="20">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="20"/>
</Grid.RowDefinitions>
<Rectangle Stroke="#FF000000" RadiusX="10" RadiusY="10"/>
<Path Fill="White" Stretch="Fill" Stroke="#FF000000" HorizontalAlignment="Left" Margin="15,-5.597,0,-0.003" Width="30" Grid.Row="1" Data="M22.166642,154.45381 L29.999666,187.66699 40.791059,154.54395"/>
<Rectangle Fill="White" RadiusX="10" RadiusY="10" Margin="1"/>
<TextBlock HorizontalAlignment="Left" VerticalAlignment="Center" FontSize="25" Text="Greetings!" TextWrapping="Wrap" Margin="5,5,50,5"/>
<Button HorizontalAlignment="Right" VerticalAlignment="Top" Background="Transparent" BorderBrush="{x:Null}" Foreground="Red" Content="❌" FontSize="15" />
<Grid.Effect>
<DropShadowEffect BlurRadius="10" ShadowDepth="3" Color="LightBlue"/>
</Grid.Effect>
</Grid>
</Window>
这种值组合指示窗口呈现透明。 在此状态下,窗口的非客户区装饰按钮无法使用,您需要自行提供按钮。
任务栏状态
窗口的默认外观包括任务栏按钮。 某些类型的窗口没有任务栏按钮,例如消息框、对话框或设置为属性的WindowStyleToolWindow窗口。 可以通过设置 ShowInTaskbar 默认的属性 true
来控制窗口的任务栏按钮是否显示。
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
ShowInTaskbar="False">
</Window>
其他类型的窗口
NavigationWindow 是一个设计用于托管可导航内容的窗口。
对话框是通常用于从用户收集信息以完成函数的窗口。 例如,当用户想要打开文件时,应用程序将显示 “打开文件 ”对话框,以便从用户获取文件名。 有关详细信息,请参阅 对话框概述。