WPF编程宝典 - 23窗口
Window类
Window类继承自ContentControl类。这意味着它只能包含单个子元素(通常是一个布局容器,如Grid控件),并且可使用由Background属性设置的画刷绘制背景。还可以使用BorderBrush和BorderThickness属性在窗口周围添加边框,当该边框会被添加到窗口框架之内(在客户区边缘周围)。可通过将WindowStyle属性设置为None,完全移除窗口框架,从而创建一个可完全定制的窗口。
客户区是窗口边界内部的表面,在其中可放置自定义内容。非客户区包括边框和窗口顶部的标题栏。非客户区由操作系统管理。
Window类的基本属性
名称
说明
AllowsTransparency
如果设置为 tue,而且如果背景被设置为透明色,Window类就允许其他窗口透过该窗口显示。如果设置为flse(默认值),窗口背后的内容就永远不能显示,并且透明的背景被呈现为黑色背景。当与 WindowStyle属性结合使用,并把 WindowSytle属性设置为 None时,可创建形状不规则的窗口
Icon
确定希望用于窗口的图标的 IageSour ...
WPF编程宝典 - 22列表、树和网格
得益于样式、数据模板以及控件模板提供的扩展功能,即使ListBox 控件(以及类似的ComboBox 控件)也可成为以各种方式显示数据的强大工具。然而,某些类型的数据表示形式只凭ListBox控件很难实现。幸运的是,WPE还提供了几个填补这一空白的富数据控件,包括以下几个控件:
ListView。ListView 继承自简单的没有特色的 ListBox。增加了对基于列显示的支持,并增加了快速切换视图或显示模式的能力,而不需要重新绑定数据以及重新构建列表。
TreeView。TreeView时层次化容器,这意味个创建多层数据显示。例如,可创建在第一级中显示类别组,并在每个类别节点中显示相关产品的TreeView控件。
DataGrid。DataGrid是WPF中功能最完备的数据显示工具。它将数据分割到包含行和列的网格中,就像ListView控件,但DataGrid控件具有其他格式化特性(比如冻结列以及设置单行样式的能力),并且支持就地编辑数据
ListView控件
ListView 类是一个特殊的列表类,它是专门针对显示相同数据的不同视图而设计的。如果需要构建显示每个数据项几 ...
WPF编程宝典 - 21数据视图
View对象
当将集合(或 DataTable)绑定到1temsControl控件时,会不加通告地在后台创建数据视图——位于数据源和绑定的控件之间。**数据视图是进入数据源的窗口,可以跟踪当前项,并且支持各种功能,如排序、过滤以及分组。**这些功能和数据对象本身是相互独立的,这意味着可在窗口的不同部分(或应用程序的不同部分)使用不同的方式绑定相同的数据。例如,可将同一产品集合绑定到两个不同的列表,并对产品进行过滤以显示不同的记录。
使用的视图对象取决于数据对象的类型。所有视图都继承自CollectionView类,并且有两个继承自CollectionView类的特殊实现:ListCollectionView和BeginListCollectionView。下面是CollectionView类的工作原理:
如果数据源实现了IBindingList接口,就会创建BindingListCollectionView视图。当绑定到ADO.NET中的DataTable对象时会创建该视图
如果数据源没有实现IBindingList接口,但实现了IList接口,就会创建ListCollect ...
WPF编程宝典 - 20格式化绑定的数据
数据转换
在基本绑定中,信息在从源到目标的传递过程中没有任何变化。这看起来是符合逻辑的,但我们并不总是希望出现这种行为。通常,数据源使用的是低级表达方式,我们可能不希望直接在用户界面中使用这种低级表达方式。例如,可能希望使用更便于读取的字符串来代替数字编码,数字需要被削减到合适的尺寸,日期需要使用长格式显示等。如果是这样的话,就需要有一种方法将这些数值转换为恰当的显示形式。并且如果正在使用双向绑定,还需要进行反向转换–获取用户提供的数据并将它们转换到适于在恰当的数据对象中保存的表示形式。
幸运的是,WPF提供了两个工具,可提供帮助:
字符串格式化。使用该功能个通过设置Binding.StringFormat属性对文本形式的数据进行转换——例如包含日期和数值的字符串。对于至少一般的格式化任务,字符串格式化是一种便捷的技术
值转换器。该功能更强大(有时更复杂),使用该功能可将任意类型的源数据转换为任意类型的对象表示,然后个传递到关联的控件。
使用StringFormat属性
为格式化需要显示的文本的数字,字符串格式化堪称完美工具。当设置Binding.StringForma ...
WPF编程宝典 - 19数据绑定
提高大列表的性能
如果处理大量数据——例如,数万条记录而不止几百条–您知道良好的数据绑定系统不仅仅需要绑定功能,还需要能够处理超大量的数据而不会严重降低显示速度或消耗大量的内存幸运的是,WPF 优化了其列表控件以为您提供帮助。
所有WOF列表控件(所有继承自ItemsControl的控件)都支持这些增强特性,包括低级的ListBox和ComboBox
虚拟化
WPF列表控件提供的最重要功能是UI虚拟化(UI virtualization),UI虚拟化是列表仅为当前显示项创建容器对象的一种技术。 例如,如果有一个具有50 000条记录的ListrBox控件,但可见区域只能包含30条记录,ListBox控件将只创建30个ListBoxItem对象(为了确保良好的滚动性能,会再增加即可ListBoxItem对象)。如果ListBox控件不支持UI虚拟化,就需要生成全部50 000个ListBoxItem对象,这显然需要占用更多的内存。更有意义的是,分配这些对象需要的时间能够明显感觉到,当代码设置ListBox.ItemsSource属性时这会短暂锁定应用程序。
UI虚拟化支 ...
WPF编程宝典 - 18自定义元素
WPF支持样式、内容控件和模板,因此不再强调自定义控件。这些特性为每位开发人员提供了多种方式来完善和扩展标准的控件,而不用派生新的控件类。下面是几种可能的选择:
样式。可使用样式方便地重用控件属性的组合。甚至可使用触发器应用效果
内容控件。所有继承自ContentControl类的控件都支持嵌套的内容。使用内容控件,可以快速创建聚集其他元素的复合控件
控件模板。所有WPF控件都是无外观的。这意味着它们具有硬编码的功能,但它们的外观是通过控件模板单独定义的。使用其他新的控件模板代替默认模板,可重新构建基本控件
数据模板。所有派生自ItemsControl的类都支持数据模板,通过数据模板可创建某些数据对象类型的富列表示。通过恰当的数据模板,可使用许多元素的组合显示每个项,这些组合元素可以是文本、图像甚至可以是可编辑控件(都在所需的布局容器中)
如果可能的话,在决定创建自定义控件或其他了;诶新的自定义元素之前,可继续使用这些方法。这是因为这些解决方案更简单,更容易实现,并且通常更容易重用
那么,何时应创建自定义元素呢?
当希望微调元素的外观时,自定义元素并非最佳选择,但 ...
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图形的开销,即使正在使用复杂的具有分层效果的组合形状和渐变画刷,这种方 ...