从0 开始 WPF MVVM 企业级框架实现与说明 ---- 第二讲 WPF中 绑定

说到WPF, 固然得从绑定提及,这也是WPF作的很成功的一个地方,这也是如今你们伙都在抛弃使用winform的其中一个主要缘由,Binding这个东西从早说到完其实都说不完的,我先就作一些基本的介绍,在咱们的项目中将会使用到的一些状况,至于一些比较深层次,不怎么会常用的到用的时候再具体介绍,其实都是一个道理,触类旁通基本都同样的,这也使万物起源的一个逻辑,任何东西都有一个核心的运做思想。html

在这以前,我想你们伙能够先看看WPF Visual Tree的一个结构,这样在你写UI的代码的时候会有一个比较清晰的认知。windows

 

想实现一个绑定的话,就得有一个数据源和一个你须要绑定的对象,数据源能够是你DataContext里的某个对象,或者是其它元素的一些DP(依赖属性)的值。绑定的目标(你想要绑定的对象)这个就看你像干什么了。框架

 

这个系统将使用的一套完整的MVVM框架模式,并且会把View和ViewModel彻底解耦,若是你在UI中想绑定一个.NET属性或者对象的话,那你的ViewModel必须实现INotifyPropertyChanged,关于这个我后面会有一个比较系统的介绍,怎样去封装这样一个机制,这样会更好管理和拓展,你们先不用着急了解这么多,先把基础的一些概念弄清楚最好,磨刀不误砍柴工是吧。spa

 

下面我就介绍下Bingding的一些基本概念:.net

 

Bingding的源介绍:有三个属性用来设置源:component

ElementName(string)、Source(Object) 和 RelativeSource(RelativeSource)--->

{orm

ElementName: 源为一个元素(Element),这里用的是此元素中设置的Name属性,好比你设置一个Grid x:Name = "Grid", 而后你想把Textbox的宽度和Grid的宽度绑定在一块儿,那你能够在textbox里这样写htm

          Width="{Binding ElementName=Grid,Path=ActualWidth}",这样Textbox的Width就会按照Grid的宽度来更新,下面我会介绍下Path是什么。对象


Source:以object做为源。<TextBlock Text="{Binding Source={StaticResource myDataSource}, Path=PersonName}"/> 这个我不多用,通常用RelativeSource居多,会比较灵活一点blog


RelativeSource: 源相对于绑定目标的位置。
                        源是元素自己:{Binding RelativeSource={RelativeSource Self}}
                        源是Tempalte中元素的Parent:{Binding RelativeSource={RelativeSource TemplatedParent}}
                        源是绑定以collection形式的前一个数据:{Binding RelativeSource={RelativeSource PreviousData}},MSDN上关于PreviousData的说明并很少,这里有一篇文章能够参考
                        以上三项为RelativeSource中的Static值,使用这些值能够减小内存开销
                        源是Ancestor(可能比parent还高):{Binding RelativeSource={RelativeSource FindAncestor,
                                                                     AncestorLevel=n, AncestorType={x:Type desiredType}}}

}

Path介绍:

Binding中的Path是 PropertyPath对象。

  • 在最简单的状况下,Path 属性值是要用于绑定的源对象的属性名称,如 Path=PropertyName。

  • 经过相似于 C# 中使用的语法,能够指定属性的子属性。例如,子句 Path=ShoppingCart.Order 将绑定设置为对象的子属性 Order 或属性 ShoppingCart。

  • 若要绑定到附加属性,请将附加属性用括号括起。例如,若要绑定到附加属性 DockPanel.Dock,则语法为 Path=(DockPanel.Dock)。

  • 在应用了索引器的属性名称以后的方括号内,能够指定属性的索引器。例如,子句 Path=ShoppingCart[0] 将绑定设置为与属性的内部索引处理文本字符串“0”的方式对应的索引。此外,还支持多个索引器。

  • 在 Path 子句中能够同时使用索引器和子属性,例如,Path=ShoppingCart.ShippingInfo[MailingAddress,Street]。

  • 在索引器内部,能够有多个由逗号 (,) 分隔的索引器参数。可使用圆括号指定每一个参数的类型。例如,可使用 Path="[(sys:Int32)42,(sys:Int32)24]",其中 sys 映射到 System 命名空间。

  • 若是源为集合视图,则能够用斜杠 (/) 指定当前项。例如,子句 Path=/ 设置到视图中当前项的绑定。若是源为集合,则此语法指定默认集合视图的当前项。

  • 能够结合使用属性名和斜杠来遍历做为集合的属性。例如,Path=/Offices/ManagerName 指定源集合的当前项,该源集合包含一样是集合的 Offices 属性。其当前项是包含 ManagerName 属性的对象。

    也可使用句点 (.)路径绑定到当前源。例如,Text=”{Binding}” 等效于 Text=”{Binding Path=.}”。

BindingExpression介绍:

这是一个基础概念,大概知道就行,Binding 类是高级别类。BindingExpression 类是基础对象,用于保持绑定源与绑定目标之间的链接。Binding 中包含可在多个 BindingExpression 对象之间共享的全部信息。也就是说,能够把一个Binding对象绑定对n个元素上,而针对这n个元素,分别有相应的n个BindingExpresion对象。
Binding能够直接绑定普通的.net实例,好比int值。可是若是后台改变int值了,前台不能显示改变后的值,这时能够调用UpdateTarget()方法更新绑定。以下:BindingExpression be = button.GetBindingExpression(Button.ContentProperty);
be.UpdateTarget(); 

 

Binding.Mode

指示源和目标间数据流的方向。

OneWay 源更新时,目标也更新
TwoWay 源更新时目标也更新,或者目标更新时同时更新源
OneTime 仅当应用程序启动时或 DataContext 进行更改时更新目标属性。绑一次就不更维护更新,目标至关于源的一次性镜像
OneWayToSource 目标更新时更新源,和OneWay相反

大部分WPF自带的控件的dependency property默认的是OneWay,像TextBox.Text默认的是TwoWay。
值得注意的事,只读属性只能设置成OneWay,不能是TwoWay,不然运行时异常。

对于 OneWay 或 TwoWay 绑定,对源的动态更改不会自动传播到目标。必须在源对象上实现 INotifyPropertyChanged 接口。 
对于 TwoWay 绑定,对目标的更改不会自动传播到源,除非绑定目标是 Text 属性。在这种状况下,更新仅在 TextBox 失去焦点时发生。 
对于 OneTime 和 OneWay 绑定,对 SetValue 的调用会自动更改目标值并删除绑定。

再次提醒,源要实现了INotifyPropertyChanged 接口才能把改变反映到目标上。

OneWayToSource 用于多个目标更改一个源的状况,能够想像成多人录入。或者用来实现源和目标倒置的状况。

 

在这里顺便提下UpdateSourceTrigger,这个你们先不用太关注,先知道在绑定的时候有这个东西

Binding.UpdateSourceTrigger

指示使用TwoWay或OneWayToSource时,目标在什么状况下更新源。有三个枚举值

PropertyChanged:目标属性改变时更新源
LostFocus:失去焦点时更新源
Explicit:只有在显式调用BindingExpression.UpdateSource方法时才更新源。BindingExpression能够经过BindingOperations.GetBindingExpression或FrameworkElement.GetBindingExpression方法得到

Binding类中提供了SourceUpdated和TargetUpdated事件,能够用来记些log,不过必须相应的NotifyOnSourceUpdated或NotifyOnTargetUpdated设置成true才会激发事件。

 

 

对于绑定的一些基本概念这里基本上是介绍差很少了,还有关于UI上的一些辅助操做,好比验证,数据转换,之类的,后面在用到的时候我会详细介绍,

这边介绍基本概念的时候我没有写一些代码上来,我以为不必,先对概念有一个基本印象就能够了,后面再上项目的时候我会用代码很好去解释一些东西。

相关文章
相关标签/搜索