2007年1月30日星期二

“都几唔痛下㗎喔”

做完手术啦!做嗰时有麻药,就真係唔痛嘅,之后慢慢开始痛,越嚟越痛……都係上床瞓觉好过啦,反正瞓着觉就唔知痛。

2007年1月28日星期日

非常好用的 Microsoft Expression Web Designer

我暂时不知道Microsoft的Expression Web DesignerOffice Sharepoint Designer有什么不同,对比过它们的安装选项看起来是一样的,所以暂时当它们一样吧,我现在正在使用的其实是Office Sharepoint Designer。

我最近做了一些小的CSS Template设计,就是设计出来的结果是一整个demo页面,里面已经包含各式常用的HTML元素与元素组合,并且是styled好的,让人一看上去就知道使用这套CSS Template制作出来的网站会是什么风格,同时使用者还可以根据自己的需要添加和覆盖一些CSS规则,简单来说就是类似Mollio那样的CSS Template。对我来说,Office Sharepoint Designer极为方便的地方包括:

  • 元素margin与padding的可视化,让你无需专门改动CSS就能方便看到页面上元素所占据的margin和padding。
  • CSS继承链的可视化,选择一个元素后CSS窗口选择“摘要”模式,就能显示它一路继承下来的属性,其中已经被覆盖掉的属性会用删除线标记。

有了这两项支持,设计就变得极为方便了,设计一个CSS Template只需要以下几步:

  • 用完全只考虑语义的方式,将需要styling的HTML Template写好,通常这个HTML Template包括常用的元素组合。
  • 自顶而下地进行CSS定义,在Office Sharepoint Designer中可以直接看到效果,用一个比较符合标准的浏览器测试也行。
  • 当整个CSS都定义完了,再考虑用不太标准的浏览器进行测试,并添加相应的修正项。

值得注意的是,Office Sharepoint Designer自身显示HTML可视化设计界面的解释器与IE6或IE7都是不同的(其实以前Frontpage也是独立解释器),它比IE6更符合标准,支持CSS也非常好,但实际上它解释出来的效果有可能会和IE7略有差异,所以千万不要以可视化界面中的效果为准。

2007年1月27日星期六

ASP.NET 无法确保在注册的 JavaScript 内不存在重复定义

在ASP.NET 2.0中,我们使用Page.ClientScript属性(也就是一个ClientScriptManager对象)的一些名字以Register开头的方法注册客户端脚本,这是大家都知道的。

理论上应该如何避免冲突

先说说为什么要这样注册脚本,而不用Response.Write直接输出。举个例子,你用3个DropDownList做了一个输入日期的区域,分别代表年/月/日,然后你为了防止用户输入2007/02/31,所以你决定把这3个DropDownList做成级联的,也就是随着年和月的输入改变,日的可选项跟着改变。这时候你可以通过写一些JavaScript来实现级联,例如定义一个名为updateDateRange()的JavaScript函数负责更新DropDownList,然后直接把这些JavaScript放到C#的字符串里,并且使用Response.Write输出。这些代码用起来会很正常,直到有一次你的页面需要输入两个日期。

在需要输入两个日期的那个页面上,你把3个DropDownList复制粘贴了一遍,也把输出的JavaScript的那段代码复制粘贴了一遍,接着根据两处ID的不同做了相应的修改,结果有一组级联无法正常运行起来。你查看服务器端输出的HTML,接着恍然大悟——原来有两个updateDateRange()函数。于是你把updateDateRange()改为updateDateRange(yearControlClientId, monthControlClientId, dateControlClientId),同时把JavaScript删减为仅输出一遍,这时候无论哪组级联都使用同一个函数,它们根据调用时输入的DropDownList.ClientID来区分。

又有一天,你决定把这组级联封装为一个UserControl,做起来当然还是复制粘贴大法,也就是把3个DropDownList和JavaScript复制进UserControl,然后把UserControl的引用复制回原本的调用处。忙完之后,发现那个有两个日期输入的页面又出错了,原来updateDateRange(yearControlClientId, monthControlClientId, dateControlClientId)又被重复输出了,因为页面上放入了两个UserControl所以JavaScript被输出了两遍,并且没办法减少输出次数。

这时候你可以使用Page.ClientScript.RegisterClientScriptBlock解决问题,它通过type和key这两个参数确定脚本是否被重复注册,而被重复注册的脚本仅会输出一次。为什么要type和key两个参数呢?以前ASP.NET 1.x的同类函数只有key一个参数,这带来的问题是可能两个不同的控件设计时都使用了同一个key来注册自己的脚本,结果其中一个控件脚本的成功输出必然会抑制另一个控件脚本的输出。加上了type参数,各控件都用自己的类型作为标识,这样就能有效避免注册时冲突。

为何无法真正避免冲突

关于这个问题,我们先看看ASP.NET内部定义的JavaScript是以什么方式命名的。通常,private的全局函数或变量,命名都以双下划线开头,例如大家熟悉的__doPostBack,或者是WebPartManager在客户端使用的__wpm。而public或protected的全局函数或变量,一般就好像C#那样使用Pascal命名法。具体的例子,大家可以用Reflector看看System.Web.UI的资源中的那些js文件。

我们暂时就假设这种命名法是正确的,然后模仿着去在自己开发的控件中实践。事实上很多控件开发者也确实这样做了,比较多的专业控件中你都能看到双下划线开头命名的函数或变量,这至少可以避免和控件使用者在页面上注册的函数或变量冲突,因为在页面上注册的函数或变量通常都采用比较简单的命名法。

假如现在我们要做一个浮动上下文菜单,也就是当你的鼠标移动到某个HTML元素上时该浮动菜单自动出现,当鼠标离开元素并且也不在菜单上时,菜单自动消失。为了方便用户操作,我们允许用户鼠标移动过程中稍微离开菜单区域,所以定义当鼠标离开菜单区域若干时间后才让菜单消失,而这个时间在客户端保存在__disappearAfter变量中。这个控件看起来什么问题都没有,直到你把它和ASP.NET 2.0自带的Menu控件放在同一个页面上,因为Menu控件也有类似的功能,而且和我们的控件一样Menu控件选择了将时间变量保存在一个名为__disappearAfter的变量中。

现然,作为ASP.NET框架的使用者,框架没有声明这个变量的名字不允许使用,我用了有问题当然就可以认为是框架的错。Brad Abrams写了一本《.NET设计规范/Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries》,里面却完全没有提及JavaScript和CSS的规范,好像在ASP.NET中使用到的JavaScript与CSS都是琐碎的不能在琐碎的事情,所以完全不值得一提。

事实上,既然ASP.NET允许一个页面上不同的控件设计者引入不同的JavaScript和CSS,就必须提供一种方法去管理潜在的命名冲突。如果是JavaScript,我们可以考虑使用ASP.NET AJAX的namespace来避免冲突,下一代代号为Orcas的Visual Studio和ASP.NET将内置ASP.NET AJAX支持,所以其内置控件所使用的JavaScript应该也会有namespace,这样就有有效降低冲突概率。至于CSS命名冲突,暂时没有好的解决放案,只能依赖控件设计者的习惯了,你可以考虑为你的控件根元素附上一个namespace以示区分,这样也算是降低冲突概率的一个办法。

最后,如果你希望阅读更多类似的ASP.NET主题文章的话,欢迎订阅Cat in dotNET (Feed: http://feeds.feedburner.com/CatChen/dotNET)或Cat in Chinese (Feed: http://feeds.feedburner.com/CatChen/Chinese)。

2007年1月25日星期四

放假了,要去做个小手术

又放假啦,又不知道做什么好了,暂时没有任何计划。

唯一问题是下星期一要做个小手术,有人愿意之后来探望我的话,可以联系我哦。

2007年1月14日星期日

开始学习 Cantonese Typing

对住份粤语字打法大全(2007贺岁版)慢慢睇,都几恶顶下,考虑係咪开翻个Cat in Cantonese玩下先。

Microsoft 应该学学 Sony 的“产品皆无完美”设计思想

MS现在推广Vista的最大障碍应该就是XP。虽然XP+SP2已经比较臃肿,但还是很够用的,XP潜在安全性问题虽然不少,不过既然SP2通过安全中心加上了那么多安全方面的提醒,也就够了。

Vista推广自己足够安全,然而却拿不出什么实际的例子来说明它比XP更安全——你总不能通过揭露自己一个产品的短处来推销自己的另一个产品吧。例如Vista的那个Virgin Stack,投入了去写一个全新的TCP协议栈,而放弃从原有系统的成熟代码修改而来,这点就应该拿出来卖卖广告啦,可惜至今只有安全领域的专业人士知道这个实事,大众用户对此一无所知。

Sony的聪明之处在于产品从开始设计时就注定是不完美的。Sony只有非常少数的经典产品可以称之为完美,大多数产品就算能够成为经典,也一定留下一个巨大的不足,或者说是瓶颈,让用户感到不够用,从而乐意掏钱买下一代的产品。

最明显的例子是Sony CLIE的TH55拔牙事件。在TH55上市之前,Sony官方的页面都是暗示这台PDA将成为完美机型的——蓝牙、Wifi、480*320长屏、摄像头、CLIE升级过的Organizer软件、Sony诱人的工业设计。然而就在TH55正式发布的前一个晚上,原来的官方页面被撤了下来,新换上去的页面公布这台机没有蓝牙,这导致大批的CLIE Fans愤愤,最终调解的结果是只有欧版的TH55是有蓝牙的。

TH55拔牙事件说明了Sony的产品设计思想,它就是不愿意看到有一个机型能够满足大多数用户的所有要求,然后人们买到这台机后就不再升级了。即使到了发布前的最后一个晚上,Sony也要改变主意把TH55的蓝牙拔掉,从而让买了TH55的人以后为了蓝牙功能而更新换代。

XP现在的问题就在于它已经太好用了,这无法促成用户去更新换代。或许MS也在祈求多一些XP有而Vista没有的安全漏洞出现吧,这样它就可以暗示大家为了安全所需而升级到Vista了。

我给 Google China 出主意

看到这个活动,我又参加了,嘻嘻……先说明,我觉得这个活动的题目应该标明是Google China,而非Google,它们不是同一回事,而是从属关系的两个实体。

2007年的Google China,是时候推出一些收费服务啦,要在中国从个人口袋里挖得到钱的服务。这是不是个非常违反常理的建议?正所谓“索取比给予还要好”(参考《硬球/Hardball》),如果你的用户已经愿意为你的服务而掏钱,那么还有什么他不愿意为你干的?

分享价值是Google价值观的一部分,然而分享方式确实非常美式的——我放在这里啦,你要的话你可以来拿啊,我不会强迫你要的。但这在中国是行不通的,中国人习惯了作客时主人会拿一大堆好吃的出来——你吃这个啦,这个好吃啊。当然,给你吃不是白吃的,如此热情好客的背后,当然是希望拉拢关系。甚至好像婚礼这样的,给你请贴了你不能不去,去吃了不能不封利事。这听起来很强买强卖,但中国人就习惯这样,因为不是这样半推半就的接受而是主动请求获取,反而是显得不礼貌的。

这样说来,流氓式的软件或者服务才真正体现了中国文化的精髓(或者是糟粕)。你想要,但又不好意思说,是不是?那我就硬塞给你,给个充分的理由让你接受,如此你就不拥顾虑别人在你背后怎么说你了。Google要学的就是这个,给个充足的理由用户去接受你的服务,这个理由不一定是经济上的,可以是道德上的。

“你看人家Google都把服务送到你嘴前了,你不张一张嘴,这不太合乎人情吧?”大多数人都会选择张嘴,而不是带着“不近人情”这顶帽子。好像Google这样优秀的服务,只要成功让你的用户吃上一口,后面他自然会主动要。而如果好像Tencent那样的烂服务,就每一口都要这样强迫用户去吃。

用户乐意吃了,这时候就应该收钱了。收多少无所谓,反正Google不缺这些钱,需要的就是获得用户的投票——如果你能让一个中国用户自愿给钱你,也就得到了他对你足够的信任和肯定。之后,你无论推出什么服务,这些信任你的用户总会乐意去用的。

2007年1月13日星期六

回归 Blog*Spot

现在Blog*Spot已经有一段时间没被封了,而地震之后Sitesled一直上不了,现在连Blogger也无法发布到Sitesled了,所以只好转回Blog*Spot。

转会去之后,自然考虑使用新的Layout模式,而放弃旧的Template,所以界面看起来会不同了,有些以前有的功能也暂时取消了。不过大家可以放心,这些功能很快会恢复,我考完试了就会把Layout改好,让它支持更多更好的功能。

2007年1月12日星期五

Windows 的换代与在线社区的兴衰

这看起来是两个没太大关系的主题,但实际上却是相关的。最近在看《魔鬼经济学/Freakonomics》,两个周末就看完整本书的6章了,然后就喜欢把一些没关系的东西联系起来看,看看是不是其中一个因素的变化会导致另一个因素跟随变化。可惜我没办法获得那么多的数据,很多事情只能观察其表象。

先说说操作系统与应用软件之间的联系,通常一个操作系统上面的应用软件越多这个操作系统的用户也就越多,所以Microsoft就想尽办法让Windows上的开发变得简单甚至可以说是弱智,就为了让更多人可以写Windows平台上的应用程序。当然,这种作用效果有时候也会反过来,如果一个操作系统越多人使用,开发人员也就越乐意在上面开发软件,因为面对的市场也就越广。

在线的软件技术讨论社区就如软件一样,和操作系统存在着上述联系。如果一个在线社区讨论一个操作系统及其软件的人多,就会让这社区上越来越多人选择该操作系统,当然也会让使用该操作系统的用户喜欢来此社区讨论。PDA就是一个明显的例子,有些比较倾向于Palm的论坛,就越来越倾向于Palm,例如以前的PalmStamp那样,Windows CE的用户就只有个“蜥蜴自然保护区”的板块。而另外一些论坛则倾向于Windows Mobile,Palm用户在上面就只有找电子书和漫画等资源的份了。

当年Windows XP出来的时候,就带旺了一些论坛,例如NewsFan。当然这些论坛都有一个共同的特点,就是专门为XP开一个专版,甚至几个专版。有些非常积极的XP Fans长期在上面,每次有一个新的build出来都会马上安装来看看的,然后和其他人分享一些hacks & tricks。其中的积极分子,后来成为了中国的第一批MSMVP(微软最有价值专家),技术特长当然是Windows XP,而且他们对大众用户也非常有价值——及时从MSDN Subscription下载Windows XP SP1的VLK版并与大家分享。

今年Windows Vista出来了,新一轮的受惠者中站在首位的肯定是VistaFans。VistaFans现在有多达8个Vista专版,讨论相关的各种hacks & tricks,还包括资源下载和界面美化,甚至连Windows PE 2.0也有专版。如果你是新来到VistaFans的访客,首先,你可以下载到一个Vista的RTM镜像,x86和x64版本都有;其次,你可以找到破解有关的讨论,例如现在比较多人用的TimerStop破解法(指暂停了激活倒计时);最后,你还可以参与到软硬件升级与兼容性相关的讨论来,例如支持Vista的杀毒软件和显卡驱动。即使你原本完全没考虑过要装一个Vista,到了VistaFans发现如此便捷的路径之后你也很可能会想装一个。

有受惠者自然有受害者。VeryCD向来允许发布MS的资源,却在2006年底突然禁止发布MS的OS,包括原版或修改版,其后还扩大到禁止发布任何MS的商业软件。以前TLF不允许发MS的商业软件,所以VeryCD成了一个优秀的替补,现在正是Vista发布前夕VeryCD却宣布禁止发布MS的商业软件,导致想用Vista的用户就流失到VistaFan之类的地方,留下来的用户就变得不想用Vista了,因为论坛内并不提供使用Vista所需要的便利。

2007年1月10日星期三

HP Pavilion tx1000

在今年CES上,发布了HP的第一台娱乐型的Tablet PC——Pavilion tx1000,并成为我当前的心水Tablet。

1.8G的AMD Turion™ 64 X2,加上1G的内存,还有NVIDIA GeForce Go 6150,绝对能满足现在大多数应用与娱乐的需求(玩游戏除外)。屏幕是触摸屏,好处是可以直接用手指按,坏处是不能用笔悬浮在表面画手势。

价格暂时没公布,不同的细节配置大概是$1300到$1700的范围,在Tablet中算得较低的了。不过HP好像没把它宣传为Tablet,只是当作新一代的可旋转屏幕的娱乐型notebook,并且是带有触摸屏的,只不过触摸屏加上Windows Vista Home Premium自带的Tablet支持这台机自然就成了传统意义上的Tablet了。

2007年1月1日星期一

Irreversible Writing

Blog,被我称之为Irreversible Writing,因为一旦点下了Publish按钮就没得回头。

当然,你会说之后可以删可以改之类的,但其实不是的。一旦搜索引擎爬过了你的blog,它所引的副本你就无法删除;一旦某个你不期望看到你blog的人看过了你的blog,他的记忆你也无法删除。而且现在不仅仅文字会被搜索引擎索引,图片也会。研究脸谱识别技术的网站最近也开始增多,如果你的脸谱特征被记录下来了,以后有你出现的照片也能自动识别到你的存在。未来音频与视频的索引技术肯定也会出现,那就是说发表在Internet上关于你的一切,无论是你发的还是别人发的,都难以删除。因此,在Internet上留下任何信息之前,记得先确认“无论谁看到这端信息都无所谓”,如果你想着“某人应该不会看到吧”,那最好还是不要发布到Internet上。