wpf知识点.docx
《wpf知识点.docx》由会员分享,可在线阅读,更多相关《wpf知识点.docx(16页珍藏版)》请在冰豆网上搜索。
![wpf知识点.docx](https://file1.bdocx.com/fileroot1/2023-2/11/cb5a84dc-376f-470f-88ed-bf20bbf884e7/cb5a84dc-376f-470f-88ed-bf20bbf884e71.gif)
wpf知识点
wpf知识点
【篇一:
wpf知识点】
本文的主要内容是自己使用wpf开发以来,本人对相关知识的梳理,仅为个人的总结,对很多事物的理解依然在探索阶段,总会有谬误和更佳的开发方式,如能提出宝贵建议,感激不尽。
虽然本人并不只专注于wpf,还喜欢各类编程语言,但估计在今后1,2年内依然会继续经常使用wpf开发。
想来想去,时间一长,很多东西还是整理并记录下来为好,遂决定从发布此文以后,开始慢慢积累,随着个人知识的扩展和理解,本文可能会不断添加或者更新内容,然而也会尽可能保留对同一概念前后不同的理解。
wpf搞了快一年,除了去年在上家公司主导开发过一个比较大的wpf项目(已经商业化),其他都是小打小闹的软件。
在我看来
wpf的优点是:
1.可以相对比较容易的写出完全定制化的界面。
2.特有的mvvm设计模式可以完美的分离ui设计(view层)和业务逻辑(model层)。
wpf的缺点是:
1.学习成本比较高(我指的是真正精通,你和我说就拖拖控件生成个事件写个方法,当个处理工具,那都不用学了)
新的概念非常多,容易混淆,本人耐性还是很好的,但依然常常连续好多天不停的折腾,折腾到开始喷ms为何这样设计。
2.不能跨平台。
过一阵子去研究下mono。
3.由于本身的复杂性,bug有时隐藏的比较深。
4.坑很多,复杂的项目下很多坑必须得自己跳,官方文档大多数时候并不能解决实际问题,网上搜索的资料参差不齐,很难查到自己想要的,为了解决大坑最开始常常需要去理解一大堆从天而降的概念。
国外下载的demo有时会复杂的过分,csdn上的很多源代码又太不专业我就吐槽下。
目前为止,我依然没有解决的问题:
a.图片占用内存太大,在图片很多并且实时刷新速度很快的时候,如果不写代码手动释放资源,内存就会暴涨至崩溃。
而同样的功能改用winform实现就只占用很小的内存。
b.数据虚拟化面板在xp或部分win7电脑上显示为空白。
只能替换为普通面板。
c.窗体设置为允许透明时,webbrowser显示为空白。
(目前查到和尝试的方案没有完美解决的)我的办法是换成第三方浏览器内核,比如cef,但是使用javascript内外通信又是很麻烦的事情。
不然就是放弃窗体透明
近期又开始使用wpf写一个程序,同时希望能利用这次开发,将之前wpf相关的知识做一个整合,重新理解概念,丢弃不好的,探索更加舒服好用的,并将已知的融会贯通,尽可能用最优雅的方式去实现功能。
那么我们开始吧。
wpf相关技术一定要弄清楚的知识点,先列个大纲,按照我个人建议的学习顺序排序。
1.理解xaml相关窗体设计的原理。
a.逻辑树结构非常类似html,但更加麻烦。
b.可以使用xamlpad查看可视树结构。
c.理解style类似于css,并可以通过随时更换资源字典以达到更换主题或者换肤的目的。
2.触发器(trigger),最常用的是属性触发器和数据触发器。
a.需要知道触发器主要是用于视觉交互的。
b.属性触发器是控件本身的某个属性值发生改变,比如ismouseover=true的时候,会触发可视内容比如背景色发生变化。
c.数据触发器是在数据模板(datatemplete)中,当某个业务数据发生变化改变时,会触发可视内容发生变化。
3.为了创建形态各异的界面,实现各种神奇的效果,需要学习wpf绘图。
a.使用图形,包括:
直线,矩形,椭圆,贝塞尔曲线,path(最强大的路径)
b.应用滤镜效果,effect比较简单,但是导入和开发外部滤镜,一直没有研究。
c.使用变形。
有平移,旋转,缩放,扭曲等基本变形,以及矩阵变形。
(要注意的是:
每种变形既可以放在呈现变形中,也可以放在布局变形中,需要区分二者的区别。
呈现变形只是看到的样子变化了,实际位置和形状都没变。
布局变形是真的变化,会在变形的同时不断对其他控件重新进行布局计算。
)
4.学习使用xaml创建简单的动画
a.尝试使用3类触发器触发动画的发生
b.使用visualstatusmanager来应用动画
c.如无必要,尽量避免通过写代码的方式创建动画
d.(扩展:
使用blend创建并组合出复杂的动画。
)
5.依赖属性和附加属性。
a.要学会如何自定义我们自己扩展的依赖属性和附加属性。
b.所谓依赖属性,从功能上讲:
就是一个普通的属性,附带了可以绑定到任意对象的其他属性上的功能。
所谓绑定就是:
一个值变化,另外一个值跟着变化的。
这样可以省去大量的界面效果相关的后台代码,并使界面和业务代码分离成为可能。
c.依赖属性可用于继承一个现有控件或者自定义控件,并为其扩展属性。
缺点是这些属性不能复用,是控件自己专属的。
d.附加属性是一种特殊的依赖属性。
有两种用法,一种继承现有类,并进行定义,实现的效果如同canvas.left。
一种新建类,主要用于为了不进行大量继承的前提下,给现有控件扩展额外的属性。
是一种很好的组合模式思维。
6.模板。
主要了解:
controltemplete,datatemplete
a.controltemplete是用来重写现有控件的可视结构的,一般和依赖属性和附加属性结合,加上绑定,控件可以获得很好的扩展。
b.datatemplete主要用于定义数据对象的可视化结构的。
既然是数据对象,最好要有个数据类型,即在datatype中定义。
c.模板在wpf起着巨大的作用。
控件模板可以很容易写出任意形态任意效果的外观,数据模板使得view层和viewmodel层很好的分离。
请一定要注意,起初我对这样的概念不屑一顾,其实就是没明白什么意思。
后来我才懂:
就因为数据模板的存在,使得代码中几乎再也不用出现控件对象了。
d.推荐模式在模板中的运用,利用自动创建的模板,经常会看到part_xxx,不明白怎么回事?
看基类的特性中,会有templatepart,这其实是一种推荐的设计模式,用于提示后来的开发者,告诉你控件组成的必要元素:
名称和类型。
也就是说,你可以重写控件模板,但是如果要实现控件自身的核心功能,一定要保留一个名为part_xxx的某个类型的控件才行。
7.mvvm设计模式,最方便学习此模式的是mvvmlight框架,可以直接在nuget中下载。
a.model-view-viewmodel。
不同于mvc,mvp等设计模式,mvvm最主要的特点是实现ui(view)和业务(model)的分离。
而viewmodel应该同时负责表现逻辑和业务逻辑。
这在开发时尤其有用,另外可以同时快速创建设计用的viewmodel,以便设计阶段即可以模拟出完全真实的使用效果,因为view层对应的viewmodel可以很容易的切换。
b.本人并非设计模式的过渡崇拜者,然而只要让代码生产力持续保持比较高的效率,就是好的方法。
很多时候只要不影响大局,在codebehind中写一些代码是无可厚非的。
c.mvvmlight框架下,有很好用的eventtocommand,可以将任何事件直接转化为命令,在我看来这使得ui和业务分离的更加彻底。
d.mvvmlight下的消息机制,messenger也是个很好用的东东,可以实现本无关联的viewmodel间的通信,让他们继续无关联下去。
另外也可以用于导航。
e.viewmodel让model更加适合于view。
注意两点:
一.viewmodel不需要知道view中有什么,换句话说,viewmodel中不要引用view中的控件。
二.view中不要直接引用model,而是借助viewmodel,想要用model怎么做?
比如:
persionviewmodel里有个公有的persion类型的属性persion,view的datacontext是persionviewmodel,绑定时写{bindingpath=persion.name}即可。
8.可以附加在控件上的行为(behavior)
a.行为,还有上面刚说的触发器,eventtocommand,都是一种附加属性。
这样就很好理解了。
通常理解的附加属性,只是一一个数据类型的值,既然扩展成了一个行为这么复杂的数据类型,目的主要是为了实现各种行为效果的重用,然而行为的封装是最完整的。
9.要反复深刻理解装饰器相关adorner,decorator,adornerdecorator
a.从简单开始,最好懂的是decorator,如果这个词感到陌生,那么border就不陌生了,边框嘛,一个东西,外面套个边而已。
然而decorator是border的基类而已。
可以扩展它,然而我目前还没有遇到继承decorator的应用场景。
b.再说adorner,这才是真正的装饰器,本身没有可视结构,它的存在就是要你继承它,并设计它的可视样式,如何继承,网上一大堆教程,最直观的理解就是:
在控件自身上面,蒙了一层额外的装饰,用于交互性的提示与操作。
比如:
光标,旋转钮,调整大小,表头的排序箭头等等。
需要什么就画什么,恩恩,这个很重要。
c.理解了前面两个,再来说最后一个,看起来好复杂好高大上的样子,其实很简单,按我的理解:
这就是一个双面胶,用来粘贴decorator和adorner。
微软需要在控件上面有个容器,用来放adorner,这个容器最好从控件的最边缘开始,控件的最边缘,自然是decorator了,ok,那么再包裹一个东西,就可以放adorner了,于是这个东西的名字叫做adornerdecorator,上面有个叫做adornerlayer的东西可以让adorner直接add。
d.事实上,只有adornerdecorator和scrollcontentpresenter具有adornerlayer,所以,想要自己加装饰器的时候,不要忘记在模板里面套一个adornerdeocrator哦。
尤其像我这种经常写自定义窗体的,窗体的contentpresenter外面套个adornerdecorator是必不能忘的。
10.路由事件和命令
a.如果想要写出来的wpf程序在复杂的界面中不会出现莫名其妙的问题,那么一定要弄懂路由事件和路由命令的概念。
所谓路由,有三种烂大街的方式:
隧道,冒泡,直接。
顾名思义:
隧道,标签从外向内响应事件。
冒泡,标签从内向外相应事件。
直接,只能从定义元素监听元素的直接事件,写别的地方没用。
b.路由事件是定义在哪一层监听事件,而不是点击哪一层会执行事件,目的自然是一夫当关万夫莫开,比如冒泡路由,n多的控件都可能响应某一鼠标事件,那么只需要在集合控件上面监听这一事件就可以了(附加事件)。
在响应事件处理中,再拿到实际命中的控件就可以了。
当然,这个时候我往往是直接取命中控件的datacontext,直接转化为viewmodel,操作数据层。
c.其实这个路由事件机制和html中javascript的事件机制非常非常类似,addeventlistener的第三个参数usecapture用来控制是否是bubbling(冒泡)方式。
我也常常会用jquery中的delegate来做类似的事情,以便监听未来产生的子元素相关的事件。
d.可以在路由事件中标记handler=true。
来阻止事件继续路由下去。
然而实际上即使这样设置,路由事件依然在继续传递。
因为用addhandler显式挂接路由事件处理程序,可以定义路由事件即使被处理依然会执行。
即设置handledeventstoo=true。
这里分析,相信handler||handledeventstoo为真时,即会执行事件处理程序。
e.自定义路由事件,类似于注册依赖属性。
其中可以定义路由类型等等。
f.说来说去,需要强调的是,preview名称开头的事件是隧道方式,代表了事件是从外向内传递的。
不带preview的事件是冒泡方式,是从内向外传递的。
同一名称的事件preview先执行。
这是个形象的反弹,球弹进去再弹出来,这个过程球可以被人抓住。
g.路由命令在我看来,因其天生的缺陷与限制,应用的比较少。
我一般使用mvvmlight的relaycommand,当然,如果项目没必要引入mvvmlight时,自己自定义也可以。
讲了半天的理论,都是这不到一年wpf开发的体会,接下来开始实践内容部分。
以后自己实现了感觉不错的东西,就会列在下面分享。
【篇二:
wpf知识点】
!
--lights,meshgeometry3danddiffusematerialobjectsareaddedtothemodelvisual3d.--directionallightcolor=#ffffffffdirection=3,-4,5/!
--definearedcone.--geometrymodel3dgeometrymodel3d.geometrymeshgeometry3dpositions=0.293893-0.50.4045090.475528-0.50.15450900.500.475528-0.50.15450900.5000.500.475528-0.50.1545090.475528-0.5-0.15450900.500.475528-0.5-0.15450900.5000.500.475528-0.5-0.1545090.293893-0.5-0.40450900.500.293893-0.5-0.40450900.5000.500.293893-0.5-0.4045090-0.5-0.500.500-0.5-0.500.5000.500-0.5-0.5-0.293893-0.5-0.40450900.50-0.293893-0.5-0.40450900.5000.50-0.293893-0.5-0.404509-0.475528-0.5-0.15450900.50-0.475528-0.5-0.15450900.5000.50-0.475528-0.5-0.154509-0.475528-0.50.15450900.50-0.475528-0.50.15450900.5000.50-0.475528-0.50.154509-0.293892-0.50.40450900.50-0.293892-0.50.40450900.5000.50-0.293892-0.50.4045090-0.50.500.500-0.50.500.5000.500-0.50.50.293893-0.50.40450900.500.293893-0.50.40450900.5000.50normals=0.7236065,0.4472139,0.52573130.2763934,0.4472138,0.85065070.5308242,0.4294462,0.73061720.2763934,0.4472138,0.85065070,0.4294458,0.90309250.5308242,0.4294462,0.73061720.2763934,0.4472138,0.8506507-0.2763934,0.4472138,0.85065070,0.4294458,0.9030925-0.2763934,0.4472138,0.8506507-0.5308242,0.4294462,0.73061720,0.4294458,0.9030925-0.2763934,0.4472138,0.8506507-0.7236065,0.4472139,0.5257313-0.5308242,0.4294462,0.7306172-0.7236065,0.4472139,0.5257313-0.858892,0.429446,0.279071-0.5308242,0.4294462,0.7306172-0.7236065,0.4472139,0.5257313-0.8944269,0.4472139,0-0.858892,0.429446,0.279071-0.8944269,0.4472139,0-0.858892,0.429446,-0.279071-0.858892,0.429446,0.279071-0.8944269,0.4472139,0-0.7236065,0.4472139,-0.5257313-0.858892,0.429446,-0.279071-0.7236065,0.4472139,-0.5257313-0.5308242,0.4294462,-0.7306172-0.858892,0.429446,-0.279071-0.7236065,0.4472139,-0.5257313-0.2763934,0.4472138,-0.8506507-0.5308242,0.4294462,-0.7306172-0.2763934,0.4472138,-0.85065070,0.4294458,-0.9030925-0.5308242,0.4294462,-0.7306172-0.2763934,0.4472138,-0.85065070.2763934,0.4472138,-0.85065070,0.4294458,-0.90309250.2763934,0.4472138,-0.85065070.5308249,0.4294459,-0.73061690,0.4294458,-0.90309250.2763934,0.4472138,-0.85065070.7236068,0.4472141,-0.52573060.5308249,0.4294459,-0.73061690.7236068,0.4472141,-0.52573060.8588922,0.4294461,-0.279070.5308249,0.4294459,-0.73061690.7236068,0.4472141,-0.52573060.8944269,0.4472139,00.8588922,0.4294461,-0.279070.8944269,0.4472139,00.858892,0.429446,0.2790710.8588922,0.4294461,-0.279070.8944269,0.4472139,00.7236065,0.4472139,0.52573130.858892,0.429446,0.2790710.7236065,0.4472139,0.52573130.5308242,0.4294462,0.73061720.858892,0.429446,0.279071triangleindices=01234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859//geometrymodel3d.geometrygeometrymodel3d.materialdiffusematerialdiffusematerial.brushsolidcolorbrushcolor=redopacity=1.0//diffusematerial.brush/diffusematerial/geometrymodel3d.material/geometrymodel3d/model3dgroup.children/model3dgroup/modelvisual3d.content/modelvisual3d/viewport3d.children/viewport3d/grid/usercontrol
makea3dcubewithpicturesonitssideswithxamlandc#
3d开发首先要把三维坐标系搞清楚,才能构建出想要的3dmodel,才能把灯光合理的照在3d模型上(环境光除外)得到不同的灯光效果,才能指定合适的相机(camera)位置从而看到自己想要看到3d投影。
3d开发中所有的几何体最终都是由一系列的三角形来组成的。
所以在您吧三维坐标系高清的前提下,您还需要考虑把您的3d模型分解成三角形。
听来就很繁琐,幸运的是现在有一些辅助类帮助大家来处理这些三角形的分解,而您所做的就是提供关键点的坐标系。
由于wpf3d是基于direct3d,和wpf2d一样直接利用显卡渲染的,并且默认开启了全景反锯齿(有个条件,需要你的显卡支持兼容)。
3d开发和2d开发复杂了很多,考虑的东西多了不少。
但为了那更真实的,更炫酷的效果,这一切都值得您去学习。
祝各位在3d开发的旅途,一路愉快!
【篇三:
wpf知识点】
引言现在物联网概念这么火,如果监控的信息能够实时在手机的客服端中以3d形式展示给我们,那种体验大家可以发挥自己的想象。
那生活中我们还有很多地方用到这些,如上图所示的kinect在医疗上的应用,当然还有体感游戏等等。
3d用来增加视觉效果,给人以更加直观,真实的感觉。
3d如此美妙,那我们在wpf中又该从何处入手开启我们的3d编程旅程?
wpf中3d开发技术的基础知识应该有以下几点:
3d开发基础知识wpf中3d开发的基础元素(elements)wpf中3d变换和动画常用辅助类3d开发基础知识坐标系coodinatesystemwpf中二维图形的坐标系将原点定位在呈现区域(通常是屏幕)的左上角。
在二维系统中,x轴上的正值朝右,y轴上的正值朝下。
而在三维坐标系中,原点位于呈现区域的中心,x轴上的正值朝右,但是y轴上的正值朝上,z轴上的正值从原点向外朝向观察者。
传统的二维和三维坐标系表示形式如下图
由这些轴定义的空间是三维对象在wpf中的固定参考框架。
当您在该空间中生成模型并创建光源和照相机以查看这些模型时,一定要在向每个模型应用变换时,将固定参考框架或“全局空间”与您为该模型创建的局部参考框架区分开。
另请记住,根据光源和照相机设置,全局空间中的对象可能会看上去完全不同或者根本不可见,但是照相机的位置不会改变对象在全局空间中的位置。
3d的世界都是三角形的王国如下图:
在3d的世界里所有的东西都是用一些列的“三角形”来描述的。
那你一定会问为什么是“三角形”?
其实就是三点确定一个平面,在一个平面上做计算最简单,考虑的因素最少。
如果用三维空间中大于三个点来做渲染基本单位,那么如果这些点不在同一个平面上的话,渲染计算是相当复杂的。
3d对象的表面叫做网格(mesh),一个网格是由许多3d点来定义的,这些点叫做顶点(vertices)。
这些顶点通过缠绕模式(windingpattern)连接在一起组成一个一个的三角形(facet)(如下图箭头所示)。