随笔-3  评论-29  文章-0  trackbacks-0

   自Silverlight(以下称SL)1.0 Alpha发布一来,一直对该技术备加关注,加上项目组正好有用到该技术,所以对SL也有了一定程度的了解。SL是一种强大的RIA技术,但同时由于其产品的不成熟,存在很多困扰开发者的问题。不论是对中文的支持,还是对媒体播放的支持,还是对WebService的支持,SL都没能提供很好的解决方案。(当然SL2 Beta 1对中文支持已经很好了)。其实本人一直看好SL,但所谓爱之越深,恨之越切,在此就仅对SL 2Beta 1的不足之处作个说明。当然,如果有不对之处,还请博友们指正。

  Silverlight 2 Beta 1版本缺陷列表

  1、WebService不支持同步调用
        在SL工程中添加Service Reference后,自动生成代理类ServiceSoapClient,实例化ServiceSoapClient后,我们只能看到异步调用的方法。比如,我的WebService提供了一个GetVideoTypes方法,在ServiceSoapClient中却只有GetVideoTypesAsync与GetVideoTypesCompleted,前者是异步方法,后者是相应的事件。上网找了资料,发现在有的外国论坛上,有人也提出了这个问题。

  2、WebRequest不支持同步调用
   与WebService一样,WebRequest也不支持同步,具体不再详述。在此说一下,WebRequest在System.Net.dll中,大家在开发时要自动引用一下。

  3、System.Runtime.Serialization.Json.DataContractJsonSerializer方法不友好
   在SL2 Beta 1中用JSON,我只想说,这是一个比较奢侈的要求,目前MS封闭的System.Runtime.Serialization.Json.DataContractJsonSerializer类接口函数很不友好,只支持ReadObject与WriteObject,没有我期待的Serialize与Deserialize。呵呵,你看看ReadObject接受的参数是什么,Stream!!哈哈,你还要构造一个Stream,而如果在分布式系统中,这个Stream就要从WebRequest与WebResponse得到了,嘿嘿,这两类还不支持同步调用。麻烦啊。不过我记得早期版本是有Serialize与Deserialize的,不知道是给去掉了,还是我没找到。
  BTW,System.Runtime.Serialization.Json.DataContractJsonSerializer在System.ServiceModel.Web.dll中,很不好找啊。

  4、对相对路径支持很不好
  我有一个视频播放的页面,要动态加载一些图片,一开始这可把我难住了。因为SL是客户端执行的,而这些图片是在服务器上。我在Xaml中直接写相对路径如"images/1.png",不好使。为什么呢,我觉得也是可以理解嘛,毕竟SL在客户端执行,客户端哪有这个文件,但你SL的Runtime是不是应该动态的去服务器把这图片download下来啊。我记得老版本是可以的啊。没办法,我一开始只能写完整的uri,如http://localhost/vodsl/images/1.png。
  不过还有一个奇怪的现象,在同一个SL页面中,有的图片显示不出来(如果用相对路径的话),但有的图片又可以显示。My God,想来想去,答案是:SL还是做了动态下载,只不过这个下载可能在SL渲染后完成,就是说有的图片下载不赶趟了。

  
   5、重绘SilderBar控件会让你抓狂
  SL 2 Beta 1引入了TextBox Button ScrollBar等控件,值得夸奖,毕竟在1.1时,自己封装TextBox 还麻烦了(绝对地狱似的编程)。
  而这些控件在美观上是远远不能满足人们日益增长的审美要求的。于是乎,我想重绘它们。感谢SL为我们提供了重绘控件的机制。具体方法是为控件(如:Button ScrollBar)指定Style,这个Style其实就是一个Resource,你可以直接在Xaml中写。但要写在相应控件的前面,否则在运行时,SL会认为控件的Style是一个无效对象。
  但定义这一个Style可不简单耶!!看看SDK中的例子,那是相当长的一段代码。而且你很难知道控件的各个元素叫什么名(我是通过SDK/Google才知道的)。很不人性啊。其实我就是想改一个小滑块的样式,(ScrollBar中的小滑块),就要写一大堆Xaml。大家可以试试,我是花了很长时间才明白这大堆Xaml的具体含义。
  好了,终于可以自定义ScrollBar的样式了,但发现ScrollBar总有一个背景图去不掉,就是下面这个图片:

  无论我怎么修改Style,这个底图总存在。没办法,我最近只好放弃重绘ScrollBar。

  6、说说Grid与DataGrid
  Grid是SL的一个相对定位容器,在Grid中的控件是不能绝对定位的,如果你也与我一样试图在Blend中拖动Grid中的控件,一定感触颇深。我觉得这是很合理的,Grid就像Html中的Table,可用作页面整体的布局,事实上SL的很多控件(比如ScrollBar)内部也是用Grid布局的。但Grid没有提供Rows.Add与Columns.Add等接口,在想动态放置子控件时比较不方便。但Grid引入了RowDefinition与ColumnDefinition的概念,这个我个人比较喜欢。它实现了Grid布局定义与子控件放置的分离,你先定义Grid有几行几列,然后在后面加子控件,再为这些子控件指定Grid.Row与Grid.Column,这样就避免了HTML Table中的层层嵌套。这样的缺陷就是不代码不直观。
  BTW,Grid的单元格似乎不能自动随子控件撑大,我只看到了Maxheight与MinHeight属性,但似乎不能实现这个功能。
  DataGrid居然没有Rows.Add接口,但有Columns.Add接口。

  7、有些属性要通过SetValue与GetValue方法
   .Net 3.0与SL引入了DependencyProperty机制,很好很强大,我们可以在一个类中定义属性,然后别的对象也能用这个属性,没有明白?比如说在Canvas中定义了Left,我们可以在任何控件对象中SetValue(Canvas.Left,v)。凡是可以嵌在Canvas中的控件都可以通过这种方式来设置Left;而Grid也有LeftProperty,同样,凡是可以嵌在Grid中的控件都可以SetValue(Grid.Left,v)。仔细想想,不难发现,在任何一个控件对象中SetValue(Grid.Left,v),最终都会调用Grid类中的一段逻辑。你要是自己定义一个容器控件,比如MyPanel,你在这个类中加一个LeftProperty,然后实现一个设置子控件Left的逻辑,那么所有子控件都可以SetValue(MyPanel.Left,v)了。(关于DependencyProperty以后再说)
  用DependencyProperty定义控件属性的缺点就是不方便,如果是GetValue还要将返回值强制转换。即使是Left,Right这样的常用属性,也要通过SetValue与GetValue方式,很是麻烦。相信下一版本的SL会封闭友好的属性接口。当然这仅仅是为了一个方便而已。


      如果大家发现有地方说的不对,还请指正。

Tag标签: Silverlight
posted on 2008-04-22 16:22 snowwolflibo 阅读(1643) 评论(25)  编辑 收藏 网摘

评论:
#1楼  2008-04-22 16:49 | R2      
SL2 BETA 2已经出来了吗?
  回复  引用  查看    
#2楼  2008-04-22 17:01 | nasa      
增加一个 random 方法还是有问题. 不是每次都能随机.
  回复  引用  查看    
#3楼  2008-04-22 18:03 | Windie Chai(笑煞天)      
估计DependencyProperty不会消失.....

还有,Silverlight 2 beta1读取RSS是有bug的,例如Google Picasa这样的rss就无法读取,但WebRequest是一个比较通用的类,所以可以想象应该还有许多东西是无法通过WebRequest读取的.
  回复  引用  查看    
#4楼 [楼主] 2008-04-22 18:20 | snowwolflibo      
呵呵,似乎真不能在控件中加Left与Top属性,因为该控件并不知道自己在什么容器里面,还得借助DependencyProperty.
  回复  引用  查看    
#5楼  2008-04-22 22:56 | PerfectDesign      
我晕~~~~
你还真.....................


顶啊~~~呵呵,我都无语了
  回复  引用  查看    
#6楼  2008-04-23 00:19 | Yannic Yang      
呵呵,毕竟是beta1
自从那个相对路径让我抓狂后,我开始彻底拒绝sl...等正式版
关于dp的问题,你说的每个控件都能用leftproperty那种方式叫attachedproperty,sl中实现还不太完善,wpf里已经很完善了
大致需要封装两种,一个是grid.Width这样模拟传统属性,另一种是类似canvas.SetLeft(v,150)
这样封装attachproperty
我这两天正在写关于dp的文章,dp确实很好很强大,呵呵
  回复  引用  查看    
#7楼  2008-04-23 01:40 | Scott Xu(南方小鬼)      
rgxs
  回复  引用  查看    
#8楼  2008-04-23 01:43 | Scott Xu(南方小鬼)      
同步请求放在sl初始化里不可以吗,或者 Page_Loaded事件下
  回复  引用  查看    
#9楼  2008-04-23 08:24 | Kains [未注册用户]
为啥flex可以直接对控件的left,top这些属性直接操作,sl还要转一下。这个很难理解,难道是应为dp得好用?相对dp的使用 flex 的实现简单明了得多了。
  回复  引用    
#10楼  2008-04-23 08:35 | 李战      

  回复  引用  查看    
#11楼  2008-04-23 09:21 | 生鱼片      
路过
  回复  引用  查看    
#12楼 [楼主] 2008-04-23 10:49 | snowwolflibo      
@Kains
是啊,不能直接给控件加Left,Top.因为控件有没有Left,Top不是取决于它本身,而是取决于它放置在什么容器里.
如果将控件放置在Grid中,Left,Top就没意义,因为Grid里的控件是相对定位,这时就得用Grid.Row与Grid.Column来定位
如果控件放置在Canvas中,就需要Canvas.Left与Canvas.Top来进行绝对定位了

  回复  引用  查看    
#13楼 [楼主] 2008-04-23 10:50 | snowwolflibo      
@Scott Xu(南方小鬼)
没明白你的意思
  回复  引用  查看    
#14楼 [楼主] 2008-04-23 10:52 | snowwolflibo      
@Yannic Yang
期待你的大作
我也很欣赏DependencyProperty机制,与接口耦合性更小,复用性也很高.但就是违背OO.
  回复  引用  查看    
#15楼  2008-04-23 10:57 | Microshaoft      
顶下波波先 收藏先

  回复  引用  查看    
#17楼 [楼主] 2008-04-23 11:22 | snowwolflibo      
个人觉得SL只是微软的一个中间技术,最终还得是WPF.
它的存在应该是微软的一个临时战略.

因为MS想通过他的.net 技术实现RIA应用,但目前大部分用户都装的是XP系统,没有.net,更没有.net 3.0,推广WPF的难度可想而知.所以"临时"推出SL.

但SL的CLR毕竟与.net不一致,且基础类库也大相径庭,更不用说第三方组件,这样一来,所有在.net中得心应手的功能在SL中就没有相应实现.

你看看SL中,对DataSet,Xml,Json,WebService,WebRequest目前都没有很好的支持,这也不能怪MS.毕竟要将.net中的相应功能移植到SL中也是一项目浩大的工程.

由于以上原因,SL开发就多少会受到限制,(就是程序员都觉得SL开发不如标准.net开发那么爽).

还是期待MS下一版本早点普及,这样客户端的RIA技术可真就很好很强大了.MS那些SL研发人员也没必要成天移植.net的相关功能了.
  回复  引用  查看    
#18楼  2008-04-23 11:29 | Scott Xu(南方小鬼)      

两种思路:        
        public App()
        {
            this.Startup += this.Application_Startup;
            this.Exit += this.Application_Exit;
            this.UnhandledException += this.Application_UnhandledException;

            InitializeComponent();
        }

        private void Application_Startup(object sender, StartupEventArgs e)
        {
            this.RootVisual = new Page();
            //new WebRequest......
        }


或者

        public Page()
        {
            InitializeComponent();
            this.Loaded += new RoutedEventHandler(Page_Loaded);
        }

        void Page_Loaded(object sender, RoutedEventArgs e)
        {
           //new WebRequest......
        }


  回复  引用  查看    
#19楼 [楼主] 2008-04-23 11:33 | snowwolflibo      
@锦瑟
你的办法确实可以,但把资源文件溶入到xap中,这个xap也太大个了
  回复  引用  查看    
#20楼  2008-04-23 12:12 | Yannic Yang      
@snowwolflibo
不觉得DP不OO..反倒觉得是种很好的模式~
算了,不讨论OO不OO了....针对这个问题我花了一中午专门写了篇文章~
http://www.cnblogs.com/yayx/archive/2008/04/23/1167110.html
欢迎讨论~
  回复  引用  查看    
#21楼  2008-04-23 12:13 | Yannic Yang      
@锦瑟
这篇文章挺受用……
还是那句话 SL毕竟还是beta,很多方案没有统一下来,我先研究wpf搞项目 然后等正式版 呵呵
  回复  引用  查看    
#22楼  2008-04-23 13:23 | swsd [未注册用户]
补充一个,SL好像不支持WSHttpBinding。
  回复  引用    
#23楼  2008-04-23 18:08 | PerfectDesign      
不会吧?竟然不支持wcf里面最常用的绑定方式?
  回复  引用  查看    
#24楼  2008-04-23 21:43 | 膘汉      
不支持H.264编码的视频,只能用微软自家的VC-1编码,但是效果比H.264烂啊。这个当然不算错误。

开发SL就好像是给WM开发软件,到处受限制,总是需要想尽办法绕过这些限制。

顺便问下如何在SL里使用System.IO往用户的磁盘上写数据?正在用SL做一个P2P视频项目,客户端接收到的数据只能写到内存里,不能保存到用户的磁盘上。这样客户端可以分享的数据就只有内存里那点,太少了。
  回复  引用  查看    
#25楼  2008-07-13 21:31 | 孤鹰 [未注册用户]
确认一下:
确实是不支持WSHttpBinding。Silverlight测试版只支持BasicHttpBinding,正式版不知道行不行。有知道的回帖告诉一下,期待中。。。
@swsd

  回复  引用    

标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2008-04-22 16:59 编辑过
Google站内搜索


China-pub 计算机图书网上专卖店!6.5万品种 2-8折!
近千种 9-95 新二手计算图书火热销售中!

相关文章:


相关搜索:
Silverlight

相关链接: