在此之前我们先了解一下WPF的"路径标记语法"

M:表示绘制起点 // M 0,0

L:表示绘制直线 (H:横线 V:竖线)  // L 100,0

C:三次方贝塞尔曲线   // C 100,200 200,400 300,200

Q: 二次曲线

z:闭合

......

要注意的是 每一次的绘制都是基于上一次的终点(或者原点M)

例如 M 0,0 L 100,0 L200,50 表示 移动绘制原点到(0,0) 然后绘制直线到(100,0) 紧接着从(100,0)开始再绘制直线到(200,50),也就是说每一次绘制命令都是接着上一次开始的.

*手写语法命令的时候注意空格的使用,以及逗号的使用.

等等 MSDN有详细介绍 不了解的可以去看看.

大致了解路径标记语法后我们来探讨一下"复合路径"功能.

首先我们绘制两条线

(一)

<Canvas >    <Path Data="M0,0 L50,120 " Stretch="Fill" Stroke="red" StrokeThickness="5"/>    <Path Data="M100,0 L250,120 "  Stretch="Fill" Stroke="green" StrokeThickness="5"/></Canvas>

看下效果

我们在看Blend->复合路径后的代码

<Path Data="M2.5,2.5 L52.5,122.5 M2.5,2.5 L152.5,122.5" Stretch="Fill" Stroke="red" StrokeThickness="5" />

我们仔细观察 复合前的2个Path.Data的语法和复合后的Path.Data的差别.

看看看看看看....嗯... IQ处理中......................

我们把前两个拼起来看看!

//拼前:    <Path Data="M0,0 L50,120 " Stretch="Fill" Stroke="red" StrokeThickness="5"/>        <Path Data="M100,0 L250,120 "  Stretch="Fill" Stroke="green" StrokeThickness="5"/>//拼后 :<Path Data="M0,0 L50,120  M100,0 L250,120 " Stretch="Fill" Stroke="red" StrokeThickness="5"/>// Blend复合的:<Path Data="M2.5,2.5 L52.5,122.5 M2.5,2.5 L152.5,122.5" Stretch="Fill" Stroke="red" StrokeThickness="5" />

看看后两个Path有什么一样的地方吗?!

是的 Blend好像也是给拼接起来的? 可是为什么有2.5的误差呢?为什么每个数都是2.5 怎么不是0.1不是其他呢?  奥秘就在这里:StrokeThickness="5"

2.5正好是5的一半嘛,是的,这个2.5只是算了粗细而已.我们可以去掉它也不会影响整体的形状的.

当我们把5改为1后(什么你说改成0?? 0像素好粗啊 会闪下我氪金狗眼的!别闹~~~)

再使用复合路径得到的数据是 M0.5,0.5 L50.5,120.5 M0.5,0.5 L150.5,120.5 , 看看"误差"变为0.5了吧.如果你手动去掉所有的小数,那么你会看到形状不变的.这里我就不去演示了.

那么我们初步得到结论:复合路径 =路径1+路径2+路径3+..... (拼接所有的路径部分) .

(二)

下面我们再来看一组数据:

    <Path Data="M0,0 L50,120 " Stretch="Fill" Stroke="red" StrokeThickness="5"/>        <Path Data="M100,0 L300,120 " Canvas.Left="50" Stretch="Fill" Stroke="red" StrokeThickness="5"/>

效果:

在看Blend复合后的代码:

<Path Data="M2.5,2.5 L52.5,122.5 M52.5,2.5 L252.5,122.5" Stretch="Fill" Stroke="red" StrokeThickness="5" />

首先我们基于(一)的结论忽略掉粗细误差2.5(顺便验证一下这个结论)得到结果

<Path Data="M0,0 L50,120 M50,0 L250,120" Stretch="Fill" Stroke="red" StrokeThickness="5"  />

Blend中我们看到形状位置都没变.

接下来我们尝试手动拼接上面(二)的2个Path得到

        <Path Data="M0,0 L50,120 " Stretch="Fill" Stroke="red" StrokeThickness="5"/>        <Path Data="M100,0 L300,120 " Canvas.Left="50" Stretch="Fill" Stroke="green" StrokeThickness="5"/>手动拼接:        <Path Data="M0,0 L50,120 M100,0 L300,120" Stretch="Fill" Stroke="red" StrokeThickness="5"/>

这是为什么? 怎么分离的这么远?

我们来解密一下:

看看第二条Path 他有这个附加属性   Canvas.Left="50"   居然给右移了50!!!! 那么我们给他挪回去试试?

得到

<Path Data="M0,0 L50,120 " Stretch="Fill" Stroke="red" StrokeThickness="5"/>        <Path Data="M100,0 L300,120 " Canvas.Left="50" Stretch="Fill" Stroke="green" StrokeThickness="5"/>手动拼接:        <Path Data="M0,0 L50,120 M100,0 L300,120" Stretch="Fill" Stroke="red" StrokeThickness="5"/>
把第二个Path的Left 50 左移回去得到: <Path Data="M0,0 L50,120 M50,0 L250,120" Stretch="Fill" Stroke="red" StrokeThickness="5"/>
左移后 <Path Data="M0,0 L50,120 M50,0 L250,120" Stretch="Fill" Stroke="red" StrokeThickness="5"/>效果(佰年金融):
是不是一样了!  左移第二条线是移动原点M和L的横坐标 所以得到M50,0 L250,120"
( 被左移 - X需要减掉相应值 . 被右移 - X需要加上相应值 )
上下移同理,上移(Top负数)需加,下移(Top正数)需减
这个过程我们暂且称为"复位"
因此我们又得到一个结论 Canvas.Left 同样会影响复合路径!当然这里也包括Canvas.Top /Right/Bottom  ,
值得提醒的是当 Left /Top等 的值为负数时  直接简单拼接和"复位" 是不对的.因为你可能复不到位.不信你试试看. 这里稍微解释一下标记语法一个特别的地方(我猜的!没有去MSDN考证.)
<Path Data="M100,0 L300,120 "  Stretch="Fill" Stroke="green" StrokeThickness="5"/>
<Path Data="M0,0 L200,120 "  Stretch="Fill" Stroke="green" StrokeThickness="5"/>
<Path Data="M-100,0 L100,120 "  Stretch="Fill" Stroke="green" StrokeThickness="5"/>
这3个Path是一样的!
当Path中只有一段图形时(这里是只有一段Line) , Line整体平移(指的是原点从0,0 平移到100,0 且 端点从200,120平移到300,120)是不会影响Path形状和位置的.
因此在只有一段图形的Path中我们可以约掉这个平移 我们暂且称为"约分"(参考数学分数的约分哈,不严谨 好记而已~~) 所以上面我说 当Canvas.Left为负数时 不能简单直接拼接和复位.怎么办呢?我们需要先约分!先把所有能约分的线段的原点约分到不能再约分的实际原点,
例如上面的三个Path的实际原点其实都是M 0,0  .约分处理完所有图形片段后 再进行 拼接和复位.最后就能得到复合路径的结果了. 另外,凡是所有能影响Path位置的属性改变都会影响复合路径的结果,比如 RenderTransform  和Margin 等. 如果想手动去算复合路径可能是非常繁琐的一个过程~~~ 您可能需要为所有影响Path位置变化的属性改变都写一个复位的方法.在执行复合路径之前需要先调用所有的复位/约分方法来恢复Path的Data到实际值.再进行拼接计算. 以上是我粗略分析后的一些看法和结论.我之前也不知道这些的,只不过是在我的一片自定义MessageBox的文章中有人问我这个问题,我就试着猜猜.
这位童鞋@距离永远  您可请俺喝酒啊!! 嘻嘻~~

WPF的"路径标记语法"的更多相关文章

  1. 详解WPF Blend工具中的复合路径功能 ( 含路径标记语法 )

    写此文章的目的是为了简单分析一下 Blend工具中提供的"复合路径"功能.有人在我的博文中留言问我复合路径的问题.  稍微琢磨一下,觉得应该是对的.因此贴出来和大家分享.有不对的说 ...

  2. Windows Phone开发(34):路径标记语法

    原文:Windows Phone开发(34):路径标记语法 如果你觉得前面所讨论的绘制各种几何图形的方法过于复杂,那么,今天我们也来一次"减负"吧.当然,我们是很轻松的,本教程是不 ...

  3. WPF中 PropertyPath XAML 语法

    原文:WPF中 PropertyPath XAML 语法 PropertyPath 对象支持复杂的内联XAML语法用来设置各种各样的属性,这些属性把PropertyPath类型作为它们的值.这篇文章讨 ...

  4. HTML标记语法总结

    一.HTML标记类型 1.单标记 语法:<标记名>,如:<img>.<br>.<hr> 2.双标记 语法:<标记名>…标记内容…</标 ...

  5. 【转】关于 Endnote 与 Word 卡死问题 标记语法错误

    转自:http://hi.baidu.com/lvneng/item/8147dcbb1436bfd085dd7962 当使用 Word 写论文或稿件时,Endnote 绝对是一个不错的帮手,不过偶尔 ...

  6. WPF系列 Path表示语法详解(Path之Data属性语法)

    示例: XAML(代码A): <Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" ...

  7. WPF中图形表示语法详解(Path之Data属性语法)ZZ

    大可山 [MSN:a3news(AT)hotmail.com] http://www.zpxp.com 萝卜鼠在线图形图像处理 ------------------------------------ ...

  8. WPF中图形表示语法详解(Path之Data属性语法)

    原文 http://blog.csdn.net/johnsuna/article/details/1885597 老规矩,看图说话. 先看显示效果:(图1) XAML(代码A):<Page xm ...

  9. HTML标记语法之图片Img元素

    语法:<img src=”xxx.jpg”alt=”xxx”title=”xxx”> 属性可取值如下: 属性名称 属性值 说明 src URL 图片路径 alt 文本 图片无法显示时的文本 ...

随机推荐

  1. [POJ2151]Check the difficulty of problems (概率dp)

    题目链接:http://poj.org/problem?id=2151 题目大意:有M个题目,T支队伍,第i个队伍做出第j个题目的概率为Pij,问每个队伍都至少做出1个题并且至少有一个队伍做出N题的概 ...

  2. 【解决】org.apache.hadoop.util.Shell$ExitCodeException: /bin/bash: line 0: fg: no job control

    [环境信息] Hadoop版本:2.4.0 客户端OS:Windows Server 2008 R2 服务器端OS:CentOS 6.4 [问题现象] 在通过Windows客户端向Linux服务器提交 ...

  3. FreeBSD从零开始---安装后配置(二)

    系统优化及安全设置   上次说了FreeBSD基本的软件安装和配置,接下来会说系统的详细配置和安全性设置   一.系统优化设置   1.网络相关设置   网卡和IP地址设置: 如果在安装时没有设置IP ...

  4. Django中提示TemplateDoesNotExist?

    用的是1.9版本.需要在settings.py文件中设置TEMPLATES下的DIRS如下: TEMPLATES = [ { 'BACKEND': 'django.template.backends. ...

  5. 组合or继承

    面向对象设计有一个原则“优先使用对象组合,而不是继承”. 下面是两者优缺点的比较: 组 合 关 系 继 承 关 系 优点:不破坏封装,整体类与局部类之间松耦合,彼此相对独立 缺点:破坏封装,子类与父类 ...

  6. :before和 :after

    :before和:after的作用就是在指定的元素内容(而不是元素本身)之前或者之后插入一个包含content属性指定内容的行内元素,最基本的用法如下: #example:before { conte ...

  7. 批量Clip

    没有建立对应dataset,直接生成featureclass,主要是工作中没几个dataset. # -*- coding: utf-8 -*-__author__ = 'tanshuai' impo ...

  8. 单例设计模式全局缓存accessToken

    使用微信JS-SDK开发的小伙伴们,看文档经常会看到这样一句话:(下面是微信开发文档的一部分原话截图) 这句话就是:开发者必须在自己的服务全局缓存access_token,jsapi_ticket 下 ...

  9. JAVA 多线程和并发学习笔记(四)

    1. 多进程 实现并发最直接的方式是在操作系统级别使用进程,进程是运行在它自己的地址空间内的自包容的程序.多任务操作系统可以通过周期性地将CPU从一个进程切换到另一个进程,来实现同时运行多个进程. 尽 ...

  10. [转]:C#的ToString如何格式化字符串

    C 货币 2.5.ToString("C") ¥2.50 D 十进制数 25.ToString("D5") 00025 E 科学型 25000.ToString ...