【WPF学习】第九章 使用Canvas面板进行基于坐标的布局

  Canvas面板允许使用精确的坐标放置元素,如果设置数据驱动的富窗体和标准对话框,这并非好的选择;但如果需要构建其他一些不同的内容(例如,为图形工具创建创建绘图表面),Canvas面板可能是个有用的工具。Canvas面板还是最轻量级的布局容器。这是因为Canvas面板没有包含任何复杂的布局逻辑,用以改变其子元素的首选尺寸。Canvas面板只是在指定的位置放置其子元素,并且子元素具有所希望的精确尺寸。

  为在Canvas面板中定位元素,需要设置Canvas.Left和Canvas.Top附加属性。Canvas.Left属性设置元素左边和Canvas面板左边之间的单位数。Canvas.Top属性设置子元素顶部和Canvas面板顶边之间的单位数。同样,这些数值也是以设备无关单位设置的。当将系统DPI设置为96dpi时,设备无关单位恰好等于通常的像素。

  可使用Width和Height属性明确设置子元素的尺寸。与使用其他面板相比,使用Canvas面板时这种设置更普遍,因为Canvas面板没有自己的布局逻辑(并且当需要精确控制组合元素如何排列时,经常会使用Canvas面板)。如果没有设置Width和Height属性,元素会获取它所期望的尺寸——换句话说,它将变得足够大以适应其内容。

  下面是一个使用Canvas的示例:

<Window x:Class="CanvasLayout.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Canvas>
        <Button Canvas.Left="10" Canvas.Top="10">(10,10)</Button>
        <Button Canvas.Left="120" Canvas.Top="30">(120,30)</Button>
        <Button Canvas.Left="60" Canvas.Top="80" Width="80" Height="60">(60,80)</Button>
        <Button Canvas.Left="180" Canvas.Top="150" Width="100" Height="60">(180,150)</Button>
    </Canvas>
</Window>

  最终效果如下图所示:

  如果改变窗口的大小,Canvas面板就会拉伸以填满可用空间,但Canvas面板上的控件不会改变其尺寸和位置。Canvas面板不包含任何锚定和停靠功能,这两个功能是在Windows窗体中使用坐标布局提供的。造成该问题的部分原因是为了保持Canvas面板的轻量级,另一个原因是为了防止以不当目的使用Canvas面板(例如,确定标准用户界面的布局)。

  与其他所有布局容器一样,可在用户界面中嵌套Canvas面板。这意味着可使用Canvas面板在窗口的一部分绘制一些细节内容,而在窗口的其余部分使用更合乎标准的WPF面板。

一、Z顺序

  如果Canvas面板中有多个互相重叠的元素,可通过设置Canvas.ZIndex附加属性来控制他们的层叠方式。

  添加的所有元素通常都具有相同的ZIndex指——0。如果元素具有相同的ZIndex值,就按他们在Canvas.Children集合中的顺序进行显示,这个顺序依赖于元素在XAML标记中定义的顺序。在标记靠后位置声明的元素会显示在前面声明的元素的上面。

  然而,可通过增加任何子元素的ZIndex值来提高层次级别。因为具有更高ZIndex值的元素始终显示在较低ZIndex值得元素的上面。如下代码所示:

<Window x:Class="CanvasLayout.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Canvas>
        <Button Canvas.Left="10" Canvas.Top="10">(10,10)</Button>
        <Button Canvas.Left="120" Canvas.Top="30">(120,30)</Button>
        <Button Canvas.Left="180" Canvas.Top="110" Canvas.ZIndex="1"  Width="80" Height="60">(180,110)</Button>
        <Button Canvas.Left="180" Canvas.Top="150" Width="100" Height="60">(180,150)</Button>
    </Canvas>
</Window>

  效果如下图所示:

  如果需要通过代码来改变元素的位置,ZIndex属性是非常有用的。只需要调用Canvas.SetZIndex()方法,并传递希望修改的元素和希望使用的新ZIndex值即可。遗憾的是,并不存在BringToFront()或SendToBack()方法——要实现这一行为,需要跟踪最高和最低的ZIndex值。

二、InkCanvas元素

  WPF还提供了InkCanvas元素,它与Canvas面板在某些方法是类似的(而在其他方面却完全不同)。和Canvas面板一样,InkCanvas元素定义了4个附加属性(Top、Left、Bottom和Right),可将这4个附加属性应用于子元素,以根据坐标进行定位。然而,基本的内容区别很大——实际上,InkCanvas类不是派生自Canvas类,甚至也不是派生自Panel基类,而是直接派生自FrameworkElement类。

  InkCanvas元素的主要目的用于接收手写笔输入。手写笔是一种在平板PC中使用的类似钢笔的输入设备,然而,InkCanvas元素同事也可使用鼠标进行工作,就像使用手写笔一样。因此,用户可使用鼠标在InkCanvas元素上绘制线条,或者选择以及操作InkCanvas中的元素。

  InkCanvas元素实际上包含两个子内容集合。一个是为人熟知的Children集合,它保存任意元素,就像Canvas面板一样。每个子元素可根据Top、Left、Bottom和Right属性进行定位。另一个是Strokes结合,它保存System.Windows.Ink.Stroke对象,该对象表示用户在InkCanvas元素上绘制的图形输入。用户绘制的每条直线或曲线都变成独立的Stroke对象。得益于这两个集合,可使用InkCanvas让用户使用存储在Strokes集合中的笔画(Stroke)为保存在Children集合中的内容添加注释。

  下面的这个示例中包含一副图片的InkCanvas元素,这幅图片已经使用附加的笔画注释过。

<Window x:Class="CanvasLayout.InkCanvasWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="InkCanvasWindow" Height="300" Width="385.714">
    <InkCanvas Name="inkCanvas" Background="LightYellow" EditingMode="Ink">
        <Image Source="背景.jpg" Width="300" Height="240"  Stretch="Fill" InkCanvas.Top="10" InkCanvas.Left="10"></Image>
    </InkCanvas>
</Window>

  效果图如下所示:

  笔画是在用户在运行时绘制的。

  根据为InkCanvas.EditingMode属性设置的值,可以采用截然不同的方式使用InkCanvas元素,下表列出了所有选项:

     名       称       说  明
Ink InkCanvas元素允许用户绘制批注,这是默认模式。当用户用鼠标或手写笔绘图时,会绘制笔画。
GestureOnly InkCanvas元素不允许用户绘制笔画批注,但会关注预先定义的特定姿势(例如在某个方向拖动手写笔或涂画内容)。能识别的姿势的完整列表由System.Windows.Ink.ApplicationGesture枚举给出。
InkAndGesture InkCanvas元素允许用户绘制笔画批注,也可以识别预先定义的姿势。
EraseByStroke 用单击笔画时,InkCanvas元素会擦除笔画。如果用户使用手写笔,可使用手写笔的底端切换到该模(可使用只读的ActiveEditingMode属性确定当前编辑模式,也可通过改变EditingModeInverted属性来改变手写笔的底端使用的工作模式)
EraseByPoint 当单击笔画时,InkCanvas元素会擦除笔画中呗单击的部分(笔画上的一个点)
Select InkCanvas面板允许用户选择保存在Childeren集合中的元素。要选择一个元素,用户必须单击该元素或拖动"套索"选择该元素。一旦选择一个元素,就可以移动该元素、改变其尺寸或将其删除
None InkCanvas元素忽略鼠标和手写笔输入

  InkCanvas元素会引发多种事件,当编辑模式改变时会引发ActiveEditingModeChanged事件,在GestureOnly或InkAndGesture模式下删除姿势时会引发Gesture事件,在Select模式下选择元素或改变元素时会引发SelectionChanging事件、SelectionChanged事件、SelectionMoving事件、SelectionMoved事件、SelectionResizing事件和SelectionResized事件。其中,名称以"ing"结尾的事件表示动作将要发生,但可以通过设置EventArgs对象的Cancel属性取消事件。

  后期还会进行更详细的介绍。

原文地址:https://www.cnblogs.com/Peter-Luo/p/12184916.html

时间: 2024-10-13 21:40:50

【WPF学习】第九章 使用Canvas面板进行基于坐标的布局的相关文章

【WPF学习】第八章 Grid面板

Gird面板是WPF中功能最强大的布局容器.很多实用其他布局控件能完成的功能,用Grid面板也能实现.Grid面板也是将窗口分割成更小区域的理想工具.实际上,由于Grid面板十分由于ong,因此在Visual Studio中为窗口添加新的XAML文档时,会自动添加Grid标签作为顶级容器,并嵌套在Window根元素中. Grid面板将元素分割到不可见的行列网格中.尽管可在一个单元格中放置多个元素,但在每个单元格中放置一个元素通常更合理.当然,在Grid单元格中的元素本身也可能是另一个容器,该容器

Python爬虫学习==&gt;第九章:正则表达式基础

学习目的: 正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特点字符.及这些特点字符组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑. 正式步骤 Step1:常用匹配模式 Step2:最常规的匹配 import re testString = 'I have 4Learned the python years' print(len(testString)) result = re.match('^I\s\w{4}\s\d\w{7}.*years$',t

java并发学习-第九章 指令重排序

一.happns-before happns-before是学习指令重排序前的一个必须了解的知识点,他的作用主要是就是用来判断代码的执行顺序. 1.定义 happens-before是用来指定两个操作之间的执行顺序.提供跨线程的内存可见性. 在java内存模型中,如果一个操作执行的结果需要对另一个操作可见,那么这两个操作之间必然存在happens-before关系 2.happens-before规则 a.程序顺序规则 单线程中的每个操作,总是前一个操作happens-before于该线程中的任

汇编语言学习第九章-转移指令的原理

本博文系列参考自<<汇编语言>>第三版,作者:王爽 可以修改IP寄存器的值,或者同时修改CS与IP的值的指令称为转移指令.转移指令的功能就是使得CPU执行内存中某段特定的指令或程序. 8086CPU的转移行为分为如下几类: 1.只改变IP值,称为段内转移.比如 jmp ax;段内转移又分为短转移和近转移.短转移IP的修改范围为-128~127,近转移IP的修改范围为-32768~32767. 2.同时改变CS:IP的值称为段间转移.比如 jmp 1000:0 8086CPU的转移指

【WPF学习】第五章 理解WPF的布局

在Windows开发人员设计用户界面的方式上,WPF布局模型是一个重大改进.在WPF问世之前,Windows开发人员使用刻板的基于坐标的布局将控件放到正确位置.在WPF中,这种方式虽然可行,但已经极少使用.大多数应用程序将使用类似Web的流(flow)布局:在使用流布局模型时,控件可以扩大,并将其他控件挤到其他位置.开发人员能创建与现实分辨率和窗口大小无关的.在不同的显示器上正确缩放的用户界面:当窗口内容发生变化时,界面可调整自身,并且可以自如地处理语言的切换.要利用该系统的优势,首先需要进一步

WPF学习—命令

摘抄自<深入浅出WPF>第九章 WPF命令系统基本要素: 1.命令(Command):WPF命令实际上就是实现ICommand接口的类,用的最多的是RoutedCommand类 2.命令源(Command Source):命令发送者,是实现了ICommandSource接口的类 3.命令目标(Command Target):命令发送目标.命令目标必须是实现了IInputElement接口的类 4.命令关联(Command Binding):负责把一些外围逻辑与命令关联起来. 命令的使用步骤:

WPF学习笔记系列之一 (布局详情)

布局:StackPanel  栈布局:控件不会拐弯且多出的不再显示.DockPanel   停靠布局 吸在上边下边或左右.WrapPanel    环绕布局   一行控件会拐弯Canvas  进行基于坐标的布局 Grid中若不指定Grid.Row属性及Grid.Column则默认为:0行,0列.RowDefinitions ColumnDefinitions ShowGridLines=true <ColumnDefinition Width="100"></Colu

【WPF学习】第五十五章 基于路径的动画

基于路径的动画使用PathGeometry对象设置属性.尽管原则上基于路径的动画也能用于修改任何适当数据类型的属性,但当动态改变与位置相关的属性时最有用.实际上,基于路径的动画类主要用于帮助沿着一条路径移动可视化对象. 正如在“[WPF学习]第四十三章 路径和几何图形”学过的,PathGeometry对象描述可包含直线.弧线以及曲线的图形.下图显示的示例具有一个PathGeometry对象,该对象包含两条弧线以及一条将最后定义的点连接到起点的直线段.这样就创建了一条闭合的路线,一个小的矢量图像以

【WPF学习】第十九章 控件类

原文:[WPF学习]第十九章 控件类 WPF窗口充满了各种元素,但这些元素中只有一部分是控件.在WPF领域,控件通常被描述为与用户交互的元素--能接收焦点并接受键盘或鼠标输入的元素.明显的例子包括文本框和按钮.然而,这个区别有时有些模糊.将工具提示视为控件,因为它根据用户鼠标的移动显示或消失.将标签视为控件,因为它支持记忆码(mnemonics,将焦点转移到相关控件快捷键). 所有控件都继承自System.Windows.Control类,该类添加了一小部分基本的基础结构: 设置控件内容对齐方式