您的位置:首页 > 其它

《Programming WPF》翻译 第7章 1.图形基础

2008-04-04 00:30 363 查看
WPF使得在你的应用程序中使用图形很容易,以及更容易开发你的显卡的能力。这有很多图形构架的方面来达到这个目标。其中最重要的是综合。

7.1.1综合

图形化元素可以组合到你的用户界面的任何一部分中。很多GUI技术易于将图形分离到一个独立的世界。这就需要一个“操纵杆”——当移动一个世界的按钮、文本框和其它框架到另一个世界的Shape和图像中,由于在很多系统中,这两个世界有不同的编程模型。

例如,Windows Forms和Mac OS的Cocoa都提供了在窗体中排列控件的能力,以及建立一个与这些控件交互的程序。它们还提供了一些API,这些API提供了高级的、完全的可伸缩的2维空间绘图工具。(在Windows Forms中为GDI+,在OS X中为Quartz 2D。)但是这些绘图API是不同于控件API的。绘图基础是非常不同于这些系统中的控件的,你不可以自由的混合这两种。

WPF,另一方面,把Shape作为UI树中的元素,就像其他元素一样。因此,我们可以自由的混和它们在任意类型的元素中。示例7-1显示了各种各样的例子。

示例7-1



<DockPanel>

<StackPanel DockPanel.Dock="Top" Orientation="Horizontal">

<TextBlock>Mix</TextBlock>

<Rectangle Fill="Red" Width="20" />

<TextBlock>text</TextBlock>

<Ellipse Fill="Blue" Width="40" />

<TextBlock>and</TextBlock>

<Button>Controls</Button>

</StackPanel>

<Ellipse DockPanel.Dock="Left" Fill="Green" Width="100" />

<Button DockPanel.Dock="Left">Foo</Button>

<TextBlock FontSize="24" TextWrap="Wrap">

And of course you can put graphics into

your text: <Ellipse Fill="Cyan" Width="50" Height="20" />

</TextBlock>

</DockPanel>
正如你看到的,图形化元素可以被无缝隙的添加到标记中。外观和图形一起工作——正如它和任何其它元素一起工作一样,结果如图7-1所示。

图7-1

<Button>

<StackPanel Orientation="Horizontal">

<Canvas Width="20" Height="18" VerticalAlignment="Center">

<Ellipse Canvas.Left="1" Canvas.Top="1" Width="16" Height="16"

Fill="Yellow" Stroke="Black" />

<Ellipse Canvas.Left="4.5" Canvas.Top="5" Width="2.5" Height="3"

Fill="Black" />

<Ellipse Canvas.Left="11" Canvas.Top="5" Width="2.5" Height="3"

Fill="Black" />

<Path Data="M 5,10 A 3,3 0 0 0 13,10" Stroke="Black" />

</Canvas>

<TextBlock VerticalAlignment="Center">Click!</TextBlock>

</StackPanel>

</Button>
当然,带有图像的按钮并不是一个新事物,但是传统上,按钮允许设置一张图片来支持于此。例如,Windows Forms中,按钮有一个Image属性,以及在Cocoa中,NSButton有一个setImage方法。这种实现使相当没有弹性的——控件允许设置一个单独的标题和一张单独的图片。比较示例7-2,这里使用了StackPanel在按钮内部布局以及只增加它需要的内容。你可以使用任意的外观面板在Button中,带有任意类型的内容。示例7-3使用了一个Grid来排列文本和一些椭圆在Button中。结果如图7-3所示。

示例7-3





<Button HorizontalAlignment="Center" VerticalAlignment="Center">

<Grid>

<Grid.ColumnDefinitions>

<ColumnDefinition />

<ColumnDefinition />

<ColumnDefinition />

</Grid.ColumnDefinitions>

<Grid.RowDefinitions>

<RowDefinition />

<RowDefinition />

<RowDefinition />

</Grid.RowDefinitions>

<Ellipse Grid.Column="0" Grid.Row="0" Fill="Blue" Width="10" Height="10" />

<Ellipse Grid.Column="2" Grid.Row="0" Fill="Blue" Width="10" Height="10" />

<Ellipse Grid.Column="0" Grid.Row="2" Fill="Blue" Width="10" Height="10" />

<Ellipse Grid.Column="2" Grid.Row="2" Fill="Blue" Width="10" Height="10" />

<Ellipse Grid.ColumnSpan="3" Grid.RowSpan="3" Stroke="LightGreen"

StrokeThickness="3" />

<TextBlock Grid.Column="1" Grid.Row="1" VerticalAlignment="Center">Click!</

TextBlock>

</Grid>

</Button>
图7-3

<Window x:Class="ChangeItem.MainWindow"

xmlns="http://schemas.microsoft.com/winfx/avalon/2005"

xmlns:x="http://schemas.microsoft.com/winfx/xaml/2005"

Text="Change Item"

>

<Canvas>

<Ellipse Canvas.Left="10" Canvas.Top="30" Fill="Indigo"

Width="40" Height="20" MouseLeftButtonDown="OnClick" />

<Ellipse Canvas.Left="20" Canvas.Top="40" Fill="Blue"

Width="40" Height="20" MouseLeftButtonDown="OnClick" />

<Ellipse Canvas.Left="30" Canvas.Top="50" Fill="Cyan"

Width="40" Height="20" MouseLeftButtonDown="OnClick" />

<Ellipse Canvas.Left="40" Canvas.Top="60" Fill="LightGreen"

Width="40" Height="20" MouseLeftButtonDown="OnClick" />

<Ellipse Canvas.Left="50" Canvas.Top="70" Fill="Yellow"

Width="40" Height="20" MouseLeftButtonDown="OnClick" />

</Canvas>

</Window>

每个椭圆的MouseLeftButtonDown事件都由定义在该窗体对应后台文件的OnClick方法处理。如示例7-5所示,OnClick方法简单的增加了Width属性——当Ellipse激发这个事件的时候。点击的结果使这个椭圆更加宽了。

[b]示例7-5



using System.Windows;

using System.Windows.Shapes;

namespace ChangeItem

<Button LayoutTransform=”scale 3 3”>
LayoutTransform属性在WPF所有的用户接口元素中是有效的,因此你可以伸缩整个窗体如同一个按钮一样简单。多种类型的变形是可以利用的,这将在后面更详细的讨论。目前,我们简单地要求扩大一个按钮——通过x和y方向上的因数3。图7-6显示了扩大后地按钮。

图7-6





比较原始的图7-2和图7-6,后者比前者更明显,正如你所希望的。更加意味深长地,细节变得更零碎了。按钮的圆角边缘比它们在一个较小的版本中更加容易看到。后者的形状定义得更好。而且我们的图形更加清晰。我们获取这种清晰度是因为WPF生成的按钮看上去和详细指明大小的按钮一样好。比较图7-6和图7-7中的示例。

图7-7





图7-7显示了发生了什么——如果你简单的扩大原始的小按钮的图像。有很多种扩大图像的不同方式。左边的示例使用了简单的算法,称为“”,有时又称为“”。为了是这张图片更大一些,象素被简单的重复了。这导致了对这张图像一种很方正的感觉。右边的示例使用了一种比较高级的插值算法。这使得圆角看起来是圆的,同时不会遭受矮矮胖胖的象素效果,而这会导致看起来很模糊。清晰,两个图像中没有一个可以达到图7-6的效果。

7.1.2分辨率,坐标系统,和“象素”

对伸缩图形的支持,意味着在你的应用程序中使用的坐标系统和屏幕使用的坐标系统间没有固定的关联。如果运行在一台高DPI的显示器上,即使你不用伸缩变形,变形会自动应用到你整个的应用程序上——这是真实的。

在WPF中,如果不是物理性象素,那么默认的度量单位又是什么呢?答案是,有点混淆,象素。为了更加精确,真实的答案是,独立于装置的象素。

独立于装置的象素,WPF官方的定义是1/96每象素。如果你详细指出一个形状的宽度为96px,就意味着这是1英寸宽。WPF会使用与所需同样多的物理象素来填充一英寸,例如,高分辨率的膝上型显示器,分辨率达到150px/I。因此如果你绘制一个宽为96px的象素,WPF将生成150px/I的宽度。

WPF依赖于系统级显示器设置,来决定物理象素的大小。你可以通过Windows Display Properties程序来调整它们。右击“桌面”,选择“属性”来显示这个程序,进下来进入到“设置”条。点击“高级”按钮,在打开的对话框中,选择“通用”条,这将告诉Windows你的显示器分辨率。

你可能想知道为什么WPF使用有点奇怪的选择1/96英寸,以及为什么叫“pixel”。原因是,96dpi是Windows中默认的DPI——当运行时使用正常的字体,因此长期考虑pixel正常的大小。这意味着在带有正常象素密度的显示器上,WPF会伸缩你的绘图为了它们保持正确的物理大小。

WPF为每一个伸缩优化图形化样式生成的能力,意味着它能理想的被用于利用增长的显示器分辨率。作为第一次,屏幕上的文字和图形会竞争这些清楚的碎片——我们已经希望来自打印机的。当然,为了所有实际中的工作,我们需要一组全面的绘图基础。

7.1.4形状,笔刷和钢笔

WPF绘图工具中的大多数类被归类为三种类型:形状,笔刷和钢笔。在这些主题上有很多变体,我们将会在后面详细检查它们。然而,为了完全获取任何地方的图形,对这些类一个基本的了解是强制的,

形状是用户界面树中的对象,提供了用于绘图的基本的创建块。我们已经看到的Ellipse、Path和Rectangle元素都是形状对象的例子。同样支持线条——基本线条和多段线条,分别使用Line和PolyLine。还可以创建任意的填充形状。Polygon支持所有边都是直的形状,而一旦你需要弧形的边,Path类支持填充如同弧形一样的形状。图7-8显示了使用中的每一个形状。

图7-8



不管你选择的是什么图形,你需要决定如何对其进行着色。为此,可以使用Brush。有很多可利用的Brush类型,最简单的是单颜色的SolidColorBrush。你可以使用LinearGradientBrush或RadialGradientBrush达到更有趣的可视化效果。这些允许在界面的形状上改变颜色,这是一种很好的办法——提供了很深的印象。你也可以基于图像创建笔刷,ImageBrush使用了一个图片,DrawingBrush使用了一个可伸缩的绘图。最后VisualBrush使你在任何可视化树、任何用户界面中你喜欢和使用的大块上绘制其他的形状。这使得达到想反射你的用户界面的全部的效果很简单。

最后,钢笔用于绘制形状的轮廓。钢笔其实只是一个增强的笔刷。当你创建一个Pen对象的时候,你给了它一个Brush来告诉它应该怎么在屏幕上画画。Pen类只是增加了一些信息如线条的厚度,阴影样式。图7-9显示了一些可用的效果,使用了笔刷和钢笔。

图7-9



7.1.5合成

图形构架的最后一个关键样式是合成。在计算机图形中,名词“合成”是指将多个形状和图片联合在一起形成最后输出的过程。WPF的合成模型是不同于传统Windows工作模型的,对于创建支持高质量可视化,这是至关紧要的。

在经典的Win32模型中,每个用户界面元素都独占它所拥有的应用程序窗体中的某个区域。在每一个顶级窗体中,任何在窗体中给定的象素都完全由那一个确切的元素控制。这就防止了元素是局部透明的。它同样排除了在元素的边缘使用抗锯齿处理,当联合非矩形元素的时候,这个技术是尤其重要的。虽然各种各样的hack已经被分成提供幻想在Win32中的透明度,它们有局限以及可以有点便利的与之工作。

WPF的组合模型支持任何形状的元素以及允许它们交叠。它还允许元素有任意局部或完全的透明化区域的混合。这意味着任何给定的屏幕上的象素都可能有多个有作用的可视化元素。进一步,WPF使用锯齿化处理在所有形状的边缘。这样减少了参差不齐的外观,更简单的绘图技术可以在屏幕上生成,导致一个平滑外观的图像。最后,组合引擎允许任何元素在组合前,将变形应用上去。

WPF的组合引擎使用了现代显卡来加速绘图的过程。在内,这可以在Direct3D模型的顶层实现。这看起来是多余的,因为多半WPF的绘图功能都是二维的,但是大多数面向3维的功能,在现代显卡上,可以还被用于绘制二维形状。例如,象素阴影可以被用于实现高级的ClearType机制,当组合文本到UI中。WPF开发了同样超快的多边形绘图机制——由SD游戏用来生成基本形状。进一步,WPF在显卡上缓存了可视化树的一部分,显著的促进了重绘的性能——当在屏幕上改动小的细节时。

现在让我们看一下支撑WPF图形系统的核心概念,让我们仔细的看一下细节。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: