学习 Silverlight 4 很受伤
silverlight 4 出来有段时间了,各网站上对它均是溢美之词,想想看,这技术也应该成熟了,心动了,就拿它练练手吧。据我原先所想,sl使用xaml做为界面语言,可使用C#开发,可使用.NET类库,开发起来应该和winform差不多吧,最多是不允许使用interop和com这些桌面相关的操作吧。在深入了解了一些资料并调试了一些程序后(网上下载的很多示例都跑不起来,可能是我火候未到吧),我发现,我错了....
事实不是我想象的那样的,感觉,silverlight4 的水很深,学习曲线很陡很陡,很受伤....
以下是现阶段我的分析,不排除有对silverlight 4 误解的地方,欢迎指正解惑(以下将用sl 4做为 silverlight 4的简写)。
1. SL 4 可使用的类库
首先,sl 4可使用的类库大大阉割了,此外也新增了很多它专有的陌生的类库。
以下是sl 4可用的数据集(我承认,是我手贱手打的,目的是加深印象):
2 Microsoft.VisualBasic
3 mscorlib
4 System
5 System.Core
6 System.Json
7 System.Net
8 System.Numerics
9 System.Data.Services.Client
10 System.Runtime.Serialization
11 System.Runtime.Serialization.Json
12 System.Xml
13 System.Xml.Linq
14 System.Xml.Serialization
15 System.Xml.Utils
16 System.Xml.XPath
17 System.ComponentModel.Composition
18 System.ComponentModel.Composition.Initialzation
19 System.ComponentModel.DataAnnotation
20 System.ServiceModel
21 System.ServiceModel.DomainServices.Client
22 System.ServiceModel.DomainServices.Client.Web
23 System.ServiceModel.Extensions
24 System.ServiceModel.NetTcp
25 System.ServiceModel.PollingDuplex
26 System.ServiceModel.Syndication
27 System.ServiceModel.Web
28 System.ServiceModel.Web.Extensions
29 System.Windows
30 System.Windows.Browser
31 System.Windows.Controls
32 System.Windows.Controls.Data
33 System.Windows.Controls.Data.DataForm.Toolkit
34 System.Windows.Controls.Data.Input
35 System.Windows.Controls.Data.Toolkit
36 System.Windows.Controls.DataVisualization.Toolkit
37 System.Windows.Controls.DomainServices
38 System.Windows.Controls.Input
39 System.Windows.Controls.Input.Toolkit
40 System.Windows.Controls.Layout.Toolkit
41 System.Windows.Controls.Navigation
42 System.Windows.Controls.Theming
43 System.Windows.Controls.Theming.*
44 System.Windows.Controls.Toolkit
45 System.Windows.Controls.Toolkit.Internals
46 System.Windows.Data
对,只有这么多类库可用!大大阉割了。大体上,这些类库可以分为以下几类:
·mscorlib、System 和 System.Core 这几个是.NET的核心类库,完整迁移到sl了
·Microsoft.CSharp 和 Microsoft.VisualBasic 这里表明可以使用 c#和vb.net特有的一些语言特性
·System.Json 和 System.Xml 这两个说明可以支持json和xml,心里有了个底
·System.Net 这个是好东西啊,点开看看!它支持Socket,WebClient,WebRequest等类,看来sl4在网络方面是下足了血本~
·System.ComponentModel.* 这个....对,在mvc项目中见到
封装了对数据模型操作的一些辅助类
如使用DataAnnotabion可以使用特性标签的方式对类的成员做方便的校验,没想到在sl里面见到老朋友了:)
·System.ServiceModel.* 这个是新东西
在接触几个示例代码后,发现这是和wcf data service, wcf ria service相关的一些类库,封装了sl和服务器端的通讯协议
这玩意....很庞大很陌生,要好好看看
·System.Windows.Controls.* 这个.....比较晕,对这些类库我有很大意见:
关于命名空间
看到这个命名空间,先是愣了一下,还以为是winform用的,狠不幸,它给wpf和silverlight无情的征用了:<
老的winform控件库在哪儿呢?倒是没搬家,还是在System.Windows.Forms下面
很显然,从这点看:
(1)WPF和Silverlight共享一套控件类库;
(2)并未使用 System.WPF 或 System.Silverlight命名空间,看来ms对wpf和sl的将来抱有极大的期望,取代winform是时间早晚的事?
此外,WPF的控件太分散了
它们分布在若干的命名空间中(而winform的控件完全在System.Windows.Froms下)
这会造成什么影响呢,以下就是它给xaml带来冗长的弊病以及编程上记忆困难的毛病,如下:
xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"
xmlns:dataForm="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.DataForm.Toolkit"
xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
<riaControls:DomainDataSource ...>
<data:DataGrid ... />
2. SL 4 阉割掉的重要类库 System.Data.*
看着看着,忽然就疑惑了,数据操作呢?这么不见 System.Data.* 相关类库呢?
对!就是没有!这意味着不能使用 ADO.NET 操作数据库,这个狠啊,阉割得利害.....
经过查资料,调程序,得知sl可以使用 socket, webclient, webrequest, wcf, wcf data service, wcf ria service 来访问服务器数据。
(1)其中,socket是要自己写通讯逻辑了,包括数据的结构,这适合游戏编程,若用来传递大批量的数据库数据,还有很大的封装代码量要做。
(2)wcf简化了socket编程,可少关注些交互协议,数据量不大的情况也可以用做游戏编程,简单封装后也可以用于传递数据库数据,这个网上见到几个例程。
(3)webClient和webrequest可以用http协议访问网站,这个.....可以用这个返回text、xml、json等文本数据,那么原有的jquery+webhandler架构就可以利用起来了。不过,sl4既然没有javascript了,json格式还有什么用呢?用System.Json还原成类对象应该是一个路子,这个有空可以做个示例。
(4)wcf data service 原先好像叫 ado.net data service,还有wcf ria service,是微软提供的服务器端数据访问框架,是基于 linqToDb 和 EntityFrameWork 的,现阶段好像只支持 sqlserver。访问其它数据库?呃.....这个......我想,也不是不可以,应该有很大的工作量要做。
注:本来打算使用 sl来建类似 orale plsql developer 的软件,忽然就迷茫了,首先,sl4不支持ado.net无法直接操作数据库,此外,socket还有古怪的安全策略,先要用943端口给sl传递一个Policy文件,老的数据库端口程序当然没有这种逻辑,这个.....怎么玩?看来sl4好像就是限制死不能与老程序直接用socket通讯,必须重新开发服务器端程序。
注:至于其它阉割掉的类库或功能,可创建 Silverlight 类库项目,自己用代码实现,这是一个路子
3. 古怪冗长不合常规的xmal语法及属性定义方法
为什么要用外部属性:x:Name 而不是 Name?
<Button x:Name="addNewEmployee" Width="90" Content="Add Employee" Margin="4,0,0,0"/>
难道 Button 连个 Name 或者 ID 属性都没有么?
此外,为什么用 Content 属性,而不是 Text 属性?
为什么绑定表达式这么古怪且冗长?
<data:DataGrid ... ItemsSource="{Binding Data, ElementName=employeeDataSource}" />
<data:DataPager ... Source="{Binding Data, ElementName=employeeDataSource}" />
为什么数据源有这么多的名称?ItemSource, Source, 为什么不用传统的 DataSource?
为什么不直接是:<data:DataPager ... DataSource="employeeDataSource" />
为什么资源表达式这么古怪且冗长?
<TextBlock Text="Employee List" Style="{StaticResource HeaderTextStyle}" />
为什么不直接是:<TextBlock Text="Employee List" Style="HeaderTextStyle" />
为什么控件表达式这么冗长:
<riaControls:DomainDataSource.DomainContext>
<ds:OrganizationContext/>
</riaControls:DomainDataSource.DomainContext>
<riaControls:DomainDataSource.SortDescriptors>
<riaControls:SortDescriptor PropertyPath="VacationHours" Direction="Ascending" />
</riaControls:DomainDataSource.SortDescriptors>
<riaControls:DomainDataSource.FilterDescriptors>
<riaControls:FilterDescriptor
PropertyPath="VacationHours"
Operator="IsGreaterThanOrEqualTo"
IgnoredValue=""
Value="{Binding ElementName=vacationHoursText, Path=Text}" >
</riaControls:FilterDescriptor>
</riaControls:DomainDataSource.FilterDescriptors>
</riaControls:DomainDataSource>
而不是
<riaControls:DomainDataSource Name="employeeDataSource" LoadSize="20" QueryName="GetSalariedEmployees" AutoLoad="True">
<DomainContext>
<ds:OrganizationContext/>
</DomainContext>
<SortDescriptors>
<SortDescriptor PropertyPath="VacationHours" Direction="Ascending" />
</SortDescriptors>
<FilterDescriptors>
<FilterDescriptor
PropertyPath="VacationHours"
Operator="IsGreaterThanOrEqualTo"
IgnoredValue=""
Value="{Binding ElementName=vacationHoursText, Path=Text}" >
</FilterDescriptor>
</FilterDescriptors>
</riaControls:DomainDataSource>
4. 其它感觉到不爽的地方:
在vs2010中 xaml 展示很慢很慢很慢,比aspnet webform 还慢得多
为什么sl程序调试时不能更改代码?
为什么sl不支持二进制序列化?
sl调试时经常遇到莫名奇妙的错误,浏览器显示错误,空白一片
以上是个人学习sl 4遇到的一些疑问,请知情的园友不啻解答,非常感谢
------- 我是淫荡的分隔线 ----------------------------------------------------
/*备注*/
先谢谢大家的解答了:)
看了两天的书《Silverlight 4 in action》(推荐看看不错的),稍微解开一点疑惑,这里大致先写一下我的收获:
(1)关于 x:Name 属性
WPF是支持用Name的,而silverlight只能用x:Name
而且该书作者说为了兼容性,最好还是写成 x:Name
但是....我还是讨厌x:Name,能简就应该简,去掉x,若能改用ID那是更喜欢
(2)Content 属性我理解了,这个可以接受。
WPF绝大部分的控件都是继承至ContentControl,该类正代表了WPF灵活的UI模型
该控件内部可以容纳任何UIElement对象,举个Button的例子,以下三种写法都可以:
<Button Width="150" Height="75" Content="Hello!" />
<Button Width="150" Height="75">
<Button.Content>
<TextBox Height="24" Text="TextBox" Width="100" />
</Button.Content>
</Button>
<Button Width="200" Height="100">
<StackPanel>
<TextBlock Text="Playing" HorizontalAlignment="Center" />
<MediaElement Height="75" Width="125" Stretch="Uniform" Source="PeteAtMIX10ch9.wmv" />
</StackPanel>
</Button>
(3)关于命名空间+对象+属性的表达式,我觉得还是相当的冗长,像这种语法:
<riaControls:DomainDataSource
<riaControls:DomainDataSource.SortDescriptors>
<riaControls:SortDescriptor PropertyPath="VacationHours" Direction="Ascending" />
</riaControls:DomainDataSource.SortDescriptors>
...
</riaControls>
缠缠绵绵浩浩荡荡的,简直不具备可读性
(4)关于数据绑定,也觉得相当的冗长。
首先是表达式:
<data:DataGrid ... ItemsSource="{Binding Data, ElementName=employeeDataSource}" />
为什么不干脆一点用DataSource="employeeDataSource"呢
其次,WPF中表示数据源的属性不统一,据我所知的有:
属性名 使用者
------ -------
ItemsSource DataGrid
Source DataPager
DataContext Grid
为什么不统一呢?有种感觉,微软的 WPF 和 ASP.NET 项目组似乎没有什么互动交流。
属性名称这种东西是小,但遵循一致性的设计是很重要的,可以减少很多疑问。
(5)关于去除ado.net的问题,仔细想想炭炭同学说得是对的
虽然说sl4支持tcp/udp,理论上直连数据库是没有问题的。但对于公开在广域网上的程序,如此多的客户端都保持数据库连接的确是不可想象的,只能用服务器端统一处理。
我的本意是想做一个基于浏览器的类似 oralce plsql developer 那样的软件,实现数据库的管理以及语法高亮什么的,使用者不会太多,所以希望可以直连数据库,且不需要服务器。既然sl不支持ADO.NET,那只能另寻它法。
题外话,现在桌面的程序,大部分都可以改造成浏览器版本,而sl就是一个很好的载体。若不考虑操作系统兼容的话,用浏览器承载WPF也不错。
(6)总得说来,xaml属性的语法我还是觉得很罗嗦,可读性比较差,不够清爽
尤其是看惯了mvc view 辅助属性的简洁语法后,再来看xaml,觉得像眼睛里脑子里有一团毛线似的,晕忽忽的
xaml可以看做是标准的xml,很严谨。但反过来说,xml太罗嗦了,所以才有json的兴旺
也许,我感觉,以后会出现新的wpf界面引擎的,就像mvc下面的rasor一样
(7)此外,想咨询下,关于sl4与服务器端的数据库数据通讯,大家都采用什么技术?
个人感觉wcf dataservice 和 wcf ria service 的实施对现有项目架构(基于jquery+服务器端生成json)的改动很大,老的技术积累都利用不起来;
且ria service自动生成缠缠绵绵的代码,将技术细节封装得太高层了,心里总是没有那种看到实际代码逻辑,心里踏实的感觉
此外,这两项技术和sqlserver结合太紧密了,以后想做数据库迁移是很困难的事,虽然说有各种开源项目支撑,如EntityFrameWork for oralce,但我需要一个灵活切换底层数据库的架构,不可能每切换一个数据库就去找相应的类库,如 EntityFrameWork for sqlite, for mysql, for .....
那么,我自己是倾向于用 webrequest 和 webclient 来请求json数据这种方案(当然,可以做些遍历封装),这样服务器端逻辑都不用改动。
你们呢?
昨天把随笔发出来后,感觉有些不安,毕竟对sl4了解得不够深,发表这些看法不够稳妥。但反过来想想,让完全没有接触过sl的程序员来编程,才能看出sl的易用性和学习难度如何,我也就坦然不改动原文了。虽然之前没有真正编写sl程序,但跟踪它已经很久了。微软的开发类产品,大家都知道的,没有3个版本是不会稳定的。在未稳定前,可以学习它,但不要轻易使用在产品中,除非经过详细的测试或者有这个专业需求。
平心而论,就功能而言,sl4的功能已经足够完善,至少足以与flash抗衡甚至更高出一些。毕竟是晚些出现的,可以汲取前者的优点,而且有语言上和开发环境上的优势。这次算是将它用作实际项目中,但我发现sl4的学习曲线并不平坦,光看网页上大家发表的一些sl功能文章是无法掌握sl的设计实现和编程原理,最终还是不得不静下心来下载出版的书籍来看。
题外话,再次推荐一下这本书《silverlight 4 in action》,这本书入门足够了,网上林林总总的sl文章也可以不用浪费时间看了,有很多还因为版本问题代码已经不能用了,会浪费学习时间。
再次谢谢大家热心的解答
转载请注明出处:http://surfsky.cnblogs.com