自定义窗口类库:PresentationWindows

在Windows应用程序开发中,经常需要创建具有独特外观和行为的窗口。PresentationWindows是一个独特的窗口类库,它提供了三个不同的窗口类,每个类都提供了不同的功能和特性。这些类分别是: WndProcWindowAeroWindowMagnifyWindow

WndProcWindow 类类似于常规窗口,但它增加了一个 WndProc() 函数,使得交互操作更加简单。这是该库中功能最少的类。

AeroWindow 类在 WndProcWindow 的基础上增加了一些特性,比如可以设置玻璃框架扩展,并且可以指定调整大小的边框扩展。此外,它还允许在窗口的标题栏区域放置控件,类似于Firefox、IE和Opera浏览器。

MagnifyWindow 类包含了前两个窗口类的所有特性,并增加了一个新功能:自动支持放大镜功能。它提供了一个“放大镜”,可以跟随鼠标指针放大触摸到的所有内容。这利用了WPF中的高质量矢量图形来缩放内容,而不会损失质量。当设置 MagnifyAmount 属性时,放大镜会自动显示和隐藏。

这个功能在Windows XP及以上版本上都能工作,下面的截图展示了许多不同的视觉样式。

让应用程序看起来更美观的一个简单任务是扩展Aero玻璃框架。可能已经尝试过在Windows Forms中实现它,但控件上的文本可能难以阅读,而且需要很多技巧才能使其工作。然后可能会尝试WPF,这会工作得很好,因为这是WPF的强项。

现在有两个选择:可以PInvoke原始API来扩展玻璃框架,或者可以使用WPF提供的 WindowChrome 类。API是有效的,但可能很快就会发现它没有考虑到DPI的差异,这意味着如果DPI高于默认值,玻璃就不会完全扩展。

WindowChrome 考虑了DPI,但使用它,将放弃操作系统通常提供的标题栏内容。然后还有基本和经典主题的问题,因为桌面组合在这些场景中被禁用,所以需要自己的实现才能工作。

有关如何手动克服这些问题的教程,但它们很难且耗时。找过,但似乎没有库将所有这些功能包装成一个专业的库,可以在XAML中启动。直到现在。

使用代码

使用这个代码非常简单。需要做的只有几件事:

  1. 向类库添加引用
  2. MainWindow.xaml 文件中添加XAML命名空间引用(见下文),并告诉XAML创建一个 PresentationWindows 类的实例,而不是常规窗口。
  3. MainWindow.xaml.cs(或.vb)中更改 MainWindow 类,使其派生自 PresentationWindows 类之一。

以下示例展示了如何设置一个放大倍数为2的 MagnifyWindow

AeroWindow 类有一些新属性,包括以下内容:

  • FrameExtension(默认="0,0,0,0") - 这是一个特殊类型的属性 "WindowFrameThickness",并指定了在每个相应侧进一步扩展窗口框架的数量。类型 "WindowFrameThickness" 像常规的Thickness一样工作,但也有 "Full" 扩展的定义(完全扩展窗口框架,就像小工具窗口一样),并允许窗口的某些侧完全没有框架(例如,FrameExtension="*,0,*,15" 只留下顶部和底部的窗口铬)。这是这个库中最重要的新属性。
  • CaptionHeight(默认="Default") - 这是另一个特殊类型的属性 CaptionHeight。这应该设置为标题栏的期望高度,或者 "Default"。
  • ResizeBorderExtension(默认="Full") - 这也是一个类型为 WindowFrameThickness 的属性,并且像 FrameExtensionProperty 一样工作,但它是关于 "调整大小边框"(定义为用户可以拖动以调整窗口大小的窗口区域)扩展多远。
  • AlwaysShowBasicFrame(默认="False") - 设置为 "true" 以强制窗口表现得像是桌面组合(Windows aero)总是被禁用。它实际上所做的是使用窗口框架的基本版本,而不是aero边框。
  • TitleBarContent(默认=null) - 这是一个特殊属性,指定了应该在窗口的标题栏中显示什么。实际内容只有在指定了不同的模板时才会显示,因为默认模板不显示这个内容。

MagnifyWindow 类型还添加了一个新属性:

  • MagnifyAmount(默认=1) - 这个属性指定了 "放大镜" 放大内容的倍数。当这个属性设置为1时,不显示放大镜。但是当它设置为不同的值时,窗口上会显示一个放大镜(见上面的截图)。这个放大镜跟随鼠标,放大它路径上的所有内容。背景中的窗口铬不会被放大,当使用aero边框时,基本标题按钮会被打开,以便可以使用。

另外,可能已经注意到,要使用 TitleBarContent,需要指定一个不同的模板。包括了一个名为 "Templates" 的静态类,可以从中获取这些。这里有四个模板:

  • AeroWindowNormalTemplate
  • AeroWindowTitleBarContentTemplate
  • MagnifyWindowNormalTemplate
  • MagnifyWindowTitleBarContentTemplate

这些应该都是自解释的。可以通过在窗口定义中添加以下属性在XAML中设置这些:

Template="{x:Static presentation:Templates.MagnifyWindowTitleBarContentTemplate}"

要点

在传统的窗口类中,不会真的设置模板属性,因为WPF会为处理,也不会像设置按钮一样设置窗口的样式。

AeroWindow(及其所有派生类型)是不同的。可以在XAML中为窗口设置一个模板,这会影响它的外观,并使用绑定和部分使其正确地与基本和经典主题一起工作,并使用正确的系统大小。

在这样做的过程中,学会了如何用代码编写模板。所有四个默认模板实际上是用代码编写的。

传统上,Windows视觉样式不是WPF的一部分,因为按钮是矢量风格的,并且与Windows视觉样式系统是分开的。如果在这里尝试,保持正确的窗口样式将是一场噩梦,所以有点hacky。基本窗口边框是用视觉样式绘制的,通过使用Windows Forms视觉样式类。这几乎是完美的,但一个缺点是不会得到高质量的矢量缩放,因为这在Windows中是以位图存储的。

在Windows 8中,人们可能会告诉Aero已经消失了。这根本不是真的,事实上,没有办法关闭它!唯一消失的aero是透明窗口和翻转3D。窗口框架仍然以相同的方式工作。因此,这在Windows 8中有效,并为窗口添加了最喜欢的颜色(见截图)。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485