目录
窗口
窗口定义
WPF中窗口继承自`Window`类,一般情况下窗口的外观使用 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"
>
<!-- 窗口的内容 -->
</Window>
下面是XAML的代码隐藏
using System.Windows;
namespace WindowsOverview
{
// 此处的类名必须要和XAML中的X:Class的值保持一致,
// 当前是窗口则必须继承自Window,和XAML中的根标签一致
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
}
}
窗口生存期
与所有类一样,窗口也有生存期,开始于首次实例化窗口,在这之后将打开、激活/停用直至最终关闭窗口。
打开窗口
// 创建窗口
Window1 window = new Window1();
// 调用Show方法打开窗口
window.Show();
窗口所有权
使用 Show方法打开的窗口与创建它的窗口不具有隐式关系。 用户可以与其中任意一个窗口独立交互,这意味着这两个窗口都可以执行以下操作:
- 覆盖另一个窗口(除非其中一个窗口的 Topmost 属性设置为 `true`)。
- 在不影响另一个窗口的情况下最小化、最大化和还原。
某些窗口要求与打开它们的窗口保持某种关系。
例如,集成开发环境 (IDE) 应用程序可能打开属性窗口和工具窗口,这些窗口的典型行为是覆盖创建它们的窗口。 此外,此类窗口应始终与创建它们的窗口一起关闭、最小化、最大化和还原。
// 只需要在创建窗口后指定打开窗口的Owner属性为当前窗口即可 var ownedWindow = new ChildWindow1(); ownedWindow.Owner = this; ownedWindow.Show();
建立所有权后:
- 被拥有的窗口可以通过检查其 Owner 属性的值来引用它的所有者窗口。
- 所有者窗口可以通过检查其 OwnedWindows 属性的值来发现它拥有的所有窗口。
- 所有者窗口将不能覆盖被拥有的窗口
事件
- Activated 窗口是否处于活动状态(聚焦)
- Deactivated 窗口失焦
- Closing 窗口关闭前触发,并提供一种可以阻止窗口关闭的机制
- 可以通过事件对象的`e.Cancel = true`的方式取消窗口关闭
- Closed窗口关闭后
方法
- * `Show` 显示窗口
- * `Hide` 隐藏窗口
- * `Close`关闭窗口
窗口位置
当窗口打开时,它在相对于桌面的 x 和 y 维度中有一个位置。 可以通过检查 `Left`和 `Top`来确定此位置。 设置这些属性以更改窗口的位置。
- * `Left`设置窗口距离屏幕左侧的位置
- * `Right`设置窗口距离屏幕右侧的位置
- * `WindowStartupLocation`使用枚举指定一个位置
- * `CenterOwner` Window 的启动位置位于包含它的 Window 的中央,由 Owner 属性指定。
- * `CenterScreen`Window 的启动位置位于包含鼠标光标的屏幕的中央。
- * `Manual`可从代码中设置 Window 的启动位置,或者使用默认的 Windows 位置。
- * `Topmost`指定当前窗口为最顶层窗口
窗口尺寸
- * `Width、MinWidth、MaxWidth`控制窗口宽度,以及最大最小宽度(即使全屏功能也不会超过最大值)
- * `Height、MinHeight、MaxHeight`控制窗口高度,以及最大最小高度(即使全屏功能也不会超过最大值)
- * `SizeToContent`窗口尺寸根据内容进行自适应
- * `Width`和内容宽度相同
- * `Height`和内容高度相同
- * `WidthAndHeight`适应内容宽度和高度
窗口状态
可调整大小的窗口在生存期中拥有三种状态:正常、最小化和最大化
可以通过设置 `WindowState`属性来配置窗口的状态
- * `Normal`(默认值)默认窗口大小
- * `Maximized`最大化
- * `Minimized`最小化
窗口外观
重设大小模式
可以通过设置窗口的 `ResizeMode`属性来配置重设窗口大小的方式,该属性可以是下列 `ResizeMode`枚举值之一:
- * `CanMinimize`只能最小化和还原窗口。 同时显示“最小化”和“最大化”按钮,但只有“最小化”按钮处于启用状态。
- * `CanResize`(默认)可以调整窗口的大小。 同时显示“最小化”和“最大化”按钮,并且两个按钮均处于启用状态。
- * `CanResizeWithGrip`可以调整窗口的大小。 同时显示“最小化”和“最大化”按钮,并且两个按钮均处于启用状态。 窗口的右下角显示一个大小调整手柄。
- * `NoResize`无法调整窗口的大小。 标题栏中不显示“最小化”和“最大化”按钮。
窗口样式
通过 WindowStyle 设置不同类型的边框,或者根本不需要边框
- * `None`无边框
- * `SingleBorderWindow`(默认值)
- * `ThreeDBorderWindow`3D边框,在win7以上已无明显差别
- * `ToolWindow`仅关闭按钮的窗体
非矩形窗口
在另外一些情况下,`WindowStyle`提供的边框样式不能满足需要。 例如,可能希望创建一个带有非矩形边框(如 Windows Media Player 所使用的边框)的应用程序。
可以将`WindowStyle`设置为`None`,并将`Window`设置为透明,在窗体中展示对应的效果
<Window
...
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>
任务栏显示
窗口的默认外观包含一个任务栏按钮。 某些类型的窗口没有任务栏按钮,如`消息框`、`对话框`或 `WindowStyle`属性设置为 `ToolWindow`的窗口
设置`ShowInTaskbar`(默认`true`)可以控制当前窗口是否显示在任务栏
对话框
对话框是窗口,但具有特定的意图和用户体验。一般用于
- * 向用户显示特定信息。
- * 从用户处收集信息。
- * 同时显示并收集信息。
- * 显示操作系统提示,例如打印窗口、选择文件或文件夹。
对话框可以通过两种方式显示:模式和非模式。
模式对话框:
应用程序使用该技术中断其正在执行的操作,直到用户关闭对话框。 这通常以提示或警报的形式出现。 在关闭对话框之前,无法与应用程序中的其他窗口进行交互。 模式对话框关闭后,应用程序将继续运行。 最常见的对话框用于显示打开文件或保存文件提示、显示打印机对话框或向用户发送一些状态消息。
非模式对话框:
打开时不会阻止用户激活其他窗口。 例如,如果用户想要在文档中查找特定单词的匹配项,主窗口通常会打开一个对话框,询问用户要查找什么单词。 由于应用程序不想阻止用户编辑文档,因此该对话框不必为模式对话框。
消息框
消息框是可以用来显示文本信息并允许用户使用按钮做出决定的对话框,可以使用[MessageBox]创建一个消息框
使用方式
`MessageBoxResult messageBoxResult = MessageBox.show(String messageBoxText, ?String caption, ?MessageBoxButton button, ?MessageBoxImage icon)`
- * `messageBoxText`用于指定要显示的文本。
- * `caption` 用于指定要显示的标题栏标题。
- * `defaultResult`用于指定消息框的默认结果。
- * `icon`用于指定要显示的图标。
- * `button`用于指定要显示哪个按钮或哪些按钮。
通用对话框
打开文件”对话框
“[打开文件]对话框由文件打开功能用于检索要打开文件的名称。
// 初始化并配置
var dialog = new Microsoft.Win32.OpenFileDialog();
dialog.FileName = "Document"; // 默认文件名
dialog.Filter = "文本文档|*.txt"; // 文件后缀过滤
// 显示对话框
bool? result = dialog.ShowDialog();
// 判断是否选择
if (result == true)
{
// 通过FileName属性获取选择文件的路径
string filename = dialog.FileName;
}
保存文件”对话框
常见的保存文件对话框作为 [SaveFileDialog]类实现,并位于 `Microsoft.Win32` 命名空间中
用法和**打开文件**对话框相同,只需修改`OpenFileDialog`为`SaveFileDialog`即可
自定义模式对话框
自定义模式对话框和基本的窗口弹出类型,只需要在展示对话框时由调用之前的`Show`方法修改为`ShowDialog`方法,弹出的窗口将会在关闭之前禁止原窗口的操作
典型对话框的用户界面包括以下内容:
- * 收集所需数据要求的各种控件。
- * “确定”按钮,用户单击该按钮可以关闭对话框、返回函数并继续处理。
- * “取消”按钮,用户单击该按钮可以关闭对话框并使函数停止进一步处理。
- * 标题栏中的“关闭”按钮。
- * “最小化”、“最大化”和“还原”按钮。
- * “系统”菜单,用于最小化、最大化、还原和关闭该对话框。
- * 打开对话框的窗口上方和中间的位置。
- * 能够尽可能调整大小(以防对话框过小)并为用户提供合适的默认尺寸
- * 用作键盘快捷方式的 Esc 键,可使“取消”按钮按下。 通过将“取消”按钮的 [IsCancel](https://learn.microsoft.com/zh-cn/dotnet/api/system.windows.controls.button.iscancel) 属性设置为 `true`,可以实现此目的。
- * 用作键盘快捷方式的 Enter 键(或回车键),可使“确定”按钮按下。 通过将“确定”按钮的 [IsDefault](https://learn.microsoft.com/zh-cn/dotnet/api/system.windows.controls.button.isdefault) 属性设置为 `true`,可以实现此目的。
自定义模式对话框的展示
MarginDialog marginDialog = new MarginDialog(); // 初始化窗口
marginDialog.Owner = this; // 设置窗口所有者
marginDialog.ShowDialog(); // 以模式对话框形式显示
设置模式对话框结果
使用[ShowDialog]打开对话框基本上类似于方法的调用:即使用 [ShowDialog] 打开对话框的代码等待 [ShowDialog]返回。 当 [ShowDialog]返回时,调用它的代码需要根据用户按“确定”按钮还是“取消”按钮来决定继续还是停止处理。
单击“确定”按钮时,[ShowDialog]应该返回 `true`。 单击“取消”按钮时,[ShowDialog]应该返回 `false`。
`ShowDialog`的返回值由弹窗中的`DialogResult`属性控制
this.DialogResult = true;
当对`DialogResult`赋值后,弹窗将会自动关闭(如果按钮的`IsCancel="True"`,点击按该按钮或者按`esc`使弹窗关闭,将会自动设置`DialogResult`为`false`)
然后打开弹窗的窗口就可以通过属性获取到对话框窗口的内容
MarginDialog marginDialog = new MarginDialog();
marginDialog.Owner = this;
bool? marginDialogResult = marginDialog.ShowDialog();
if(marginDialogResult == true)
{
// 此处的name、age、sex引用弹窗对应的TextBox
MessageBox.Show($"Name: {marginDialog.name.Text}, Age: {marginDialog.age.Text}, Sex: {marginDialog.sex.Text}");
}
自定义无模式对话框
无模式对话框通过调用 [Show]方法来打开。
无模式对话框会立即返回。 因此,调用窗口无法判断无模式对话框何时关闭,也就不知道何时检查对话框结果或从对话框获取数据进行进一步处理
如果需要对对话框的操作做一些反应,可以使用委托来完成
// Dialog.xaml.cs
namespace WpfApp2
{
// 定义一个委托
public delegate void TextFoundEventHandler(object sender, EventArgs e);
public partial class Dialog : Window
{
// 创建一个委托
public event TextFoundEventHandler TextFound;
public Dialog()
{
InitializeComponent();
}
// 进行某些操作后触发委托
public void Ok(object sender, RoutedEventArgs e)
{
if (TextFound != null) TextFound(sender, e);
}
}
}
// MainWindow.xaml.cs
Dialog dialog = new Dialog();
dialog.Owner = this;
dialog.Show();
// 注册委托
dialog.TextFound += (object sender, EventArgs e) =>
{
Debug.WriteLine("开始搜索" + dialog.name);
};
本文部分来源网络,如有侵权请联系删除!!!