登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

秒大刀 博客

好好学习 天天向上

 
 
 

日志

 
 
 
 

读《深入浅出WPF》  

2012-05-16 09:46:06|  分类: 读书 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
读《深入浅出WPF》 - 秒大刀 - 秒大刀 博客


正文之前
  1. 微软在WPF技术方面有相当的务实精神和决心
  2. .net开发人员学习WPF的回报是相当高的,几乎整个微软新一代开发框架都能看到WPF的影子。学习完WPF,WF也会了一小半;学习完WPF后,Silverlight可以算是会了80%
  3. Windows Phone 7中运行的Silverlight与浏览器中运行的Silverlight别无二致
  4. MVC(Model-View-Control)模式和MVP(Model-View-Presenter)模式均使用事件驱动
  5. 事件驱动时代,用户每进行一个操作会激发程序发生一个事件,事件发生后,用于响应事件的事件处理器就会执行。事件处理器是一个方法,在这个方法中,程序员可以处理数据或调用别的方法,这样程序就在事件的驱动下向前执行了。事件驱动时代的数据是静态的、被动的;界面控件是主动的、界面逻辑与业务逻辑之间的桥梁是时间。
  6. 数据驱动下,当数据发生变化时,会主动通知界面控件、推动控件展示最新的数据;同时,用户对控件的操作会直接送达数据,就好像控件是透明的。数据占据主动地位、控件和控件事件被弱化(控件事件一般只参与界面逻辑,不再染指业务逻辑,使程序复杂度得到有效控制)

第一部分 深入浅入话XAML
第1章 XAML概览
  1. UI代码与逻辑代码纠缠在一起的后果:
    • 无论是软件功能还是UI设计有所变化或者是出了bug,都将导致大量代码的修改
    • 会让逻辑代码更难理解——修改往往比重写更困难,因为在修改之前必须先读懂
    • 重用逻辑代码编程了Mission Impossible
  2. XAML帮助开发团队真正实现了UI与逻辑的剥离。因根本无法在其中加入程序逻辑,这就强制的把逻辑代码从UI代码中赶走了

第2章 从零起步认识XAML
  1. 我们何必再“蒙上眼睛”编程、自己折磨自己呢?
  2. Property属于面向对象理论范畴;Attribute则是编程语言文法层面的东西
  3. XML xmlns后可以跟一个可选的映射前缀,之前用冒号分隔。如果没有写可选映射前缀,那就意味着所有来自于这个名称空间的标签前都不用加前缀,这个没有映射前缀的名称空间称为“默认名称空间”——默认名称空间只能有一个
  4. xaml中的x名称空间对应一些与xaml语法和编译相关的类型,与语言解析处理相关,是语言层面上的东西

第3章 系统学习XAML语法
  1. xaml使用树形逻辑结构来描述UI
  2. 可采用VisualTreeHelper和LogicalTreeHelper来对可视树和逻辑树进行操作
  3. TypeConverterAttribute可以用来指定类型的默认转型器
  4. 对于复杂的绘图和动画创作,应该先在Blend里进行操作,然后回到VS里进行精确的微调,在保证不影响效果的情况下尽可能的提高代码的可读性和可维护性
  5. x:Code标签可以将后台代码直接写在xaml文件中,其中的内容最好使用<![CDATA[...]]>进行转义

第4章 x名称空间详解
  1. x名称空间里的成员是专门写给xaml编译器看的
  2. FindResouce可以从资源字典中检索资源
  3. 编译器会默认给资源添加x:Shared="true",以标记多个副本间的资源共享
  4. xaml中用来表示空值的是x:Null

第5章 控件与布局
  1. GUI的方便之处在于它对数据表达的直观性
  2. 我们关注的应该是抽象的数据和行为而不是控件具体的形象
  3. 如果需要组织在一起的内容能够自由缩放,可使用ViewBox元素
  4. TextBlock不能编辑内容,但可以使用丰富的印刷级别的格式控制标记显示专业的排版效果
  5. 要对每种布局控件的特点都清楚并灵活使用,切莫对其无所不用其极。选择合适的布局元素,将会大大的简化编程,反之将会被迫实现一些布局控件原本已有的功能
  6. 滥用Margin是初学者常见的错误。对于简单的布局,Height+Width+Margin的方式尚能应付,但对于结构复杂的布局这种方式就吃不消了

第二部分 游历WPF内部世界
  1. 生产工具的先进程度代表了生产力的水平
  2. 编程工具之所以能代表软件开发的生产力是因为每种工具背后都隐藏着一整套软件开发的概念和方法
  3. 开发的方法论是开发工具的精髓,掌握了一种开发方法论就掌握了精通某种开发工具的钥匙。只学习某种开发工具而不深究其方法论和内涵便是舍本逐末;若是使用某种开发工具去实践另一种开发工具背后的方法论就更是南辕北辙了


第6章 深入浅出话Binding
  1. UI逻辑层与展示层折腾的根源在于二者的地位不固定——当实现客户需求的时候,逻辑层的确处在中心地位,但到了实现UI交互的时候展示层又处于中心地位
  2. WPF在深层次上帮助程序员把思维的中心固定在了逻辑层、让展示层永远处于逻辑层的从属地位
  3. Binding更注重表达它是一种像桥梁一样的关联关系
  4. 当自定义类型实现了INotifyPropertyChanged接口,并在属性set中激发PropertyChanged事件,则可将属性的更改通知给Binding
  5. 依赖属性(DependencyProperty)的值可以通过Binding依赖在其他对象的属性上,被其他对象的属性值所驱动
  6. 只有依赖属性才能被Binding,而源属性可以为普通属性
  7. Binding对源的要求并不苛刻——只要它是一个对象,并且通过属性公开自己的数据,就能作为Binding源
  8. 如果想让Binding源的对象具有自动通知Binding自己的属性值已经变化的能力,那么就需要让类实现INotifyPropertyChanged接口并在属性的set语句中激发PropertyChanged事件
  9. C#代码可以访问xaml代码中声明的变量,但xaml代码中却无法访问C#代码中声明的变量
  10. C#中我们可以直接访问控件对象,所以一般不会使用Binding的ElementName属性,而是直接把对象赋值给Binding的Source属性
  11. 可以把Binding视为一种间接的、不固定的赋值方式
  12. 当Binding设置了NotifyOnSourceUpdated和NotifyOnTargetUpdated属性后,会自动激发SourceUpdated和TargetUpdated事件
  13. Binding/Path中,如果集合元素的属性仍然是一个属性,则可以使用多级斜线的语法,如:/Provinces/CityList.Name
  14. 当xaml中Binding源本身就是数据则Path为"."或省略,但在C#中需要显示指明Path为“.”
  15. 直观上Binding会沿着UI元素树向上找数据,而Binding并无此智能。之所以会有这种效果是因为DataContext是一个依赖属性。当没有为控件的某个依赖属性显式赋值时,控件会把自己容器的属性值“借过来”当做自己的属性值。实际上是属性值沿着UI元素树向下传递了
  16. 在使用集合类型作为列表控件的ItemSource时一般会考虑使用ObservableCollection<T>,因其实现了INotifyCollectionChanged和INotifyPropertyChanged接口,能把集合的变化立即通知显示它的控件,改变会立即显现出来
  17. 当使用XML数据作为Binding的Source时,要使用XPath属性而不是Path来制定数据的来源。需要加“@”以指明是Attribute
  18. XmlDataProvider用来提供XML数据源以供绑定,ObjectDataProvider包装普通对象作为绑定数据源
  19. Binding中的Converter用来做数据转换,ValidationRules用来做数据验证
  20. Binding进行校验时的默认行为是认为来自Source的数据总是正确的,只有来自Target的数据才有可能有问题。Binding只在Target被外部方法更新时校验数据,而来自Binding Source的数据更新Target时默认是不会进行校验的,除非设置ValidatesOnTargetUpdate属性
  21. 凡是能使用Binding的场合都能使用MultiBinding

第7章 深入浅出话属性
  1. 我们希望对象有能力判断将被写入的值是否正确
  2. 依赖属性:一种可以自己没有值,并能通过使用Binding从数据源获得值(依赖在别人身上)的属性。
    • 节省实例对内存的开销
    • 属性值可以通过Binding依赖在其他对象身上
  3. 登山队员的装备:用得着就带着,用不着就不带,有必要的时候可以借别人的用一下
  4. 依赖对象:传统的.net开发中,一个对象所占用的内存空间在调用new操作符进行实例化的时候就已经决定了,而WPF允许对象在被创建的时候并不包含用于存储数据的空间(即字段所占用的空间),只保留在需要用到数据时能够获得默认值、借用其他对象数据或实时分配空间的能力——这种对象就成为依赖对象,而它这种实时获取数据的能力则依靠依赖属性来实现
  5. 依赖属性是那个由public static readonly修饰的DependencyProperty实例,有没有包装器这个依赖属性都存在。包装器的作用是以“实例属性”的形式想外界暴露依赖属性,这样,一个依赖属性才能成为数据源的一个Path。当然,依赖属性即使没有包装属性也可以很好的工作
  6. BindingOperations的SetBinding可以以第三人称的视角对数据进行绑定
  7. 依赖属性自带更新通知功能,不需另外实现INotifyPropertyChanged接口
  8. 被public static readonly修饰的依赖属性本身并不是用来做属性值存储,而是用来进行属性检索
  9. 附加属性是说一个属性本来不属于某个对象,但由于某种原因被后来附加上。附加属性的作用是将属性与数据类型(宿主)解耦,让数据类型的设计更加灵活
  10. 附加属性的本质是依赖属性,附加属性也可以通过Binding依赖在其他对象的数据上

第8章 深入浅出话事件
  1. 编程的本质是用编译器(有时要借助类库)来扩展操作系统的功能
  2. 路由事件被激发后是沿着VisualTree传递而不是LogicalTree
  3. 为路由事件添加普通事件包装器是为了把路由事件暴露的像一个传统的直接事件,仍然可以使用+=和-=进行事件操作
  4. RoutedEventArgs中的Source表示的是LogicalTree上的消息源头,而OriginalSource则表示VisualTree上的源头
  5. 路由事件的宿主都是些拥有可视化实体的界面元素,而附加事件则不具备显示在用户界面上的能力,但通过附加,仍可与其他对象进行沟通
  6. UIElement类是路由事件宿主与附加事件宿主的分水岭。在一个非UIElement派生类中注册了路由事件,则这个类的实例既不能自己激发此路由事件也无法自己侦听此路由事件,只能把这个事件的激发“附着”在某个具有RaiseEvent方法的对象上,借助这个对象的RaiseEvent方法把时间发送出去;时间的侦听任务也只能交给别的对象去做。
  7. 很少会把附加事件定义在业务逻辑相关的类中

第9章 深入浅出话命令
  1. 事件不具有约束力,而命令具有约束力
  2. PreviewCanExecute和CanExecute的执行时机不由程序员控制,而且频率比较高
  3. RoutedCommand是一个与业务逻辑无关的类,只负责在程序员中跑腿而并不对命令目标做任何操作

第10章 深入浅出话资源
  1. ResourceDictionary可以存储任意类型的对象
  2. ResourceDictionary可以通过Source引用独立的xaml资源文件
  3. 静态资源(StaticResource)是指程序载入内存时对资源的一次性使用,之后就不再去访问这个资源了;动态资源指在程序的运行过程中仍然会去访问资源。如果你确定某些资源只在程序初始化的时候使用一次、之后不会再改变,就应该使用StaticResource,而程序运行过程中还有可能改变的资源应该以DynamicResource形式使用
  4. 将Resources.resx文件的访问级别由Internal改为Public以供xaml编辑器使用: Text={x:Static local:Resources.UserString}
  5. 使用Resources.resx最大的好处就是便于程序的国际化、本地化
  6. WPF不支持从resx文件中访问非字符串资源,需要以独立的文件资源的形式访问
  7. 如果想让外部文件编译进目标成为二进制资源,需要在属性窗口中将文件的Build Action设置为Resource,如果不希望以散包资源文件的形式访问,则需要把Build Action改为None,同时设置Copy to Output Directory
  8. 内嵌二进制资源的访问语法为:pack:application,,,[/程序集名称;][可选版本号;][文件夹名称/]文件名称,其中“pack:application,,,”可省略。如:
    • Source="pack:application,,,/Resources/Images/Test.jpg" // 绝对路径
    • Source="Resources/Images/Test.jpg" // 相对路径,也可以用./、../进行相对路径导航;若以“/”开头则为绝对路径

第11章 深入浅出话模板
  1. 形而上者谓之道,形而下者谓之器
  2. 控件是数据内容表现形式和算法内容表现形式的双重载体
  3. ControlTemplate是算法内容的表现形式,一个控件怎样组织其内部结构才能让它更符合业务逻辑、让用户操作起来更舒服是由ControlTemplate来控制的。ControlTemplate决定了控件长成什么样子,并让程序员有机会在控件原有的内部逻辑基础上扩展自己的逻辑
  4. DataTemplate是数据内容的表现形式,一个数据显示成什么样子,是简单的文本还是直观的图形动画是由DataTemplate决定的
  5. ControlTemplate是控件的外衣,DataTemplate是数据的外衣
  6. ControlTemplate作用于整个控件区域,而DataTemplate只作用于数据内容区域
  7. 事件驱动是控件和控件之间的沟通,是形式和形式之间的沟通
  8. 数据驱动是数据与控件之间的沟通,是内容决定形式
  9. 可以通过更换ControlTemplate改变控件外观,使之具有更优的用户使用体验及外观。借助使用ControlTemplate,程序员可以和设计师并行工作
  10. 实现Template时,可通过TemplateBinding将自己的属性值关联到目标控件的某个属性值上
  11. HierarchicalDataTemplate会自动产生迭代应用效果
  12. 构成Style最重要的两种元素是Setter和Trigger,Setter帮助设置控件的静态外观风格,Trigger帮助设置控件的行为风格
  13. Trigger一旦满足条件,则Setter中的值就会被应用; 触发条件不满足后,各属性值会被自动还原
  14. 不明确指出Source时Binding会把控件的DataContext属性当做数据源而并不是控件本身
  15. UI层的动画效果往往与EventTrigger相关联

第12章 绘图和动画
  1. Microsoft Expression中的Design可以像Photoshop那样绘制图形,再由设计者决定导出为png或者xaml格式
  2. Blend生成的代码质量并不高,可读性比较差——数字过分精确、排列颠三倒四
  3. UIElement中的BitmapEffect是基于CPU的,而Effect是基于GPU的
  4. BitmapEffect能产生的界面效果有:
    • BevelBitmapEffect: 斜角效果
    • BitmapEffectGroup: 复合效果
    • BlurBitmapEffect: 模糊效果
    • DropShadowBitmapEffect: 投影效果
    • EmbossBitmapEffect: 浮雕效果
    • OuterGlowBitmapEffect: 外发光效果
  5. Effect自带的效果有:
    • BlurEffect: 模糊效果
    • DropShadowEffect: 投影效果
    • ShaderEffect: 着色器效果(抽象类)
  6. Photoshop能够大获成功的一个重要原因就是它的插件标准是公开的,众多第三方公司和人员就可以为其设计插件,极大的丰富其功能——众人拾柴火焰高
  7. RenderTransform定义在UIElement中,控制呈现相关的变形
  8. LayoutTransform定义在FrameworkElement中,控制布局相关的变形
  9. 用户并不能感觉到究竟是控件本身的位置、角度发生了改变,还是呈现的位置角度发生了改变
  10. 在窗体上移动UI元素本身会导致窗体布局的改变,而窗体布局的变化将导致所有窗体元素的尺寸测算函数、位置测算函数、呈现函数等的调用,造成性能问题。而呈现变形不会引起重新测算,呈现变形只改变元素”出现在哪里“,只涉及窗体的重绘
  11. 布局变形一般只用于静态变形,呈现变形可用于动画制作
  12. 用来制作动画的属性必须是依赖属性
  13. Storyboard是并行执行的一组动画,关键帧动画是串行执行的一组动画

  评论这张
 
阅读(2699)| 评论(0)

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018