首页 > 代码库 > Silverlight项目笔记1:UI控件与布局、MVVM、数据绑定、await/async、Linq查询、WCF RIA Services、序列化、委托与事件

Silverlight项目笔记1:UI控件与布局、MVVM、数据绑定、await/async、Linq查询、WCF RIA Services、序列化、委托与事件

    最近从技术支持转到开发岗,做Silverlight部分的开发,用的Prism+MVVM,框架由同事搭好,目前做的主要是功能实现,用到了一些东西,侧重于如何使用,总结如下:

    1.UI控件与布局

    2.MVVM

    3.数据绑定

    4.await/async

    5.Linq查询

    6.WCF RIA Services

    7.序列化

    8.委托与事件

    1.UI控件与布局

      常用的主要是Grid、StackPanel、Border,其中最常用的的是Grid,是一种行列组成的网格布局,特别是划分一个面板的区域时很方便,如图所示,通过Grid.RowDefinitions将整个面板划分为两大部分进行布局设计,而在局部泽运用了Grid.ColumnDefinition来进行列的划分,通过使用Grid能够快速将一个面板进行网格划分,实现自己的页面布局。

      

    StackPanel则是一个允许对所属内容进行水平或垂直排列的容器,Border这个的特点则在于可以添加边框,如图所示,通过BorderThickness和BorderBrush分别设置边框的粗细和颜色,Grid.Column="3"指的是这个Border在网格中的位置为所属网格的第四列,当然,网格中还可以嵌套网格,相当于一个网格中再进行网格划分。

        

     目前偏向于使用Grid,一个容器里需要设置多项时就Grid里在嵌套Grid,因为使用最方便,设计起来容易,需要边框的时候使用Border。

     需要特别注意一点的是,设计界面的时候一定要考虑容器大小发现变化,比如用户对窗口进行缩放,所以最好使用相对布局。

     不建议指定Width、Height,最多使用"Magrin"来设置控件与父容器边框的距离,多用“HorizontalAlignment”和“VerticalAlignment”来设置控件的位置,这样窗口大小发生变化时布局才能统一协调。

     另外有时还需要对UI控件的模板进行重写,比如ListBox里放置TextBlock来显示绑定的数据,对符号设置旋转角度等等,这时就需要根据实际应用情况进行设置。

     

     

    另外,项目中使用了第三方控件Telerik的RadControl For Silverlgiht系列,效果还不错,而且基本为所有语言提供了精心制作的UI控件,地址http://docs.telerik.com/

    2.MVVM  

    熟悉MVC了后对MVVM就能很快熟悉,关于MVC如果还陌生可以参考斯坦福公开课学习笔记1来帮助理解,也是为了将界面与逻辑分离,界面View即V还是直接在xaml中设计,ViewModel即VM逻辑实现则单独写在一个文件,是UI与逻辑的分离,数据传递则通过在xaml下的cs文件中使用DataContext与ViewModel这一层进行绑定来实现。

   

    

    这中间遇到一个问题,如果MVVM模式下要求一个操作后关闭自身窗口如何实现?这不是与MVVM模式下UI与逻辑分离相违背吗?

    有三个方法,一是通过将V窗口传到ViewModel里去,然后去控制关闭,这显示违背了MVVM模式设计初衷,但是这里由于使用了第三方控件,在ViewModel中接收传递过来的窗口这个参数时,强制转换遇到一些问题,故不用此法。

    二是严格遵守MVVM模式来实现View与ViewModel进行交互,暂时未实现,感兴趣参考这篇博文http://www.cnblogs.com/henryzhu/archive/2013/01/26/mvvm-viewmodel-view-interaction.html 

    三是直接将关闭窗口这个动作“this.close"传递进去,然后在ViewModel中触发这个动作即可,这个简单可行,暂时用此法。

    

    

    3.数据绑定

     需要改变UI上的显示的数据,最直接的就是给UI控件设置标示符,写代码时根据标识符找到控件,更新数据即可。

     但是在MVVM下,稍有些不同,需要进行绑定设置。

     

     

     有几个需要注意的是,

      一是IValueConverter接口,当UI上有一项值是根据一个变量的返回值来确定,但是返回值是是int类型的数字或其他,但要求显示的是文字,例如,返回值1代表“在审”,返回值为2则代表“未审”,可以通过IValueConverter这个转换器接口实现,重写Convert、ConvertBack两个方法即可。详细参考:http://www.silverlightchina.net/html/study/WPF/2012/0913/18875.html

     

     

     二是INotifyPropertyChanged接口,如果某一项值改变了,如何通知UI也去更改呢,例如页面上显示根据不同条件查询出来的异常数据数量AbnormalProjectCount,如何让UI知道这个值改变了呢?通过继承INotifyPropertyChanged接口即可。

     

           

              

     4.await/async

     .Net FrameWork4.5中新的关键字await/async,当使用await时,方法中需要声明为async,作用是当执行到await的方法时,当前方法会挂起,知道await方法执行完毕返回值后再继续执行。

     

     

    5.Linq查询

    在上图中有这样一段代码,使用的就是Linq查询,根据Linq的介绍,使用LINQ 可以查询C#中许多不同的数据源,包括对象、SQL 数据库、XML 文档、实体数据模型和外部应用程序。

    

    6.WCF RIA Services

     Silverlight中如何与数据库交互,实现增删改查呢?答案是WCF RIA Services,但是有几点需要注意:

     (1)数据库对应的表必须要有主键,否则设置时读取不了实体类;

     (2)实体模型的属性设置中,Code Generation Strategy这一属性设置为“Default”;

     (3)删除后缀为.tt的两个文件;

     (4)建立域服务DomainServices前注意先编译一般,不然无法读取到更新的实体模型类。

      详细关于WCF RIA Services的使用以及设置注意事项参考MSDN的资料:

      演练:创建 RIA Services 解决方案 

      http://msdn.microsoft.com/zh-cn/library/ee707376(v=vs.91).aspx

      "Some Entity Framework context classes may have been excluded" message when adding a new Domain Service Class“

       http://support.microsoft.com/kb/2745294

     7.序列化

      程序运行时,数据对象都保存在内存当中,当需要解析文件读取数据或根据数据生成对象并保存成文件时,就需要进行序列化和反序列化,以XML文件为例。

     

     8.委托与事件

    应用场景:B窗口提交了数据,A窗口中数据列表需要自动更新,就可以通过委托与事件来实现,类似地,在地图上框选一个范围,自动读取范围值并显示出来也可以通过委托与事件实现。

   

   使用步骤是:

   (1)定义委托与事件

   

   (2)定义发布事件的类(调用它会触发事件),在B窗口中提交数据后触发事件。

   

 

    (3)订阅事件,以及处理事件的方法,在A窗口的构造函数中订阅事件,这样当B窗口提交数据后,A窗口订阅到这个事件,知道数据更新了,重新获取一次数据,数据列表就更新了。

       

    类似于iOS中的delegate与Flex的消息机制。