65.9K
CodeProject 正在变化。 阅读更多。
Home

WPF 控件测试器

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.83/5 (5投票s)

2012年1月30日

CPOL

8分钟阅读

viewsIcon

26239

downloadIcon

1492

WPF 控件测试器是一个小型应用程序,用于测试几个 WPF 控件和面板,以研究它们的行为。初学者 WPF 程序员可以通过研究此应用程序中使用的技术获益。

LaunchWindow.png

引言

本文将向您介绍我编写的一个名为“WPF 控件测试器”的示例应用程序。该应用程序的目的是研究和演示 WPF 自带的控件面板以及其他几个重要控件的行为。

背景

自几年前 WPF 技术推出以来,我一直断断续续地学习 WPF;不幸的是,我花费的时间更多的是“断”,而不是“续”。在长期使用 .NET Forms 控件以及之前的类似技术之后,我发现很难理解 XAML 的工作方式。那些熟悉的属性要么完全消失了,要么以全新的方式运行。

最近有一些空闲时间,我利用这个机会沉浸在 WPF 的学习中,我很庆幸现在我不仅开始掌握了 WPF,而且我还在享受 WPF,并且我可以看到它在许多方面都优于旧的方式。

作为我近期 WPF 研究的一部分,我编写了随本文提供的应用程序。该应用程序的大部分内容是特意用 XAML 编写的。除了少数为了方便而用 C# 编写的老式事件处理程序外,我想看看如何在不编写代码的情况下用 XAML 完成事情。一旦逻辑开始变得有意义,您就可以通过编写 XAML 完成很多事情。我确信我编写的一些代码可以以更好的方式完成,但有时我还是认为完成一个项目比把所有事情都做得尽善尽美更重要。

在接下来的文章中,我将简要介绍该应用程序,然后指出我在编程过程中发现的一些有趣的发现。

使用 WPF 控件测试器

您可以从此页面下载 WPF 控件测试器,有两个软件包可供选择。编译后的版本只需将其及其支持文件和文件夹解压缩到计算机上的任何文件夹即可“开箱即用”。否则,您可以下载源代码,以便审阅和进行自己的修改,然后从源代码编译并运行应用程序。

该应用程序创建了六个测试窗口来演示几个 WPF 控件的各种功能。所有这些窗口都可以在主启动窗口中访问。这里提供了每个窗口的缩略图(加上另外两个),并附有详细说明。

Margins and Panels window StackPanels window WrapPanels window DockPanels window
边距和内边距 StackPanels WrapPanels DockPanels
Grids window Canvas Panels window Help Window Context Menu
Grids Canvas Panels 帮助窗口 上下文菜单

边距和内边距

边距和内边距窗口演示了所有 WPF 控件上 MarginPadding 属性的使用。它演示了当使用一个数字、两个数字和四个数字来设置属性时,这些属性的行为方式。通过比较顶部、中部和底部行中显示的输出,可以轻松看出 Margin 设置和 Padding 设置之间的区别。

为了进行演示,我使用了 Label 包裹在 Border 中,以便于区分 Margin 定义的区域(红色 Border 外面的绿色区域)和 Padding 定义的区域(红色 Border 内部包围 Label 文本的区域)。

StackPanels

下一个窗口是StackPanels。在此窗口中,展示了两个 StackPanel 对象,以演示 Orientation="Vertical"Orientation="Horizontal" 之间的区别。这可能是六个测试窗口中最简单的。作为一点有趣的说明,我决定在此窗口中使用 Grid 来组织和分隔两个 StackPanel。这也可以通过其他面板完成,包括 StackPanel,所以有时在一种面板和另一种面板之间进行选择仅仅是偏好的问题。

WrapPanels

WrapPanels 窗口与StackPanels 窗口非常相似。比较两个窗口的 XAML 会发现,除了 WrapPanelStackPanel 标签之外,视觉元素几乎没有区别。在 Resources 部分创建的 Style 中,我为 WrapPanel 添加了两个 Setter 标签,它们不属于 StackPanel Style,一个是 ItemWidth,另一个是 ItemHeight

StackPanels 窗口一样,WrapPanels 也有两个 WrapPanel 对象,演示了 Orientation水平垂直设置。

DockPanels

DockPanels 窗口演示了 WPF 中可能最有用的面板。将控件添加到 DockPanel 时,您可以通过附加属性 DockPanel.Dock 指定控件应停靠在哪一侧。此窗口显示了控件添加的顺序如何影响其可用的空间。该窗口还演示了将 LastChildFill 设置为 TrueFalse 的效果。

Grids

最后两个窗口是最有趣的。Grids 窗口说明了 Grid 中的行和列是如何设置的,以及设置 RowDefinitionHeightColumnDefinitionWidth"Auto""*" 的大小调整效果。

Canvas Panels

最后一个测试窗口称为Canvas Panels,它演示了附加属性 Canvas.LeftCanvas.Top 以及常规 Margin 属性如何组合以影响控件在 Canvas 上的放置。

我需要帮助!没问题。

通过右键单击这些窗口,可以在帮助窗口中找到有关所演示控件的额外信息。这将打开一个上下文菜单。单击顶部的菜单选项将打开一个新窗口,其中包含有关该窗口和那里演示的控件的信息。

关注点

除了测试窗口中提供的演示之外,应用程序的代码还有其他有趣之处。为了方便打开测试窗口,我在启动窗口Window.Resources 中添加了每个窗口的一个实例,然后使用 Binding 将每个窗口绑定到其 Button,并使用 Button Style 将每个 ButtonContent 属性设置为其窗口的 Title 属性,并将窗口本身设置为 ButtonTag 属性。(请参阅 LaunchWindow.xaml 获取相关标记。)

然后,启动窗口就变得很简单,只需将 Sender 转换为 Window 并使用其方法使其出现。为了防止窗口在程序运行时被处理掉,LaunchWindowbutton_Click 事件处理程序向其启动的任何窗口添加了一个事件处理程序。然后,当 LaunchWindow 检测到窗口试图关闭时,它会拦截并简单地使窗口不可见。后续打开相同窗口的请求会通过使窗口可见然后使其成为活动窗口来得到满足。

我在调试时发现,当我退出程序(通过关闭所有窗口)时,程序实际上并不会停止运行。起初这让我很困惑,因为在我的测试过程中,我总是先关闭测试窗口,然后再关闭启动窗口。我曾假设关闭该窗口会使其资源被处理掉,从而自动关闭所有测试窗口。我的想法错了。

也许将 LaunchWindow 设置为每个测试窗口的 Owner 会使程序按我预期的方式工作,但我没有对此进行测试。相反,我重写了 OnClosing 来在 LaunchWindow 关闭时关闭每个测试窗口。然而,另一种技术可能在不采取措施移除用于防止测试窗口关闭的事件处理程序的情况下不起作用,并且当测试窗口调用已被处理掉的对象的事件处理程序时,可能会导致其他问题。(请参阅 LaunchWindow.xaml.cs 获取讨论的代码。)

还有其他几项可能对程序员有益。一个是在 HelpWindow 中使用 Frame 元素来显示为项目创建的 html 帮助文件。在 HelpWindow.xaml 和 HelpWindow.xaml.cs 中查找用于实现此功能的标记和代码隐藏。

另一个是添加启动屏幕在应用程序打开时显示的简单性。(只需向项目中添加一个图像,并将其 Build Action 属性设置为 SplashScreen。)起初,这个应用程序启动得很快,以至于没有足够的时间显示启动屏幕,所以我会在 App() 构造函数中添加一个短暂的延迟,然后再在 App.xaml.cs 中显示第一个窗口。

最后,您可能想看看也位于 App.xaml.cs 中的上下文菜单的事件处理程序。因为同一个 ContextMenu 用于所有可用的窗口,所以我必须找到一种方法来确定哪个窗口参与了请求。我知道 WPF 中有更好的方法来处理这个问题,但对于这个快速应用程序,我编写了代码来从生成事件的 MenuItem 中查找 ContextMenu 对象,然后从 ContextMenu 中,PlacementTarget 属性给了我一个事件调用的窗口中的控件。一旦我有了那个,我只需要沿着 Parent 项目的路径找到合适的 Window,然后我就可以确定在帮助窗口中加载哪个帮助文件了。

我很高兴能一起完成这个应用程序,并在这里写下它。我的目的主要是自私的,希望通过这条道路,我能更好地理解这项技术。然而,我也希望这能帮助其他人比没有它的时候更快地理解 WPF。

尽情享用!

历史

2012 年 1 月 29 日 - 原始提交。

© . All rights reserved.