WPF编程宝典 - 17控件模板
理解逻辑树和可视化树
下图显示了一个非常简单的窗口,该窗口包含两个按钮。为创建该窗口,在窗口中嵌套了一个StackPanel控件。在StackPaenl控件中,放置了两个Button控件,并且在每个按钮中可以添加所选择的内容
1234<StackPanel Margin="5"> <Button Margin="5" Padding="5">First Button</Button> <Button Margin="5" Padding="5">Second Button</Button></StackPanel>
添加的元素分类成为逻辑树,下图显示了逻辑树。WPF编程人员需要耗费大部分时间构建逻辑树,然后使用事件处理代码支持它们。实际上,到目前为止介绍的所有WPF特性(如属性值继承、事件路由以及样式)都是通过逻辑树进行工作的。
简单窗口的逻辑树
然而,如果希望自定义元素,逻辑树起不到多大 ...
WPF编程宝典 - 16高级动画
动画类型回顾
创建动画面临的第一个挑战是为动画选择正确的属性。期望的结果(例如,在窗口中移动元素)于需要使用的属性(在这种情况下是Canvas.Left和Canvas.Top属性)之间的关系并不总是很直观。西面是一些知道原则:
如果希望使用动画来使元素显示和消失,不要使用 Visibility 属性(该属性只能在完全可见和完全不可见之间进行切换)。应改用 Opacity 属性淡入或淡出元素。
如果希望动态改变元素的位置,可考虑使用Canvas面板。它提供了最直接的属性(Canvas.Left 及 Canvas.Top),而且开销最小。此外,也可使用动画属性在其他布局容器中获得类似效果。例如,可通过使用 ThicknessAnimation 类动态改变 Margin 和 Padding 等属性,还可动态改变 Grid 控件中的 MinWidth 或 MinHeight 属性、一列或一行。
**动画最常用的属性是渲染变换。**可使用变换移动或翻转元素(TranslateTransform)、旋转元素(RotateTransform)、缩放或扭曲元素(ScaleTransform)等。 ...
WPF编程宝典 - 15动画基础
理解WPF动画
在许多用户框架中(特别是 WPF 之前的框架,如 Windows窗体和 MFC),开发人员必须从头构建自己的动画系统。最常用的技术是结合使用计时器和一些自定义的绘图逻辑。WPF通过自带的基于属性的动画系统,改变了这种状况。接下来的两节将描述这两者之间的区别。
基于时间的动画
加入需要旋转Windows窗体应用程序中的About对话框中的一块文本。下面是构建解决方案的传统的方法:
创建周期性触发的计时器(例如,每隔50毫秒触发一次)
当触发计时器时,使用事件处理程序计算一些与动画相关的细节,如新的旋转角度。然后使窗口的一部分或者整个窗口无效
不久后,Windows将要求窗口重新绘制自身,触发自定义的绘图代码
在自定义的绘图代码中,渲染旋转后的文本
尽管这个基于计时器的解决方案不难实现,但将它集成到普通的应用程序窗口中却非常麻烦。下面列出这种解决方案存在的一些问题:
绘制像素而不是控件。为旋转Windows窗体中的文本,需要低级的GDI+绘图支持。GDI+易于使用,但却不能与普通的窗口元素(如按钮、文本框和标签等)很好地相互协调。所以,需要将动画内容和控件 ...
WPF编程宝典 - 14效果和可视化对象
通常,当基本性能成为问题或需要访问单个像素时,将使用这些低级功能。
可视化对象(Visual):如果希望构建用于绘制矢量图形的程序,或计划创建包含数千个形状并可以分别操作这些形状的画布,那么使用WPF的元素系统和形状类会使速度过慢,不能满足要求。相反,需要更简洁的方法,使用低级的Visual类手动进行执行渲染
效果(Effect):如果希望为元素应用复杂的可视化效果(如模糊和颜色调整),最简便的方法是使用像素着色器(pixel shader)这个专用工具修改单个像素。为提高性能,像素着色器是硬件加速的,并且有许多已经制作好的效果,您付出很少的努力就可以将这些效果应用到自己的应用程序中
WriteableBitmap:虽然需要做很多工作,但通过 WriteableBitmap 类可以完全拥有幅位图–这意味着可以设置并检査位图的任何像素。对于复杂的数据可视化情形(例如当图形化科学计算数据时)可以使用该特性,也可以使用该特性从头开始实现一个赏心悦目的效果。
可视化对象
通过使用几何图形、图画和路径,可以降低2D图形的开销,即使正在使用复杂的具有分层效果的组合形状和渐变画刷,这种方 ...
WPF编程宝典 - 13几何图形和图画
路径和几何图形
Path类能够包含任何简单形状、多组形状以及更复杂的要素,如曲线。Path类提供了Data属性,该属性接受一个Geometry对象,该对象定义路径包含的一个活多个图形。不能直接创建Geometry对象,因为Geometry时抽象类,而是需要使用下表的7可派生类中的一个进行创建。
几何图形类
名称
说明
LineGeometry
代表直线,该几何图形相当于Line形状
RectangleGeometry
代表矩形(可以具有圆形拐角),该几何图形相当于Rectangle形状
EllipseGeometry
代表椭圆,该图形相当于Ellipse形状
GeometryGroup
为单个路径添加任意多个Geometry对象,使用EvenOdd活NonZero填充规则来确定要填充的区域
CombinedGeometry
将两个几何图形合并为一个形状。可使用CombineMode属性选择如何组合两个几何图形
PathGeometry
代表更复杂的由弧线、曲线以及直线构成的图形,并且既可以时闭合的,也可以不是闭合的
StreamGeometry ...
WPF编程宝典 - 12形状、画刷和变换
理解形状
在WPF用户界面中,绘制2D图形内容的最简单方法时使用形状(Shape)——专门用于表示简单的直线、椭圆、矩形以及多边形的一些类。从技术角度看,形状就是所谓的绘图图元(Primitive)。可组合这些基本元素来创建更复杂的图形
关于 WPF 中形状的最重要细节是,它们都继承自FrameworkElement类。因此,形状是元素。这样会带来许多重要的结果:
形状绘制自身:不需要管理无效的情况和绘图过程。例如,当移动内容、改变窗口尺寸或改变形状属性时,不需要手动重新绘制形状。
使用与其他元素相同的方式组织形状:换句话说,可在任何布局容器中放置形状(尽管 Canvas 明显是最有用的容器,因为它允许在特定的坐标位置放置形状,当构建复杂的具有多个部分的图画时,这很重要)。
形状支持与其他元素相同的事件:这意味着为了处理焦点、按下键盘、移动鼠标以及单击鼠标等,不必执行任何额外工作。可使用用于其他元素的相同事件集,并同样支持工具提示、上下文菜单和拖放操作。
Shape类
每个形状都继承自抽象类System.Windows.Shapes.Shape。下图显示了形状类的继承层 ...
WPF编程宝典 - 11样式和行为
样式(style)时组织和重用格式化选项的重要工具。不是使用重复的标记填充XAML,以便设置外边距、内边距、颜色以及字体等细节,而是创建一系列封装所有这些细节的样式,然后在需要之处通过属性来应用样式
行为(behavior)时一款重用用户界面代码的更有挑战性的工具。其基本思想时:使用行为封装一些通用的UI功能(例如,使元素可被拖动的代码)。如果具有适当的行为,可使用一两行XAML标记将其附加到任意元素,从而节省编写和调试代码的工作。
样式基础
样式是可应用于元素的属性值集合。WPF 样式系统与 HTML标记中的层叠样式表(CascadingStyle Sheet,CSS)标准担当类似的角色。与 CSS 类似,通过 WPF 样式可定义通用的格式化特性集合,并且为了保证一致性,在整个应用程序中应用它们。与CSS样,WPF样式也能够自动工作,指定具体的元素类型为目标,并通过元素树层叠起来。然而,WPF样式的功能更加强大,因为它们能够设置任何依赖项属性。这意味着可以使用它们标准化未格式化的特性,如控件的行为。WPF样式也支持触发器(trigger),当属性发生变化时,可通过触发器改 ...
WPF编程宝典 - 10资源
资源基础
WPF允许在代码中以及在标记中的各个位置定义资源(和特定的控件、窗口一起定一,或在整个应用程序中定义)。资源具有很多重要的优点,如下所述:
高效:可以通过资源定义对象,并在标记中的多个地方使用。这会精简代码,使其更高效
可维护性:可通过资源使用低级的格式化细节(如字号),并将它们移到便于对其进行修改的中央位置。在XAML中创建资源相当于在代码中创建常量。
适应性:一旦特定信息与应用程序的其他部分分离开来,并放置到资源部分中,就可以动态地修改这些信息。例如,可能希望根据用户的个人喜好或当前语言修改资源的细节。
资源集合
每个元素都有Resources属性,该属性存储了一个资源字典集合(它是ResourceDIctionary类的示例)。资源集合可包含任意类型的对象,并根据字符串编写索引。
尽管每个元素都提供了 Resources 属性(该属性作为 FrameworkElement 类的一部分定义),但通常在窗口级别定义资源。这是因为每个元素都可以访问各自资源集合中的资源,也可以访问所有父元素的资源集合中的资源。
12345678<Window.Resour ...
WPF编程宝典 - 09命令
理解命令
所谓的命令——并将控件连接到命令,从而不需要重复编写事件处理代码。更重要的是,当连接的命令不可用时,命令特性通过自动禁用控件来管理用户界面的状态。命令模型还为存储和本地化命令的文本标题提供了一个中心场所。
将事件映射到命令
虽然WPF命令系统是一款简化应用程序设计的优秀工具,但仍有一些很重要的问题没有解决。特别是,WPF 对以下方面没有提供任何支持:
命令跟踪(例如,保留最近命令的历史)
“可撤销的”命令
具有状态并可处于不同“模式”的命令(例如,可被打开或关闭的命令)
命令模型
WPF命令模型由许多可变的部分组成。总之,它们具有如下4个重要元素:
命令:命令表示应用程序任务,并且跟踪任务是否能够被执行,然而,命令实际上不包含执行应用程序任务的代码。
命令绑定:每个命令绑定针对用户界面的具体区域,将命令连接到相关的应用程序逻辑。这种分解的设计是非常重要的,因为单个命令可用于应用程序中的多个地方,并且在每个地方具有不同的意义。为处理这一问题,需要将同一命令与不同的命令绑定。
命令源:命令源触发命令。例如,MenuItem和Button都是命令元。单击它们都会 ...
WPF编程宝典 - 08元素绑定
将元素绑定到一起
数据绑定的最简单情形是,源对象是WPF元素而且源属性是依赖属性。
绑定表达式
数据绑定表达式使用XMAL标记扩展(因此具有花括号)。因为正在创建System.Windows.DataBinding类的一个实例,所以绑定表达式以单词Binding开头。尽管可采用多种方式破诶只Binding对象,但本示例只需要设置两个属性:ElementName属性(指示源元素)和Path属性(指示源元素中的属性)
1234<StackPanel> <Slider x:Name="silder" Minimum="10" Maximum="100"/> <TextBlock FontSize="{Binding ElementName=silder,Path=Value}" Text="Simple Text"/></StackPanel>
之所以使用名称Path而不是Property,是因为Path ...