WPF Windows 概述
用户通过窗口与 Windows Presentation Foundation (WPF) 独立应用程序进行交互。 窗口的主要用途是承载可视化数据并使用户可以与数据进行交互的内容。独立 WPF 应用程序使用 Window 类来提供它们自己的窗口。 本主题首先介绍 Window,然后介绍在独立应用程序中创建和管理窗口的基础知识。
注意 |
---|
浏览器承载的 WPF 应用程序(包括 XAML browser applications (XBAPs) 和松散Extensible Application Markup Language (XAML) 页)不提供它们自己的窗口。而是承载于 Windows Internet Explorer 提供的窗口中。请参见 WPF XAML 浏览器应用程序概述。 |
本主题包括下列各节。
- 窗口类
- 实现窗口
- 为 MSBuild 配置窗口定义
- 窗口生存期
- 窗口位置
- 窗口大小
- 大小调整属性的优先级顺序
- 窗口状态
- 窗口外观
- 安全注意事项
- 其他类型的窗口
- 相关主题
窗口类
下图显示了窗口的构成部分。
窗口分为两个区域:非工作区和工作区。
窗口的非工作区由 WPF 实现,它包括大多数窗口所共有的窗口部分,其中包括:
边框。
标题栏。
图标。
“最小化”、“最大化”和“还原”按钮。
“关闭”按钮。
“系统”菜单,其中包含允许用户最小化、最大化、还原、移动和关闭窗口以及调整窗口大小的菜单项。
窗口的工作区是窗口的非工作区内部的区域,开发人员使用它来添加应用程序特定的内容,如菜单栏、工具栏和控件。
在 WPF 中,窗口通过 Window 类进行封装,使用该类可以执行下面的操作:
显示窗口。
配置窗口的大小、位置和外观。
承载应用程序特定的内容。
管理窗口的生存期。
实现窗口
典型窗口的实现既包括外观又包括行为,其中外观定义用户看到的窗口的样子,而行为则定义在用户与窗口进行交互时窗口的运行方式。 在 WPF 中,可以使用代码或 XAML 标记来实现窗口的外观和行为。
但一般来说,窗口的外观使用 XAML 标记来实现,而行为则使用代码隐藏来实现,如下面的示例所示。
<Window
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.MarkupAndCodeBehindWindow">
<!-- Client area (for content) -->
</Window>
Imports System.Windows ' Window
Namespace SDKSample
Partial Public Class MarkupAndCodeBehindWindow
Inherits Window
Public Sub New()
InitializeComponent()
End Sub
End Class
End Namespace
using System.Windows; // Window
namespace SDKSample
{
public partial class MarkupAndCodeBehindWindow : Window
{
public MarkupAndCodeBehindWindow()
{
InitializeComponent();
}
}
}
为了使 XAML 标记文件和代码隐藏文件配合工作,需要达到下面的条件:
在标记中,Window 元素必须包含 x:Class 特性。 生成应用程序时,标记文件中存在的 x:Class 将使 Microsoft build engine (MSBuild) 生成一个从 Window 派生的 partial 类,并且该类的名称是由 x:Class 特性指定的。 这要求添加 XAML 架构的 XML 命名空间声明 (xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml")。 生成的 partial 类实现了 InitializeComponent 方法,调用此方法可注册事件并设置在标记中实现的属性。
在代码隐藏中,该类必须是 partial 类,其名称必须与标记中 x:Class 特性指定的名称相同,且必须派生自 Window。 这样,代码隐藏文件就与应用程序生成时为标记文件生成的 partial 类相关联(请参见生成 WPF 应用程序 (WPF))。
在代码隐藏中,Window 类必须实现调用 InitializeComponent 方法的构造函数。 标记文件的已生成的 partial 类实现 InitializeComponent,以便注册事件和设置在标记中定义的属性。
注意 |
---|
在使用 Microsoft Visual Studio 将新 Window 添加到项目时,Window 是同时使用标记和代码隐藏实现的,并且它包括了必要的配置来创建此处所述的标记文件和代码隐藏文件之间的关联。 |
进行此配置之后,您可以集中精力在 XAML 标记中定义窗口的外观,并在代码隐藏中实现窗口的行为。 下面的示例显示一个包含按钮的窗口(在 XAML 标记中实现)以及该按钮的 Click 事件的事件处理程序(在代码隐藏中实现)。
<Window
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.MarkupAndCodeBehindWindow">
<!-- Client area (for content) -->
<Button Click="button_Click">Click This Button</Button>
</Window>
Imports System.Windows
Namespace SDKSample
Partial Public Class MarkupAndCodeBehindWindow
Inherits Window
Public Sub New()
InitializeComponent()
End Sub
Private Sub button_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
MessageBox.Show("Button was clicked.")
End Sub
End Class
End Namespace
using System.Windows;
namespace SDKSample
{
public partial class MarkupAndCodeBehindWindow : Window
{
public MarkupAndCodeBehindWindow()
{
InitializeComponent();
}
void button_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("Button was clicked.");
}
}
}
为 MSBuild 配置窗口定义
实现窗口的方式决定了为 MSBuild 配置窗口的方式。 对于使用 XAML 标记和代码隐藏定义的窗口:
XAML 标记文件配置为 MSBuild Page 项。
代码隐藏文件配置为 MSBuild Compile 项。
这将在下面的 MSBuild 项目文件中显示。
<Project ... xmlns="https://schemas.microsoft.com/developer/msbuild/2003">
...
<Page Include="MarkupAndCodeBehindWindow.xaml" />
<Compile Include=" MarkupAndCodeBehindWindow.xaml.cs" />
...
</Project>
有关生成 WPF 应用程序的信息,请参见生成 WPF 应用程序 (WPF)。
窗口生存期
和所有类一样,窗口也有生存期,在第一次实例化窗口时生存期开始,然后就可以打开、激活和停用窗口,直到最终关闭窗口。
本节包含下列子节。
- 打开窗口
- 窗口激活
- 关闭窗口
- 窗口生存期事件
打开窗口
若要打开窗口,首先应创建一个窗口实例,下面的示例演示此操作。
<Application
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.App"
Startup="app_Startup">
</Application>
Imports System.Windows
Namespace SDKSample
Partial Public Class App
Inherits Application
Private Sub app_Startup(ByVal sender As Object, ByVal e As StartupEventArgs)
' Create a window
Dim window As New MarkupAndCodeBehindWindow()
' Open a window
window.Show()
End Sub
End Class
End Namespace
using System.Windows;
namespace SDKSample
{
public partial class App : Application
{
void app_Startup(object sender, StartupEventArgs e)
{
// Create a window
MarkupAndCodeBehindWindow window = new MarkupAndCodeBehindWindow();
// Open a window
window.Show();
}
}
}
在此示例中,在应用程序启动时(在引发 Startup 事件时发生),MarkupAndCodeBehindWindow 进行实例化。
在实例化窗口时,指向该窗口的引用会自动添加到由 Application 对象管理的窗口列表中(请参见 Application.Windows)。 另外,默认情况下,Application 会将实例化的第一个窗口设置为主应用程序窗口(请参见 Application.MainWindow)。
最后,通过调用 Show 方法打开窗口;结果如下图所示。
通过调用 Show 打开的窗口是无模式窗口,这意味着应用程序所运行的模式允许用户在同一个应用程序中激活其他窗口。
注意 |
---|
调用 ShowDialog 来模式打开窗口,例如对话框。有关更多信息,请参见对话框概述。 |
当调用 Show 时,在显示窗口以建立让窗口可以接收用户输入的基础结构之前,窗口会执行初始化工作。 当初始化窗口时,将引发 SourceInitialized 事件并显示窗口。
作为一种快捷方式,可以设置 StartupUri 以指定在应用程序启动时自动打开的第一个窗口。
<Application
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.App"
StartupUri="PlainWindow.xaml" />
当应用程序启动时,StartupUri 的值所指定的窗口会无模式地打开;在内部,则通过调用 Show 方法来打开窗口。
窗口所属权
使用 Show 方法打开的窗口与创建它的窗口之间没有隐式关系;用户可以与这两个窗口分别进行独立的交互,这意味着这两个窗口都可以执行下面的操作:
覆盖另一个窗口(除非其中一个窗口的 Topmost 属性设置为 true)。
在不影响另一个窗口的情况下,最小化、最大化和还原一个窗口。
某些窗口要求与打开它们的窗口之间保持某种关系。 例如,Integrated Development Environment (IDE) 应用程序可能会打开属性窗口和工具窗口,而这些窗口的典型行为是覆盖创建它们的窗口。 此外,此类窗口应始终与创建它们的窗口协调一致地进行关闭、最小化、最大化和还原。 可以通过让一个窗口拥有另一个窗口来建立这种关系,也可以通过使用对所有者窗口的引用来设置附属窗口的 Owner 属性,以建立这种关系。 下面的示例对此进行演示。
' Create a window and make this window its owner
Dim ownedWindow As New Window()
ownedWindow.Owner = Me
ownedWindow.Show()
// Create a window and make this window its owner
Window ownedWindow = new Window();
ownedWindow.Owner = this;
ownedWindow.Show();
建立了所属权之后:
附属窗口可以通过检查 Owner 属性的值来引用它的所有者窗口。
所有者窗口可以通过检查 OwnedWindows 属性的值来发现它拥有的全部窗口。
防止窗口激活
有些情况下,不应在显示窗口时将其激活,例如 Internet Messenger 风格的应用程序的对话窗口或电子邮件应用程序的通知窗口。
如果应用程序具有不应在显示时被激活的窗口,可以在首次调用 Show 方法之前将其 ShowActivated 属性设置为 false。 这样:
窗口便不会被激活。
也不会引发窗口的 Activated 事件。
当前激活的窗口保持激活状态。
但是,只要用户通过单击客户端或非客户端区域激活了窗口,窗口就会变为激活状态。 在这种情况下:
窗口被激活。
引发窗口的 Activated 事件。
停用以前激活的窗口。
随后作为对用户操作的响应,如期引发窗口的 Deactivated 和 Activated 事件。
窗口激活
在首次打开一个窗口时,它便成为活动窗口(除非是在 ShowActivated 设置为 false 的情况下显示)。 活动窗口是当前正在捕获用户输入(例如,键击和鼠标单击)的窗口。 当窗口变为活动窗口时,它会引发 Activated 事件。
注意 |
---|
当第一次打开窗口时,只有在引发了 Activated 事件之后,才会引发 Loaded 和 ContentRendered 事件。记住这一点,在引发 ContentRendered 时,便可认为窗口已打开。 |
窗口变为活动窗口之后,用户可以在同一个应用程序中激活其他窗口,还可以激活其他应用程序。 当这种情况出现时,当前的活动窗口将停用,并引发 Deactivated 事件。 同样,当用户选择当前停用的窗口时,该窗口会再次变成活动窗口并引发 Activated。
处理 Activated 和 Deactivated 的一个常见原因是为了启用和禁用只有在窗口活动时才能够运行的功能。 例如,某些窗口显示的交互式内容需要持续的用户输入或需要用户时刻注意,包括游戏和视频播放机。 下面的示例是一个简化的视频播放机,演示如何处理 Activated 和 Deactivated 以实现此行为。
<Window
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.CustomMediaPlayerWindow"
Activated="window_Activated"
Deactivated="window_Deactivated">
<!-- Media Player -->
<MediaElement
Name="mediaElement"
Stretch="Fill"
LoadedBehavior="Manual"
Source="numbers.wmv" />
</Window>
Imports System ' EventArgs
Imports System.Windows ' Window
Namespace SDKSample
Partial Public Class CustomMediaPlayerWindow
Inherits Window
Public Sub New()
InitializeComponent()
End Sub
Private Sub window_Activated(ByVal sender As Object, ByVal e As EventArgs)
' Recommence playing media if window is activated
Me.mediaElement.Play()
End Sub
Private Sub window_Deactivated(ByVal sender As Object, ByVal e As EventArgs)
' Pause playing if media is being played and window is deactivated
Me.mediaElement.Pause()
End Sub
End Class
End Namespace
using System; // EventArgs
using System.Windows; // Window
namespace SDKSample
{
public partial class CustomMediaPlayerWindow : Window
{
public CustomMediaPlayerWindow()
{
InitializeComponent();
}
void window_Activated(object sender, EventArgs e)
{
// Recommence playing media if window is activated
this.mediaElement.Play();
}
void window_Deactivated(object sender, EventArgs e)
{
// Pause playing if media is being played and window is deactivated
this.mediaElement.Pause();
}
}
}
其他类型的应用程序在窗口停用时可能仍会在后台运行代码。 例如,当用户使用其他应用程序时,邮件客户端可能会继续轮询邮件服务器。 这种类型的应用程序通常会在主窗口停用时提供不同的或其他的行为。 对于邮件程序,这可能意味着将新邮件项添加到收件箱并将通知图标添加到系统任务栏。 只有当邮件窗口不活动时,才需要显示通知图标,可以通过检查 IsActive 属性来确定窗口是否不活动。
如果后台任务完成,窗口可能需要通过调用 Activate 方法来更紧急地通知用户。 如果在调用 Activate 时用户正在与另一个激活的应用程序交互,则窗口的任务栏按钮会闪烁。 如果用户正在与当前应用程序交互,则调用 Activate 会将窗口置于前台。
注意 |
---|
可以使用 Application.Activated 和 Application.Deactivated 事件处理应用程序范围的激活。 |
关闭窗口
当用户关闭窗口时,窗口的生命便开始走向终结。 可以使用非工作区中的元素来关闭窗口,这些元素包括:
**“系统”菜单的“关闭”**项。
按 Alt + F4。
按**“关闭”**按钮。
可以为工作区提供关闭窗口的附加机制,其中比较常用的包括:
**“文件”菜单中的“退出”**项,通常用于主应用程序窗口。
**“文件”菜单中的“关闭”**项,通常出现在辅助应用程序窗口中。
**“取消”**按钮,通常出现在模式对话框中。
**“关闭”**按钮,通常出现在无模式对话框中。
若要响应这些自定义机制中某个机制来关闭窗口,需要调用 Close 方法。 下面的示例实现通过选择**“文件”菜单上的“退出”**来关闭窗口的功能。
<Window
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.WindowWithFileExit">
<Menu>
<MenuItem Header="_File">
<MenuItem Header="E_xit" Click="fileExitMenuItem_Click" />
</MenuItem>
</Menu>
</Window>
Imports System.Windows ' window, RoutedEventArgs
Namespace SDKSample
Partial Public Class WindowWithFileExit
Inherits System.Windows.Window
Public Sub New()
InitializeComponent()
End Sub
Private Sub fileExitMenuItem_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
' Close this window
Me.Close()
End Sub
End Class
End Namespace
using System.Windows; // window, RoutedEventArgs
namespace SDKSample
{
public partial class WindowWithFileExit : System.Windows.Window
{
public WindowWithFileExit()
{
InitializeComponent();
}
void fileExitMenuItem_Click(object sender, RoutedEventArgs e)
{
// Close this window
this.Close();
}
}
}
当窗口关闭时,它会引发两个事件:Closing 和 Closed。
Closing 在窗口关闭之前引发,它提供一种机制,可以通过这种机制来阻止窗口关闭。 阻止窗口关闭的一个常见原因是窗口内容包含了已修改数据。 在这种情况下,可以处理 Closing 事件来确定数据是否已更新,如果已更新,则询问用户是继续关闭窗口而不保存数据,还是取消窗口关闭。 下面的示例显示处理 Closing 的关键方面。
Imports System ' EventArgs
Imports System.ComponentModel ' CancelEventArgs
Imports System.Windows ' window
Namespace VisualBasic
Partial Public Class DataWindow
Inherits Window
' Is data dirty
Private isDataDirty As Boolean = False
...
Private Sub DataWindow_Closing(ByVal sender As Object, ByVal e As CancelEventArgs)
MessageBox.Show("Closing called")
' If data is dirty, notify user and ask for a response
If Me.isDataDirty Then
Dim msg As String = "Data is dirty. Close without saving?"
Dim result As MessageBoxResult = MessageBox.Show(msg, "Data App", MessageBoxButton.YesNo, MessageBoxImage.Warning)
If result = MessageBoxResult.No Then
' If user doesn't want to close, cancel closure
e.Cancel = True
End If
End If
End Sub
End Class
End Namespace
using System; // EventArgs
using System.ComponentModel; // CancelEventArgs
using System.Windows; // window
namespace CSharp
{
public partial class DataWindow : Window
{
// Is data dirty
bool isDataDirty = false;
...
void DataWindow_Closing(object sender, CancelEventArgs e)
{
MessageBox.Show("Closing called");
// If data is dirty, notify user and ask for a response
if (this.isDataDirty)
{
string msg = "Data is dirty. Close without saving?";
MessageBoxResult result =
MessageBox.Show(
msg,
"Data App",
MessageBoxButton.YesNo,
MessageBoxImage.Warning);
if (result == MessageBoxResult.No)
{
// If user doesn't want to close, cancel closure
e.Cancel = true;
}
}
}
}
}
向 Closing 事件处理程序传递一个 CancelEventArgs,该参数实现 Boolean Cancel 属性,将该属性设置为 true 可以阻止窗口关闭。
如果未处理 Closing,或者处理但未取消,则窗口将关闭。 在窗口真正关闭之前,会引发 Closed。 这时无法阻止窗口关闭。
注意 |
---|
可以将应用程序配置为当主应用程序窗口关闭(请参见 MainWindow)或最后一个窗口关闭时自动关闭。有关详细信息,请参见 ShutdownMode。 |
尽管可以通过非工作区和工作区中提供的机制来显式关闭窗口,但窗口也可能会由于应用程序或 Windows 的其他部分中的行为而隐式关闭,这些行为包括:
用户注销或关闭 Windows。
窗口的所有者关闭(请参见 Owner)。
主应用程序窗口关闭并且 ShutdownMode 为 OnMainWindowClose。
调用 Shutdown。
注意 |
---|
窗口关闭后将无法重新打开。 |
窗口生存期事件
下面的插图显示了窗口的生存期中的主体事件的顺序。
下面的插图显示了窗口(显示时没有激活)生存期中的主体事件的顺序(显示窗口之前将 ShowActivated 设置为 false)。
窗口位置
当窗口打开时,窗口在相对于桌面的 x 和 y 维度有一个位置。 可以通过分别检查 Left 和 Top 属性来确定此位置。 可以设置这些属性以更改窗口的位置。
通过将 WindowStartupLocation 属性设置为下面的 WindowStartupLocation 枚举值之一,还可以指定 Window 第一次出现时的初始位置:
如果将起始位置指定为 Manual,并且未设置 Left 和 Top 属性,则 Window 将向 Windows 请求显示的位置。
最顶层窗口和 Z 顺序
除了具有 x 和 y 位置之外,窗口还在 z 维度中具有位置,该位置确定窗口相对于其他窗口的垂直位置。 此位置称作窗口的 z 顺序,有两种 z 顺序:正常 z 顺序和最顶层 z 顺序。 在正常 z 顺序中,窗口的位置取决于窗口当前是否活动。 默认情况下,窗口位于正常 z 顺序中。 在最顶层 z 顺序中,窗口的位置也取决于窗口当前是否活动。 此外,在最顶层 z 顺序中的窗口总是位于正常 z 顺序中的窗口之上。 通过将窗口的 Topmost 属性设置为 true 可以使窗口位于最顶层 z 顺序中。
<Window
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
Topmost="True">
...
</Window>
在每个 z 顺序中,当前活动的窗口都会显示在同一 z 顺序中的所有其他窗口之上。
窗口大小
除了具有桌面位置以外,窗口还有一定的大小,窗口大小由多个属性确定,包括各种宽度和高度属性以及 SizeToContent。
MinWidth、Width 和 MaxWidth 用于管理窗口在生存期中可以具有的宽度的范围,其配置如下面的示例所示。
<Window
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
MinWidth="300" Width="400" MaxWidth="500">
...
</Window>
窗口高度由 MinHeight、Height 和 MaxHeight 管理,其设置如下面的示例所示。
<Window
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
MinHeight="300" Height="400" MaxHeight="500">
...
</Window>
因为各个宽度值和高度值各自指定了一个范围,所以可调整大小的窗口的宽度和高度可以是相应维度的指定范围内的任何值。 若要检测窗口的当前宽度和高度,请分别检查 ActualWidth 和 ActualHeight。
如果您想让窗口的宽度和高度适应窗口内容的大小,则可以使用 SizeToContent 属性,该属性具有下面的值:
Manual. 不起任何作用(默认)。
WidthAndHeight. 可以适应与内容宽度和高度,这与将 MinHeight 和 MaxHeight 设置为内容的高度并将 MinWidth 和 MaxWidth 设置为内容的宽度具有相同的效果。
下面的代码显示一个窗口,在第一次显示时,该窗口会在垂直和水平方向上自动调整大小,以适应其内容。
<Window
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
SizeToContent="WidthAndHeight">
...
</Window>
大小调整属性的优先级顺序
实质上,窗口的各种大小属性可以结合使用,以定义可调整大小的窗口的宽度和高度范围。 为了确保保持有效的范围,Window 会使用下面的优先级顺序来计算大小属性的值。
对于高度属性:
对于宽度属性:
优先级顺序还可以确定窗口在最大化时的大小;此时的窗口大小使用 WindowState 属性管理。
窗口状态
在可调整大小的窗口的生存期内,窗口可以有三种状态:正常、最小化和最大化。 处于正常状态的窗口是窗口的默认状态。 处于此状态的窗口如果是可调整大小的,则允许用户使用大小调整手柄或边框来移动窗口或调整窗口大小。
如果 ShowInTaskbar 设置为 true,则处于最小化状态的窗口会折叠到任务栏按钮;否则,窗口会折叠到可能的最小大小并重新定位到桌面的左下角。 尽管不在任务栏中显示的最小化窗口可以在桌面上四处拖动,但是不能使用边框或大小调整手柄来调整上述两种最小化窗口的大小。
处于最大化状态的窗口会扩展到可能达到的最大大小,而最大大小只能与 MaxWidth、MaxHeight 和 SizeToContent 属性规定的大小相同。 与最小化窗口一样,最大化窗口的大小也无法通过使用大小调整手柄或拖动边框来调整。
注意 |
---|
窗口的 Top、Left、Width 和 Height 属性的值始终表示正常状态的值,即使当窗口当前处于最大化或最小化状态时也是如此。 |
可以通过设置 WindowState 属性来配置窗口的状态,该属性可以取以下 WindowState 枚举值之一:
下面的示例说明如何创建在打开时最大化显示的窗口。
<Window
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
WindowState="Maximized">
...
</Window>
通常,应设置 WindowState 以配置窗口的初始状态。 一旦显示了可调整大小的窗口,用户便可以按窗口的标题栏上的最小化、最大化和还原按钮来更改窗口状态。
窗口外观
通过向窗口工作区添加窗口特定内容(如按钮、标签和文本框),可以更改窗口工作区的外观。 为了配置非工作区,Window 提供了多个属性,包括设置窗口图标的 Icon 和设置窗口标题的 Title。
还可以通过配置窗口的大小调整模式、窗口样式,以及窗口是否显示为桌面任务栏中的按钮,来更改非工作区边框的外观和行为。
本节包含下列子节。
- 大小调整模式
- 窗口样式
- 任务栏显示
大小调整模式
根据 WindowStyle 属性,您可以控制用户如何(以及是否可以)调整窗口的大小。 窗口样式的选择将影响用户是否可以通过用鼠标拖动边框来调整窗口的大小,非工作区是否显示**“最小化”、“最大化”和“调整大小”**按钮,以及如果显示这些按钮是否启用它们。
可以通过设置 ResizeMode 属性来配置窗口调整大小的方式,该属性可以取以下 ResizeMode 枚举值之一:
和 WindowStyle 相同,窗口的大小调整模式在其生存期内不能更改,这意味着您很可能会通过 XAML 标记设置该模式。
<Window
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
ResizeMode="CanResizeWithGrip">
...
</Window>
请注意,通过检查 WindowState 属性可以检测窗口是否被最大化、最小化或还原。
窗口样式
从窗口的非工作区公开的边框适合大多数应用程序。 但是,在有些情况下,可能需要使用不同类型的边框,或根本不需要边框,这要取决于窗口的类型。
若要控制窗口的边框的类型,请将窗口的 WindowStyle 属性设置为以下 WindowStyle 枚举值之一:
下图显示了这些窗口样式的效果。
可以使用 XAML 标记或代码设置 WindowStyle;因为窗口样式不能在窗口的生存期内更改,所以您很可能会使用 XAML 标记对其进行配置。
<Window
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
WindowStyle="ToolWindow">
...
</Window>
非矩形窗口样式
在另外一些情况下, WindowStyle 允许使用的边框样式不足以满足需要。 例如,您可能希望创建一个带有非矩形边框的应用程序,如 Microsoft Windows Media Player 所使用的边框。
下图中显示的对话气泡框就是一个例子。
通过将 WindowStyle 属性设置为 None,并利用 Window 对透明度的特殊支持,可以创建此类型的窗口。
<Window
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
WindowStyle="None"
AllowsTransparency="True"
Background="Transparent">
...
</Window>
不同值的这种组合使窗口呈现完全透明。 在此状态中,无法使用窗口的非工作区修饰(“关闭”菜单、“最小化”、“最大化”和“还原”按钮,等等)。 因此,您需要提供自己的修饰。
任务栏显示
窗口的默认外观包括一个任务栏按钮,如下图中所示。
有些类型的窗口没有任务栏按钮,例如消息框和对话框(请参见 对话框概述)。 通过设置 ShowInTaskbar 属性(默认情况下为 true)可以控制是否显示窗口的任务栏按钮。
<Window
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
ShowInTaskbar="False">
...
</Window>
安全注意事项
Window 要求实例化 UnmanagedCode 安全权限。 对于从本地计算机安装和启动的应用程序而言,这在为应用程序授予的权限集的范围之内。
但是,它却在为使用 ClickOnce 从 Internet 或本地 Intranet 区域启动的应用程序授予的权限集的范围之外。 因此,用户将接收到一个 ClickOnce 安全警告,并需要将应用程序的权限集提升到完全信任。
此外,XBAPs 在默认情况下无法显示窗口或对话框。 有关独立应用程序安全注意事项的讨论,请参见 WPF 安全策略 — 平台安全性。
其他类型的窗口
NavigationWindow 是一个用于承载可导航内容的窗口。 有关更多信息,请参见 导航概述。
对话框是通常用于从用户收集信息以完成某项功能的窗口。 例如,当用户要打开一个文件时,应用程序通常会显示**“打开文件”**对话框,以从用户那里获取文件名。 有关更多信息,请参见对话框概述。