
本主题概述 WPF 可视化层 本主题重点讲述 WPF 模型中呈现支持的 Visual 类的角色
Visual 对象的角色 Visual 类是每个 FrameworkElement 对象所派生自的基本抽象 该类还充当在 WPF 中编写新控件的入口点 在 Win 应用程序模型中 该类在许多方面可以被视为窗口句柄 (HWND)
Visual 对象是一个核心 WPF 对象 它的主要角色是提供呈现支持 用户界面控件(如 Button 和 TextBox)派生自 Visual 类 并使用该类来保持它们所呈现的数据 Visual 对象为下列功能提供支持
输出显示 呈现 Visual 对象的持久的序列化绘图内容
转换 针对 Visual 对象执行转换
剪辑 为 Visual 对象提供剪辑区域支持
命中测试 确定 Visual 对象的边界内是否包含坐标或几何形状
边界框计算 确定 Visual 对象的边框
但是 Visual 对象不包括对非呈现功能的支持 如 ◆事件处理
◆布局
◆样式
◆数据绑定
◆全球化
Visual 作为子类必须派生自的公共抽象类进行公开 下图显示了 WPF 中所公开的可视化对象的层次结构
Visual 类的层次结构
DrawingVisual 类DrawingVisual 是一个用于呈现形状 图像或文本的轻量绘图类 此类之所以被视为轻量 是因为它不提供布局或事件处理功能 从而能够改善运行时性能 因此 绘图最适于背景和剪贴画 DrawingVisual 可用于创建自定义可视化对象
Viewport DVisual 类Viewport DVisual 在二维 Visual 和 Visual D 对象之间起到桥梁作用 Visual D 类是所有三维可视化元素的基类 Viewport DVisual 要求您定义一个 Camera 值和一个 Viewport 值 可以借助照相机来查看场景 投影映射到二维图面的区域称作视区
ContainerVisual 类ContainerVisual 类用作 Visual 对象集的容器 DrawingVisual 类派生自 ContainerVisual 类 这允许它包含可视化对象的集合
可视化对象中的绘图内容Visual 对象将它的呈现数据另存为向量图形指令列表 指令列表中的每一项都以序列化格式表示一组低级别的图形数据及其相关资源 共有四种不同类型的呈现数据可以包含绘图内容
通过 DrawingContext 您可用可视化内容填充 Visual 当您使用 DrawingContext 对象的绘图命令时 实际上是存储一组日后将由图形系统使用的呈现数据 而不是实时绘制到屏幕上
当您创建 WPF 控件(如 Button)时 该控件会为绘图对象本身隐式生成呈现数据 例如 设置 Button 的 Content 属性会导致该控件存储标志符号的呈现表示
Visual 将其内容描述为一个或多个包含在 DrawingGroup 中的 Drawing 对象 DrawingGroup 还描述不透明蒙板 转换 位图效果和应用于其内容的其他 *** 作 呈现内容时 DrawingGroup *** 作按如下顺序应用 OpacityMask Opacity BitmapEffect ClipGeometry GuidelineSet 和 Transform
下图显示了在呈现过程中 DrawingGroup *** 作的应用顺序
DrawingGroup *** 作的顺序
在可视化层绘制内容绝不能直接实例化 DrawingContext 但可以通过某些方法
(例如 DrawingGroup :: Open 和 DrawingVisual :: RenderOpen)获取绘图上下文 下面的示例从 DrawingVisual 中检索 DrawingContext 并将其用于绘制矩形
在可视化层枚举绘图内容此外 Drawing 对象还可提供用来枚举 Visual 内容的对象模型
说明 您在枚举可视化层的内容时 就是相当于在检索 Drawing 对象 而不是以向量图形指令列表形式检索呈现数据的基础表示 下面的示例使用 GetDrawing 方法来检索 Visual 的 DrawingGroup 值并枚举该值
如何使用可视化对象来生成控件 WPF 中的许多对象都由其他可视化对象组成 这意味着它们可以包含子代对象的各种层次结构 WPF 中的许多用户界面元素(如控件)都由多个表示不同类型呈现元素的可视化对象组成 例如 Button 控件可以包含许多其他对象 其中包括 ClassicBorderDecorator ContentPresenter 和 TextBlock
下面的代码显示的是在标记中定义的 Button 控件
如果您要枚举包含默认 Button 控件的可视化对象 则将发现如下所示的可视化对象层次结构
可视化树层次结构的关系图
Button 控件包含一个 ClassicBorderDecorator 元素 该元素又包含一个 ContentPresenter 元素 ClassicBorderDecorator 元素负责为 Button 绘制边框和背景 ContentPresenter 元素负责显示 Button 的内容 在本例中 由于您要显示文本 因此 ContentPresenter 元素中包含一个 TextBlock 元素 Button 控件使用 ContentPresenter 这意味着该控件的内容可以由其他元素(如 Image)或几何形状(如 EllipseGeometry)来表示
控件模板将控件扩展为控件层次结构的关键在于 ControlTemplate 控件模板为控件指定默认的可视化层次结构 当您显式引用某个控件时 会隐式引用它的可视化层次结构 您可以重写控件模板的默认值 以便为控件创建自定义的可视化外观 例如 您可以修改 Button 控件的背景颜色值 以便它使用线性渐变颜色值 而不使用纯色值
用户界面元素(如 Button 控件)包含几个向量图形指令列表 这些列表描述控件的全部呈现定义 下面的代码显示的是在标记中定义的 Button 控件
如果您要枚举包含 Button 控件的可视化对象和向量图形指令列表
则将发现如下所示的可视化对象层次结构
可视化树和呈现数据的关系图
Button 控件包含一个 ClassicBorderDecorator 元素 该元素又包含一个 ContentPresenter 元素 ClassicBorderDecorator 元素负责绘制所有构成按钮边框和背景的离散图形元素 ContentPresenter 元素负责显示 Button 的内容 在本例中 由于您要显示图像 因此 ContentPresenter 元素中包含一个 Image 元素
对于可视化对象和向量图形指令列表的层次结构 需要注意多个事项
该层次结构中的排序表示绘图信息的呈现顺序 从可视化元素的根 按照从左到右 从上到下的顺序遍历子元素 如果某个元素有可视化子元素 则会先遍历该元素的子元素 然后再遍历该元素的同级
层次结构中的非叶节点元素(如 ContentPresenter)用于包含子元素 它们并不包含指令列表
如果可视化元素既包含向量图形指令列表又包含可视化子级 则会先呈现父级可视化元素中的指令列表 然后再呈现任何可视化子对象中的绘图
向量图形指令列表中的项按照从左到右的顺序呈现
可视化树 可视化树中包含某个应用程序的用户界面所使用的所有可视化元素 由于可视化元素中包含持久的绘图信息 因此您可以将可视化树视为场景图 其中包含将输出写入显示设备所必需的全部呈现信息 该树汇集了由该应用程序在代码或标记中直接创建的所有可视化元素 该可视化树还包含由元素(如控件和数据对象)的模板扩展功能创建的所有可视化元素
下面的代码显示的是在标记中定义的 StackPanel 元素
如果您要枚举包含标记示例中 StackPanel 元素的可视化对象 将发现如下所示可视化对象的层次结构
可视化树层次结构的关系图
呈现顺序通过可视化树 可以确定 WPF 可视化对象和绘图对象的呈现顺序 将从位于可视化树中最顶层节点中的可视化元素根开始遍历 然后将按照从左到右的顺序遍历可视化元素根的子级 如果某个可视化元素有子级 则将先遍历该可视化元素的子级 然后再遍历其同级 这意味着子可视化元素的内容先于该可视化元素本身的内容而呈现
可视化树呈现顺序的关系图
可视化元素根可视化元素根是可视化树层次结构中最顶层的元素 在大多数应用程序中 可视化元素根的基类是 Window 或 NavigationWindow 但是 如果您在 Win 应用程序中承载可视化对象 则可视化元素根将是在 Win 窗口中承载的最顶层的可视化元素
与逻辑树的关系WPF 中的逻辑树表示应用程序在运行时的元素 尽管您不直接 *** 作该树 但是该应用程序视图对于了解属性继承和事件路由非常有用 与可视化树不同 逻辑树可以表示非可视化数据对象(如 ListItem) 在许多情况下 逻辑树密切映射到应用程序的标记定义 下面的代码显示的是在标记中定义的 DockPanel 元素
如果您要枚举包含标记示例中 DockPanel 元素的逻辑对象 则将发现如下所示逻辑对象的层次结构
逻辑树的关系图
可视化树和逻辑树与当前的应用程序元素集合同步 并反映对元素进行的任何添加 删除或修改 但是 这些树表示不同的应用程序视图 与可视化树不同 逻辑树不展开控件的 ContentPresenter 元素 这意味着同一组对象的逻辑树和可视化树之间没有直接的一对一对应关系 实际上 在将同一个元素用作参数的情况下 调用 LogicalTreeHelper 对象的 GetChildren 方法与调用 VisualTreeHelper 对象的 GetChild 方法会生成不同的结果
使用 XamlPad 查看可视化树WPF 工具 (XamlPad) 提供了一个用来查看和浏览可视化树的选项 该树与当前所定义的 XAML 内容相对应 单击菜单栏上的 显示可视化树 [Show Visual Tree]按钮可显示相应的可视化树
下面将说明如何在 XamlPad 的 可视化树资源管理器 [Visual Tree Explorer]面板中将 XAML 内容扩展为可视化树节点
XamlPad 中的 可视化树资源管理器 [Visual Tree Explorer]面板
请注意 Label TextBox 和 Button 控件在 XamlPad 的 可视化树资源管理器 [Visual Tree Explorer]面板中各自显示一个可视化对象层次结构 这是由于 WPF 控件具有一个包含其可视化树的 ControlTemplate 当您显式引用某个控件时 会隐式引用它的可视化层次结构
分析可视化性能WPF 提供了一套性能分析工具 来帮助您分析应用程序的运行时行为 并确定可以应用的性能优化的类型 可视化探查器工具通过直接映射到应用程序的可视化树来为性能数据提供一个丰富的图形视图 在此屏幕快照中 可视化探查器的 CPU Usage [CPU 使用率]部分使您可以清楚地了解对象对 WPF 服务(如呈现和布局)的使用情况
可视化探查器显示输出
可视化对象的呈现行为 WPF 引进了几个影响可视化对象呈现行为的功能 保留的模式图形 矢量图形和与设备无关的图形
保留的模式图形了解即时模式和保留模式图形系统之间的区别是了解 Visual 对象角色的要点之一 基于 GDI 或 GDI+ 的标准 Win 应用程序使用即时模式图形系统 这意味着应用程序负责重新绘制工作区中由于某项 *** 作(如调整窗口大小)或者对象的可视化外观发生变化而失效的部分
Win 呈现顺序的关系图
与之相比 WPF 使用保留模式系统 这意味着具有可视化外观的应用程序对象定义一组序列化绘图数据 在定义了绘图数据之后 系统会响应所有的重新绘制请求来呈现应用程序对象 甚至在运行时 您也可以修改或创建应用程序对象 并仍旧依赖系统响应绘制请求 保留模式图形系统中有一个强大功能 那就是绘图信息总是由应用程序保持为序列化状态 但是呈现功能仍由系统负责 下面的关系图演示应用程序如何依赖 WPF 来响应绘制请求
WPF 呈现顺序的关系图
智能重绘使用保留模型图形的最大好处之一就是 WPF 可以高效率地优化需要在应用程序中重绘的内容 即使您有一个具有各种不透明度的复杂场景 通常也不必编写特殊用途的代码来优化重绘功能 请将智能重绘功能与 Win 编程进行比较 在后者中 可以通过最小化更新区域中的重绘量来尽力优化应用程序
向量图形WPF 使用向量图形作为其呈现数据的格式 向量图形(包括可缩放的向量图形 (SVG) Windows 元文件 ( wmf) 和 TrueType 字体)存储呈现数据 并以指令列表的形式传输该呈现数据 这些指令描述如何使用图形基元来重新创建图像 例如 TrueType 字体是描述一组直线 曲线和命令(而不是像素数组)的矢量字 矢量图形的主要好处之一就是能够伸缩到任何大小和分辨率
与矢量图形不同 位图图形以图像的逐像素表示形式来存储呈现数据 而且在特定的分辨率下预先呈现 位图图形格式和矢量图形格式的主要区别之一就是对原始图像的保真度 例如 当某个源图像的大小发生变化时 位图图形系统会拉伸该图像 而向量图形系统会伸缩该图像 从而保持图像的保真度
下图显示了源图像在放大到 倍时的情况 请注意 当源图像作为位图图形拉伸时会发生失真 而当源图像作为矢量图形伸缩时 则不会发生失真
光栅图形和矢量图形之间的区别
下面的标记显示所定义的两个 Path 元素 第二个元素使用 ScaleTransform 将第一个元素的绘图指令放大到 倍 请注意 Path 元素中的绘图指令保持不变
关于分辨率和与设备无关的图形可通过以下两个系统因子来确定屏幕上的文本大小和图形大小 分辨率和 DPI 分辨率描述出现在屏幕上的像素数量 由于分辨率变大 因此像素会变小 从而导致所显示的图形和文本会变小 在将显示器的分辨率从 x 更改为 x 时 显示器上所显示的图形会小得多
另一个系统设置 (DPI) 以像素数来描述屏幕英寸的大小 大多数 Windows 系统的 DPI 都为 这意味着一屏幕英寸等于 个像素 增加 DPI 设置会使屏幕英寸变大 减小 DPI 会使屏幕英寸变小 这意味着屏幕英寸与实际的英寸不相等 在多数系统上 二者很有可能不相等 当您增加 DPI 时 屏幕英寸会变大 因此支持 DPI 的图形和文本也会变大 增加 DPI 可能会增强文本的可读性 在高分辨率下尤其如此
并非所有的应用程序都支持 DPI 一些应用程序将硬件像素作为其主要计量单位 更改系统 DPI 不会对这些应用程序产生任何影响 许多其他应用程序都使用支持 DPI 的单位来描述字号 使用像素来描述任何其他内容 DPI 太小或太大都可能会导致这些应用程序出现布局问题 因为应用程序的文本会随着系统的 DPI 设置而伸缩 而应用程序的 UI 却不会出现此类问题 对于使用 WPF 开发的应用程序 此问题已经消除
WPF 支持通过将与设备无关的像素(而不是硬件像素)用作其主要计量单位来自动伸缩 图像和文本会适当伸缩 而无需应用程序开发人员执行任何额外的工作 下图显示了 WPF 文本和图形在不同 DPI 设置下的显示方式的示例
不同 DPI 设置下的图形和文本
VisualTreeHelper 类 VisualTreeHelper 类是一个静态帮助器类 它提供了一个要在可视化对象级别编程的低级功能 该类在非常特殊的方案(如开发高性能自定义控件)中非常有用
在大多数情况下 更高级的 WPF 框架对象(如 Canvas 和 TextBlock)提供更大的灵活性且更易于使用
命中测试VisualTreeHelper 类提供了当默认的命中测试支持无法满足您的需要时 针对可视化对象的命中测试方法 可以在 VisualTreeHelper 类中使用 HitTest 方法来确定几何形状或点坐标值是否位于给定对象(如控件或图形元素)的边界内 例如 您可以使用命中测试来确定鼠标在对象边框中的单击点是否落在圆形几何形状内部 您还可以选择重写对命中测试的默认实现来执行自己的自定义命中测试计算
枚举可视化树VisualTreeHelper 类提供了用来枚举可视化树成员的功能 若要检索父级 请调用 GetParent 方法 若要检索可视化对象的子级或直接子代 请调用 GetChild 方法 此方法返回父级在指定索引处的子 Visual
下面的示例演示如何枚举一个可视化对象的所有子代 如果您对序列化可视化对象层次结构的所有呈现信息感兴趣 则可能希望使用该技术
在大多数情况下 逻辑树更能表示 WPF 应用程序中的元素 尽管您不直接修改逻辑树 但是该应用程序视图对于了解属性继承和事件路由非常有用 与可视化树不同 逻辑树可以表示非可视化数据对象(如 ListItem) VisualTreeHelper 类提供用来返回可视化对象边框的方法 可以通过调用 GetContentBounds 来返回可视化对象的边框 可以通过调用 GetDescendantBounds 来返回可视化对象及其所有子代的边框 下面的代码演示如何计算可视化对象及其所有子代的边框
lishixinzhi/Article/program/net/201311/11370
网页可见区域宽:documentbodyclientWidth
网页可见区域高:documentbodyclientHeight
网页可见区域宽:documentbodyoffsetWidth (包括边线和滚动条的宽)
网页可见区域高:documentbodyoffsetHeight(包括边线的宽)
网页正文全文宽:documentbodyscrollWidth
网页正文全文高:documentbodyscrollHeight
网页被卷去的高:documentbodyscrollTop
网页被卷去的左:documentbodyscrollLeft
网页正文部分上:windowscreenTop
网页正文部分左:windowscreenLeft
屏幕分辨率的高:windowscreenheight
屏幕分辨率的宽:windowscreenwidth
屏幕可用工作区高度:windowscreenavailHeight
屏幕可用工作区宽度:windowscreenavailWidth
屏幕设置 windowscreencolorDepth 位彩色
屏幕设置 windowscreendeviceXDPI 像素/英寸
一般都是用js来获取,所以直接在js里面调用就可以获得
将任何房间的角落变成真正有效的家庭办公室
任何在家里度过时间的人都知道拥有一个专门的工作区域,甚至是一个爱好空间会是多么美好。但是,如果您不能将整个房间都专用于家庭办公室,则可以采用一些方法将工作空间放入房子的其他房间中。它可以设置在备用墙角,离墙几英寸的地方,也可以设置在您从未想到的其他未使用的地方。
但是,事后请不要将桌子和椅子放在空的角落。这八个鼓舞人心的想法可以帮助您找到 家庭办公室 的理想场所,并创建一个时尚,实用和刺激的工作区。
80年代Studio Pte Ltd
在客厅中
在开放式多功能空间(例如 客厅)中 集成工作区时,请确保您的办公室空间在外观上或外观上不会突出。使用与空间设计息息相关的家具和装饰,并确保它们不会阻塞人流。一种方法是将沙发移动到房间中央,然后在其后面放一个狭长的桌子。将它与可以完全塞到桌子下面的椅子或凳子配对。您还可以利用可用的资源–搁板,书架,凹陷的区域–您可以在其中安装工作台并放入元件(灯或椅子),这些元件也可以在完成工作后用于其他目的。
在这间公寓中, 80年代工作室的 室内设计师Jann Low 建了一个半高的混凝土墙来划定学习区域,并在桌子上放了两个吊灯。这样,舒适的书房就与居住区在物理上是分开的,但是由于它散发出着相同的原始工业风格,因此在视觉上与周围环境保持联系。
卡姆建筑
在厨房中
,备用厨房角可转换为双重工作区。您可以做一些工作,同时注意晚餐在炉子上着的时间,或孩子做作业时的时间。将您的办公桌放在长柜台的末端或食品储藏室旁边的空角处,以使其靠近但不太靠近 *** 作台。这个厨房厨房的一端有一个很大的死角,可以安静地摆弄钞票或学习。
在设计方面,请为您的工作空间使用相同的橱柜颜色和台面材料,以使其与厨房的其余部分无缝融合。使用用于打印机,其他办公用品和文件的抽拉式搁板和抽屉,保持混乱,并节省一些工作台面。画一面黑板墙,使您的厨房工作区也可以用作家人的中央信息中心。
考古学
在步入式衣橱中
如果您不需要的只是写字台,计算机和一些架子空间,那么步入式衣橱中未使用的角落肯定可以满足您的需求。将壁橱的末端专用于打开的书架或书架,书架,文件夹和文件。
自然光洒入了由 Architology 设计的步入式衣橱,因此,适合将工作桌放在窗户旁边。为了与其余空间融为一体,内置书桌与壁柜门的层压板表面相同。人体工学椅子和柔软的地毯增加了舒适感。设有滑门可将卧室的步入式衣柜关闭,为无干扰的家庭办公室腾出空间。
Lynne Scalo设计
在卧室里
另一个选择是 在卧室里 创建一种“现在就看到你现在就不知道”的办公室设置。将您的办公桌和书架放在空的壁橱中,并悬挂全长窗帘,这样在不使用时就可以隐藏整个工作区。确保对办公室区域进行装饰,使其与卧室的其余部分保持协调,从而即使将窗帘绑起来也看起来不错。
休·杰斐逊·伦道夫建筑师
楼梯下楼梯下
那笨拙且经常被忽视的空间对于紧凑型工作站可能是个好地方。围绕可用空间布置浮动式架子和内置桌子,以最大程度地减小占地面积。用鲜艳的色彩(例如阳光明媚的**或清新的草地绿色)绘画墙壁可以给空间增加一些冲击力,并激发创意。如果您希望保持整体中性色调,则可以使用个性化椅子,软木墙或醒目的艺术品来提升您的楼梯下风格。
设计干预
在客房中将
不经常使用的客房兼作家庭办公室是很有意义的。由于几乎不使用床,请考虑将其塞在墙上以充分利用空间。无论是大小还是功能,这是此房间的理想之选,是沙发床,您还可以在其中度过安静的时间,或者将墨菲床折叠起来,放到墙壁上。即使房间是两用房,它也应该在外观和感觉上和谐统一–有利于工作,但对下榻的客人却很舒适。中性色调可以作为整体基础,但不要害怕通过配饰或个人纪念品与色彩搭配,赋予房间一些个性。
在这个房间里,由 Design Intervention 进行研究 大型条纹地毯有效地定义了工作区域。床被塞入角落,为工作空间留出足够的腿部空间。设计师Nikki Hunt说:“大号床已被L型床头板和丰富的靠垫包裹着,将其伪装成温馨的沙发床,非常适合一本好书。墙纸的书架图案也很好地捕捉了房间的轻松氛围。
白金大厦集团
沿着走廊
,通过在长的空墙的延伸部分上放置内置桌子,可以使通过空间更加有用。这是一个实用的设置,可以容纳更多的家庭成员。高架存储至关重要。您可以使用内置式橱柜或安装长架子,以防止空间混乱。请注意,桌子不要太深,椅子可以完全塞在下面,以保持通畅的走道。
任何未被充分利用的角落
您还可以在起居室/餐厅,楼梯平台附近,您的卧室或窗户旁边设置商店–任何未被充分利用的角落都有可能被转变为功能性办公空间。如该设计所示,将工作区封闭在玻璃中是保持隐私感并防止在狭窄空间内感到局促的好方法。使用浮动搁板而不是扩展得很宽,也可以最大程度地利用紧凑的空间。
将您的家庭办公室封闭起来或放在普通视野中实际上是个人喜好问题。重要的是平衡功能和样式。
告诉
我们您在家庭的哪一部分设置了家庭办公室?您如何最大化空间?
一个好的Web应用程序将调整Blockly的大小以填充屏幕上的可用空间,而不是固定大小。有几种方法可以做到这一点,包括使用iframe,CSS和JavaScript定位。此页面演示了一种强大而灵活的叠加方法。
这是一个三步过程。第一步是定义区域。第二步是注入Blockly。第三步是将Blockly定位在这个区域上。
使用HTML表格或带有CSS的div,创建一个空白区域,在页面调整大小时重新流动。确保该区域有ID(在此页面上我们将其称为blocklyArea)。
这是一个填充屏幕底部的表格单元格的 现场演示 。
注入Blockly与注入固定大小的Blockly中描述的过程相同。添加脚本,blocklyDiv元素,工具箱和注入脚本。
Blockly现在应该在页面上运行,而不是位于它应该位于的位置(可能在屏幕外)。
最后一步是将blocklyDiv元素放在blocklyArea元素上。为此,从blocklyDiv中删除任何高度和宽度样式并添加绝对定位:
然后将注入脚本替换为将'blocklyDiv'置于'blocklyArea'上的脚本:
这是Blockly的 现场演示 ,它填满了屏幕的底部。
以上就是关于WPF的图形呈现全部的内容,包括:WPF的图形呈现、用c# 怎样实现 获取 PDA 的 分辨率 大小、扩大工作区空间的8种方法等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)