为了能快算理解算法,下面十分直观的描述一下算法,完整而严谨的描述请参考其他资料对辗转相除的描述。
问题:求a,b的最大公约数g
解决:不妨设a = alpha * g, b = beta * g且a > b
让大的减小的, 得到两个数 (alpha - beta) * g, beta * g
再大的减小的, g的系数越来越小, 这样减下去,直到g的系数成为一了,就把g找到了.
当然在实际计算中a, b不能是写成alpah * g, beta * g的形式的(都写成这样了,还用计算么?), 所以就反复你减我,我减你,直到得到两个相等的整数为止.这个整数就是a和b的最大公约数了.
日期 | 時間 | 課程名稱 | 講師 | 類型 | 初學者參加 |
2004/08/09 ~ 2004/08/13 | 上午 9:30 ~ 12:00 | 網頁基礎設計 | 陳劍恒 | 入門 | 可以,免基礎 |
2004/08/09 ~ 2004/08/13 | 下午 13:30 ~ 16:30 | FreeBSD入門教學 | 黃世銘 | 入門 | 可以,免基礎 |
2004/08/16 ~ 2004/08/20 | 上午 09:30 ~ 12:00 | 一周學會PHP接案 | 孫仲岳 | 入門 | 可以,免基礎 |
2004/08/16 ~ 2004/08/20 | 下午 13:30 ~ 16:30 | 網路概論 | 陳威任 | 入門 | 可以,免基礎 |
2004/08/30 ~ 2004/09/03 | 上午 09:30 ~ 12:00 | JSP網頁設計入門 | 歐陽芳泉 | 入門 | 可以,免基礎 |
2004/08/30 ~ 2004/09/03 | 下午 13:30 ~ 16:30 | Linux架站入門 | 林炫百 | 入門 | 可以,免基礎 |
2004/09/06 ~ 2004/09/10 | 上午 9:30 ~ 12:00 | Java程式設計入門 | 歐陽芳泉 | 入門 | 可以,免基礎 |
2004/09/06 ~ 2004/09/10 | 下午 13:30 ~ 16:30 | PHP 專案實戰講座 | 孫仲岳 | 進階 | 簡單的 PHP基礎 |
2004/09/23 ~ 2004/09/24 | 下午 19:00 ~ 21:30 | PHP 新手上路講座 | 孫仲岳 | 入門 | 可以,免基礎 |
2005/01/24 ~ 2005/01/28 | 上午 9:00 ~ 12:00 | Linux 入門教學 | 陳威任 | 入門 | 可以,免基礎 |
2005/01/24 ~ 2005/01/28 | 下午 2:00 ~ 5:00 | 一週學會 PHP 接案 | 孫仲岳 | 入門 | 可以,免基礎 |
2005/01/31 ~ 2005/02/04 | 上午 9:00 ~ 12:00 | 網路概論 | 曾全佑 | 入門 | 可以,免基礎 |
2005/01/31 ~ 2005/02/04 | 下午 2:00 ~ 5:00 | FreeBSD 入門教學 | 邱秉誠 | 入門 | 可以,免基礎 |
根据〖中华人民共和国国家标准 GB 11643-1999〗中有关公民身份号码的规定,公民身份号码是特征组合码,由十七位数字本体码和一位数字校验码组成。
排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。
地址码表示编码对象常住户口所在县(市、旗、区)的行政区划代码。
生日期码表示编码对象出生的年、月、日,其中年份用四位数字表示,年、月、日之间不用分隔符。
顺序码表示同一地址码所标识的区域范围内,对同年、月、日出生的人员编定的顺序号。顺序码的奇数分给男性,偶数分给女性。
校验码是根据前面十七位数字码,按照ISO 7064:1983.MOD 11-2校验码计算出来的检验码。下面举例说明该计算方法。
15位的身份证编码首先把出生年扩展为4位,简单的就是增加一个19,但是这对于1900年出生的人不使用(这样的寿星不多了)
某男性公民身份号码本体码为34052419800101001,首先按照公式⑴计算:
∑(ai×Wi)(mod 11)……………………………………(1)
公式(1)中:
i----表示号码字符从由至左包括校验码在内的位置序号;
ai----表示第i位置上的号码字符值;
Wi----示第i位置上的加权因子,其数值依据公式Wi=2(n-1)(mod 11)计算得出。
i 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
ai 3 4 0 5 2 4 1 9 8 0 0 1 0 1 0 0 1 a1
Wi 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2 1
ai×Wi 21 36 0 25 16 16 2 9 48 0 0 9 0 5 0 0 2 a1
根据公式(1)进行计算:
∑(ai×Wi) =(21+36+0+25+16+16+2+9+48++0+0+9+0+5+0+0+2) = 189
189 ÷ 11 = 17 + 2/11
∑(ai×Wi)(mod 11) = 2
然后根据计算的结果,从下面的表中查出相应的校验码,其中X表示计算结果为10:
∑(ai×WI)(mod 11) 0 1 2 3 4 5 6 7 8 9 10
校验码字符值ai 1 0 X 9 8 7 6 5 4 3 2
根据上表,查出计算结果为2的校验码为所以该人员的公民身份号码应该为 34052419800101001X。
C#代码:
private string per15To18(string perIDSrc)
{
int iS = 0;
//加权因子常数
int[] iW = new int[] { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 };
//校验码常数
string LastCode = "10X98765432";
//新身份证号
string perIDNew;
perIDNew = perIDSrc.Substring(0, 6);
//填在第6位及第7位上填上‘1’,‘9’两个数字
perIDNew += "19";
perIDNew += perIDSrc.Substring(6, 9);
//进行加权求和
for (int i = 0; i < 17; i++)
{
iS += int.Parse(perIDNew.Substring(i, 1)) * iW[i];
}
//取模运算,得到模值
int iY = iS % 11;
//从LastCode中取得以模为索引号的值,加到身份证的最后一位,即为新身份证号。
perIDNew += LastCode.Substring(iY, 1);
return perIDNew;
}

外部链接文字:10分
标题:10分
域名:7分
H1,H2字号标题:5分
每段首句:5分
路径或文件名:4分
相似度(关键词堆积):4分
每句开头:1.5分
加粗或斜体:1分
文本用法:1分
title属性:1分
alt标记:0.5分
Meta描述(Description):0.5分
Meta关键词(Keywords):0.05分
设置Apache虚拟目录
httpd.conf文件中加一行
Alias /vd "d:/vd/"
表示将d:/vd/目录设置为虚拟目录/vd/,那么你在d:/vd/下的文件,就可以通过在浏览器中输入“http://127.0.0.1/vd”访问。
注:当然你可以写成
Alias /vd/ "d:/vd/"
但是这样的话,你要输入http://127.0.0.1/vd/才能访问,而上面那种只要http://127.0.0.1/vd

2000/XP/2003 下 IIS+PHP+MySQL+Zend Optimizer+GD库+phpMyAdmin安装配置
(假设 C:\ 为你现在所使用操作系统的系统盘,如果你目前操作系统不是安装在 C:\ ,请自行修改。)
一、安装 IIS(Windows2003只要安装“应用程序服务器(IIS,ASP.NET)”即可跳过此步):
(1)插入系统盘;
(2)进入控制面板-》添加或删除程序-》添加/删除Windows组件-》在“Internet信息服务(IIS)打勾-》下一步安装。
(3)安装完成后在浏览器地址栏输入 htt://127.0.0.1 检查是否安装正常。
如果没有系统盘,那么下载 IIS 5.1 的安装包(for XP),重复上述步骤,安装时指定路径即可。
IIS下载地址:http://soft.mumayi.net/downinfo/2597.html
二、安装 PHP:
(1)官方下载:http://www.php.net/downloads.php。
(2)下载后得到 php 的 zip 压缩包,解压至 C:\php(这个路径可以随意,下面要是用到这个路径,请相应修改);
(3)将 C:\php\libmysql.dll 和 C:\php\ext\php_mysql.dll 复制到 C:\Windows\system32 下;
将 C:\php\php.ini-recommended 复制到 C:\Windows (Windows 2000 下为 C:\WINNT)并将改名为php.ini,
然后用记事本打开,利用记事本的查找功能搜索:
搜索“; Windows Extensions”并仅打开需要的模块以节省内存(去掉每个模块前的;号即可):
extension=php_gd2.dll
GD库支持,支持水印。
extension=php_mbstring.dll
支持phpMyAdmin
extension=php_mysql.dll
支持MySQL。
(4)配置 IIS 使其支持 PHP
在“控制面板”的“管理工具”中选择“Internet 服务管理器”,
然后在左侧选择你需要支持 PHP 的 Web 站点上单击右键选择“属性”,
在打开的“Web 站点属性”窗口的“ISAPI 筛选器”标签里找到并点击“添加”按钮,在弹出的“筛选器属性”窗口中的“筛选器名称”栏中输入:PHP,再将可执行文件指向 php5isapi.dll 所在路径,如:C:\php\php5isapi.dll。
打开“Web 站点属性”窗口的“主目录”标签,找到并点击“配置”按钮,在弹出的“应用程序配置”窗口中找到并点击“添加”按钮,在弹出的窗口中新增一个扩展名映射,扩展名为 .php ,单击“浏览”将可执行文件指向 php5isapi.dll 所在路径,如:C:\php\php5isapi.dll,然后一路确定即可。
再打开“Web 站点属性”窗口的“文档”标签,找到并点击“添加”按钮,向默认的 Web 站点启动文档列表中添加 index.php 项。您可以将 index.php 升到最高优先级,这样,访问站点时就会首先自动寻找并打开 index.php 文档。
确定 Web 目录的应用程序设置和执行许可中选择为纯脚本,然后关闭 Internet 信息服务管理器。
2003系统配置:在“Internet 服务管理器”左边的“WEB服务扩展”中设置:
ISAPI 扩展允许
开始-》运行-》输入“iisreset”,重启IIS。
在 IIS 根目录下新建一个 phpinfo.php,内容如下:
<?php
phpinfo();
?>
打开浏览器,输入:http://127.0.0.1/phpinfo.php,将显示当前服务器所支持 PHP 的全部信息。
三、安装 MySQL:
(1)官方下载:http://dev.mysql.com/downloads/mysql/5.2.html
custom
安装
Skip Sign-Up
Finish
Next
Standard Comfiguration
设置数据库密码
(重要)重新启动电脑!
四、安装 Zend Optimizer :(有需要时安装)
(1)官方下载:http://www.zend.com/products/zend_optimizer
(2)安装时只需选择Web服务器为iis,指定php.ini路径即可。
五、安装 phpMyAdmin:(用于管理MYSQL数据库,可选择)
下载 http://www.phpmyadmin.net,将其解压到站点根目录,
找到 ./libraties/config.default.php,做以下修改:
方案一:
搜索 $cfg['Servers'][$i]['auth_type'] 设置为config
搜索 $cfg['Servers'][$i]['user'] 用户名一般为root
搜索 $cfg['Servers'][$i]['password'] 设置MySQL的密码
打开浏览器,输入:http://127.0.0.1/phpMyAdmin/ ,若 IIS 和 MySQL 均已启动,即可浏览数据库内容。
(此设置允许任何人通过以上路径登录管理数据库,安全性极低)
方案二:
搜索 $cfg['Servers'][$i]['auth_type'] 设置为cookie
搜索 $cfg['Servers'][$i]['user'] 用户名一般为root
搜索 $cfg['PmaAbsoluteUri'] 访问路径,设置为http://127.0.0.1/phpmyadmin/
搜索 $cfg['blowfish_secret'] 这是cookie作用域,设置为127.0.0.1
(此设置只允许本机上登录,并且需要输入用户名密码才能登录,安全性极高)
-----------------------------------------------------------------------------------
至此所有安装完毕。以上配置在所有老版本软件中不一定有效,强烈推荐下载最新版本的软件。

简单安装过程:请各位注意安装顺序
----------------------------------------------------
(一)Apache:
装在默认目录。安装-自定义-全部选中。
----------------------------------------------------
(二)PHP:
第一步:压缩C:\php5目录下。
第二步:(将PHP目录添加到PATH环境变量中)开始 -> 控制面板 -> 系统 -> 高级 -> 环境变量 -> 系统变量 -> Path -> 双击 -> 加入“;C:\php5”
第三步:将C:\php5\php.ini-recommended 重命名为 php.ini 。
用记事本打开 php.ini ,查找register_globals = Off,把off改成On (有二处)
查找short_open_tag = Off,把off改成On 有一处
查找extension_dir = "./" 改为 extension_dir = "C:\php5\ext"
查找;extension=php_mbstring.dll,把下面几句前面的分号去掉
extension=php_mbstring.dll
extension=php_dba.dll
extension=php_dbase.dll
extension=php_filepro.dll
extension=php_gd2.dll
extension=php_imap.dll
extension=php_ldap.dll
extension=php_mysql.dll
修改了一些文件上传以及内存使用最大限制:
memory_limit = 20M 内存容量
post_max_size = 20M 闪存容量
upload_max_filesize = 20M 附件容量
保存退出。
第四步:(使php.ini文件在Windows下被PHP所用)
开始 -> 控制面板 -> 系统 -> 高级 -> 环境变量 -> 系统变量 -> 新建 -> 输入“PHPRC” -> 在“变量值”中输入 php.ini文件所在的目录(例如:C:\php5)
点击“确定”
Microsoft Windows 下的 Apache 2.0.x
先停止Apache
用记事本打开C:\Apache2\conf(可能在C:\Program Files\Apache Group\Apache2\conf)下的httpd.conf
这个文件我改了几个地方:
把PHP直接作为apache的一个模块运行,我在里面加了两句:
查找到 #LoadModule ssl_module modules/mod_ssl.so 在它的下面一行加上
LoadModule php5_module "C:/PHP5/php5apache2.dll"
AddType application/x-httpd-php .php 注意点前面有个空格滴,大家最好用复制粘贴
(新版apache2.2的php5apache2_2.dll在外面,放上去同理用)
我在D盘下建立了一个www的目录用于存放我的站点文件,在http.conf里改了这样一句话:
把
DocumentRoot "C:/Program Files/Apache Group/Apache2/htdocs"
改成了
DocumentRoot "D:/www"
所有
Apache2.0.x于1.3.x相比2.0.x默认不能直接列目录,如需,就改:
把DocumentRoot "E:/www"这句下的如下语句
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
改为:
<Directory />
Options Indexes FollowSymLinks
AllowOverride None
</Directory>
修改目录的默认首页:
如:DirectoryIndex index.htm index.html index.php index.html index.html.var
别的就没再动什么地方,保存后退出。
注意一点的是,要使以上所有这些配置生效需要重新启动电脑
最后我们来测试PHP是否正常载入。打开记事本,输入
<?php
phpinfo();
?>
保存,在弹出的窗口中,文件类型选所有文件,文件名为phpinfo.php,保存位置为网站目录下。如(E:\www\phpinfo.php)
打开IE浏览器输入:http://localhost/phpinfo.php 如果能正常显示就OK了。
-------------------------------------------------------
(三)Zend:
先停止Apache
安装Zend Optimizer也很简单,安装中它会两处提示其一:选择那种服务器?请选择Apache。其二:PHP.ini的路径?请选择C:\PHP5。其它的按默认配置安装就行了。OK安装完后我的Zend目录就是C:\Zend。
-------------------------------------------------------
(四)Mysql:

部署Silverlight到产品Web服务器是一个相当容易的过程,尽管有时候会有一些错觉——譬如,认为Silverlight需要部署在基于微软的Web服务器(IIS)上,事实上, Silverlight不强制一定部署在基于微软的Web服务器上,Apache也可以像IIS一样,轻松愉快的支持Silverlight运行。
但是还是要那么一点东东要指出来:Web服务器通常都只支持有限种已知扩展名的静态文件内容。看起来都很好,但是Silverlight引入了两个新的文件扩展(.xaml为松散XAML文件;.xap为基于zip压缩的二进制包格式文件),因此,你需要为web服务器添加MIME类型,这样才能让Web服务器识别并处理那些类型的文件。下面列出了你需要添加到Web服务器的MIME类型:
Extension | MIME Type |
.xaml | application/xaml+xml |
.xap | application/x-silverlight-app |
这些就是你所有需要做的。但是具体到如何为不同的web服务器添加MIME类型,实际因web服务的不同而不同,下面列出了目前流行的一些web服务器和他们的链接,你可以从哪里找到如何配置和更多的信息:
当你在更新所支持的MIME类型的时候,或许还想添加相关的类型,如WPF和ClickOne应用程序的支持,那么还需要添加下表中的MIME类型:
Extension | MIME Type |
.manifest | application/manifest |
.application | application/x-ms-application |
.xbap | application/x-ms-xbap |
.deploy | application/octet-stream |
.xps | application/vnd.ms-xpsdocument |
但是如果你的web服务器在一个你不能修改其配置的共享的服务器上,那么你可以通过修改XAP文件成web服务器已支持的MIME类型来“欺骗”服务器,从而支持xap文件。XAP文件实际上是基于zip压缩的,所以可以直接把.XAP给成.ZIP,并在HTML中把Silverlight对象的source参数指到新的文件目录即可。这里有一个示例(点击这里查看),通过查看网页源代码你可以看到这项技术的实质——它就是指向一个zip压缩文件(里面包含Silverlight内容的)的纯HTML页面。
最后有一个好消息是,随Windows Server 2008发布的IIS 7.0默认已经支持了以上的WPF和Silverlight的MIME类型,包括.xap和.xaml类型扩展。所以如果你使用Windows Server 2008,就已经万事大全,只欠东风了。(另外,对于Vista,不论是全新的安装Vista SP1还是从Vista SP1 RTM升级到SP1 Release,你的IIS的配置只有在先卸载IIS功能在重新安装IIS才会更新。)
【原文地址】First Look at Using Expression Blend with Silverlight 2
【原文发表日期】 Thursday, February 28, 2008 9:36 PM
上个星期,我写了一个《Silverlight 2 初览》的贴子,讨论即将发布的Silverlight 2 Beta1 版。在该贴子里,我给出了一些我撰写的系列教程的链接,这些教程示范了Silverlight和WPF后面的一些根本性编程概念,以及演示如何使用它们来建造一个Silverlight版的“Digg搜索客户端”应用:
在这第一套Silverlight教程里,我没有使用可视化的设计工具来建造用户界面,而是注重于展示底层的XAML UI标识(我认为这有助于更好地解释核心编程概念)。既然我们完成了对基本概念的讨论,让我们来探究一下可为我们所用,变得更有效率的一些工具。
Expression Blend对Silverlight的支持
除了即将发布Silverlight 2的Beta1版本外,我们还将发布针对这个版本的Visual Studio 2008 和 Expression Studio 的工具支持。这些工具将为建造RIA应用提供强有力的支持,是设计来允许开发人员和设计师轻松地合作开发项目的。
在今天的贴子里,我将介绍即将发布的Expression Blend 2.5三月份预览版的一些功能。在演示关于Blend是如何工作的一些基础的东西之后,我们将用它来建造一个跨平台,跨浏览器的 Silverlight IM聊天客户端:
上面的屏幕截图展示了在MAC上运行时该应用的样子,下面是在Expression Blend中该应用设计时的屏幕截图:
我们将使用Expression Blend,用可视化方法构造该应用所有的用户界面,以及使用它来干净地将UI数据绑定到代表我们的聊天会话和消息的.NET类上。
我们用来建造聊天应用的所有控件都是Silverlight 2的Beta1版的一部分。
声明:我不是设计师(也不很酷)
让我预先声明,我是个开发人员,不是个设计师。我也不是很酷。虽然我理解创建用户界面的技术,但在组合界面时,我有时会挑选很差的颜色和字体(就在我弄完本贴的屏幕截图之后,有个同事十分有助地指出,实际上有个致力于取缔我使用的一些字体和颜色的专门网站,哎,很受打击)。
我想对你们中那些有艺术细胞的人说,请对我温柔点,将你的注意力集中在我在下面演示的功能和技术上,别针对我使用的字体和颜色选择, :-)
起步: 创建一个新Silverlight 2项目
Expression Blend 和 Visual Studio 2008共享同样的解决方案/项目文件格式,这意味着你可以在VS 2008中创建新的Silverlight 项目,然后在Expression Blend 中打开,或者你也可以在Expression Blend 创建新的Silverlight 项目,然后在VS中打开。你还可以使用Expression Blend和VS 2008同时打开和编辑同个项目。
因为在我先前的Silverlight教程系列中,我已经展示了如何使用VS 2008来创建一个新Silverlight项目,让我们用这个贴子来展示如何使用Expression Blend来创建一个新的Silverlight应用。要做的话,只要在Expression Blend中选择 文件->新项目 ,选择Silverlight 2 Application图案,然后点击OK:
这会创建一个新的(与VS相兼容的)解决方案文件和Silverlight应用项目:
Blend包括了一个面向Silverlight 2应用的完整的所见即所得的设计器。在打开Silverlight页面和控件时,你可以在设计视图,XAML源码视图,或者同时显示设计视图和XAML源码视图的分割视图之间转换设计表面(支持同步编辑)。在上面我们使用了分割视图这个选项。
理解一些基本的东西:往表面上加控件
Expression Blend拥有一个与Visual Studio稍微不同的工具调色板(tool palette)(与你在像Photoshop这样的设计工具里的找到的调色板更相似些)。
Blend支持矢量图像编辑:
Blend还支持添加和操作控件。在放置布局控件(Grid, Stack, Canvas, Border, ScrollViewer等),文本控件(TextBox, TextBlock等)的工具箱中,有个特殊的图案,以及一个显示你最近用过的控件的图案:
点击工具调色板上最后面的">>"图案会显示可为你所用的所有的控件:
确认点击了Asset Library的右上角的“Show All(显示所有控件)”的复选框,如果你看不到你在找的控件的话。你还可以使用“搜索”文本框,来按名称过滤所显示的控件。
重要注意事项: Blend对所有控件都支持一种设计体验(无论是内置的控件还是第三方的控件或你应用引用的用户控件)。
在你从工具箱里选中一个控件后,你可以在设计表面点击,拖拉,画出控件来。你也可以把控件从asset工具拖拉到artboard上。在默认情形下,当你在设计表面上添加控件,与之交互时,你将得到自动的尺子和定位标记 (下面是一个带有内置按钮,日历和slider控件的表单):
理解其他基本的东西:操作控件属性
你可以在设计表面上选择任何对象,然后在屏幕的右手边点击“属性”面板,来定制它的属性:
在上面,我在把按钮的“背景”画刷改成渐变的深蓝(deeper blue gradient)(在“Brushes(画刷)”节点下面用红笔圈中的第三片,它允许我们配置渐变式的画刷)。
有用的小技巧: 属性窗口的上方包含一个搜索框,你可以用它来过滤可见的属性名称:
因为Silverlight和WPF中所有的UI对象都是使用矢量图像组成的,我们可以任何方式对控件进行变形,样式化,转换。例如,我们可以设置我们的按钮控件的Transform属性或者点击它的边角来旋转,倾斜,扩缩它:
这给与我们很大的威力和灵活性,来快速和轻松地定制我们想要的体验:
有用的小技巧: 你可以按住CTRL键来放大或缩小设计表面,然后使用你的鼠标的滑轮来控制放缩的深度。然后你可以通过按住空格键来移动设计表面的可见区域,这会导致手形光标的显示,然后你可以按住鼠标,用它来把当前可见的区域在屏幕上拖拉。后面这个小技巧在你放大得太多,想轻松地移动可见内容时会非常有用。
建造我们的聊天应用: 定义布局
在我先前的Silverlight教程系列中的第二部分:使用布局管理 (木野狐译)中,我曾谈到Silverlight和WPF中的布局管理系统,以及如何使用布局面板来轻松地控制应用的布局和流程。Expression Blend可以使得定义布局规则变得容易,还包括使用这些布局面板的内置工具支持。
记住,我们建造聊天应用的目标是拥有象这样的UI:
要达成这个目标,我们先在网页上定义三行的<grid>布局,我们可以这么做,把鼠标悬浮在设计表面的左边缘,然后点击我们想生成新的行定义的地方(在下图中,我已经建立了顶行的定义,用红笔圈出的光标所在表示我将点击来添加第二行定义的地方):
点击设计表面的左上角(下图红圈处)允许我们转换设计表面是处于 Canvas 布局模式还是Grid布局模式:
在Grid布局模式中时,Blend 会告诉我们某个行或某个列是否有固定的宽度,或是否与控件的尺寸成比例关系。上面的“空锁(empty locks)”表示这三行之间目前成比例关系(意味着它们会按比较增加,如果我们加大浏览器的大小的话):
如果我们点击顶部和底部的锁的话,我们可以把这些行设置成拥有固定的高度,而让中间一行填充剩下的高度:
我们要做的最后一步是点击顶部的边缘,再定义一个右手的列,我们将其设置成拥有固定的宽度(让左边那列动态地改变大小):
在做完上面的步骤之后,我们的XAML文件将有一个定义成下面这样的Grid:
有用的小技巧: 在上面,我们对我们的Silverlight应用设置了固定的宽度和高度(注意<UserControl>根元素上的Width 和 Height属性)。我们也可以完全去掉Width和Height属性,致使应用拥有动态的大小,自动地流式改变大小来适合包含它的HTML元素或浏览器窗口的大小。(我曾在这里的教程的结尾谈到过这个技巧)。如果我们要给我们的应用设置设计时的宽度和高度,我们可以在根UserControl元素上设置 d:DesignWidth="640" 和 d:DesignHeight="476" 属性。这会在使用设计器来设计应用时,致使设计器使用该尺寸的大小。
建造我们的聊天应用: 添加控件和颜色
至此,我们定义了我们的聊天应用的核心布局,让我们往里面加些控件,开始定制它的外观。
我们将先选择根Grid布局面板,定制它的背景颜色为渐变的蓝色(blue gradient)。可为我们所用,选择一个特定控件的一个简单的方法是使用“Interaction(交互)”面板,然后点击我们想选择的控件:
然后我们可以使用“"Brushes(画刷)”属性面板来定制一个蓝色的 LinearGradient 画刷为Grid的背景:
设置完成后,我们可以开始操作聊天窗口的底部,加一个“Send”(发送)按钮:
至于我们的聊天消息文本框,我们则将使用一个标准的文本框。但要加点活力,我们将先加一个RoundRadius为5的边框控件,然后加象这样的Background(背景)和BorderBrush(边框画刷):
然后我们在Border控件中嵌入我们的TextBox。
重要的小技巧: 为使用设计表面把TextBox嵌套在Border控件之中,我们需要在Interaction窗口中双击Border控件。这会将其设置成设计表面上的当前可插入控件,象下面这样用黄色高亮显示:
然后我们可以使用控件工具箱选择一个TextBox控件,将其加进Border控件。我们将设置TextBox的背景和边框画刷从父控件Border处继承其好看的曲线型外观:
Blend生成的XAML标识看上去象这样(注意,TextBox是内嵌在Border控件之中的,如果Border不是当前插入控件的话,是不会这样的):
我们也可以对header行重复上面的过程,将一个TextBox嵌入一个Border控件中,在右列里加一个图片控件,创建出象这样的UI:
由Blend生成的XAML标识会看上去象下面这样:
最后,绝对不是最不重要,我们将在中间一行添加另一个Border控件,往其中加一个ListBox控件。我们将配置Border控件延伸跨越Grid的两列,将它的背景和前景颜色进行定制。然后我们在ListBox加一些测试消息作为站位文字(我们将在后面对UI进行定制,并将其绑定到实际数值):
由Blend生成的XAML标识将看上去象下面这样:
至此,我们运行应用的话,我们会有一个在浏览器中运行的基本的聊天IM客户端(带硬写的值)。在我们改变浏览器大小时,应用会自动流动,改变大小以适合窗口:
我们还有一堆UI活要干,使我们的IM客户端看上去不至于很粗糙,但至少我们现在有东西可以运行了。
建造我们的聊天应用: 添加ChatMessage和ChatSession 2个类
至此,我们在Expression Blend中创建了初始的UI,让我们在 Visual Studio 中打开同个项目,加些我们可以绑定到UI的一些聊天类。
我们可以在 Visual Studio中选择 VS 2008 中的文件->打开项目,然后选择我们项目的项目文件来打开项目,或者在Expression Blend中我们可以右击项目节点,然后选“Edit in Visual Studio(在Visual Studio中编辑)”菜单项来启动打开了项目的VS 2008:
Beta1版本中的VS 2008的Silvelight支持包括对Silverlight 2方案的项目管理支持,完整的Intellisense和事件连接支持,以及对在Windows和Mac上运行的Silverlight应用的调试支持。VS 2008还支持对Silverlight .xaml文件的分割视图的编辑。譬如,下面是我们在Blend 建造的同个Page.xaml 文件,在VS2008中打开后的样子:
Beta1版的VS 2008设计视图并不是可交互的(意味着还是只读)。但你在源码视图中做的变动会马上在设计视图中更新,这给予你一个很好的XAML-pad的体验(在Silverlight 2 Beta1中,VS 2008支持完整的XAML源码intellisense)。
在这个博客贴子里,我们不会使用Visual Studio的XAML编辑器,而是将创建一些类,我们可以用来代表ChatSession以及相关的聊天消息。然后我们将使用Expression Blend将我们的UI控件绑定到这些类上。
我们先加一个定义了2个公开属性的叫“ChatMessage”的新类:
然后我们将创建一个叫“ChatSession”的类,它代表了一个聊天会话:
上面的ChatSession类有三个公开的属性,前2个属性代表远程聊天对象的用户名和avatar。
第三个属性是过去聊天消息的集合。注意,它的类型不是List<ChatMessage>集合,而是一个ObservableCollection<ChatMessage>集合。ObservableCollection对你来说,也许是个不熟悉的类型,假如你来自ASP.NET背景的话,但对那些来自Windows Forms或WPF背景的,大概会非常熟悉。基本上来说,这是个泛型集合类,往其中添加或去除条目时(或者其中的条目实现了INotifyPropertyChanged的话,在属性变动时),它会发出变化通知事件。这在做数据绑定时会非常方便,因为UI控件可以使用这些通知来知道自动刷新它们的值,而不用开发人员编写代码来显式地这么做。
ChatSession 还有2个公开的方法,其中一个方法的任务是连接到聊天服务器上去,另一个方法的任务是向聊天服务器发送消息。为简单起见(也因为我没有聊天服务器),我会对2个方法做假的实现。在实战中,我们大概会使用内置于Silverlight的网络socket实现连接到一个远程的聊天服务器上去。
ChatSession类实现了INotifyPropertyChanged接口,意味着它会呈示一个公开的PropertyChanged事件。在这个类中,我们会在改变它的属性时,触发这个事件。这会在属性值发生变化时,通知监听者(例如,与它数据绑定的控件),以允许它们重新绑定数据。
为设计时数据绑定实现假的数据
从纯粹功能性的角度来说,上面的代码是为实现我们的聊天客户端所需的所有的代码。但为帮着改进在Blend中的设计时体验,我们还将加一个构造器,检查我们是处于运行时模式还是设计模式,如果宿主于设计器里,那么就给ChatSession装载假的数据:
一会儿我们就会看到这是如何方便在设计器里呈现数据绑定之数据的。
建造我们的聊天应用: 在Expression Blend中使用数据绑定连接UI
既然我们定义了ChatMessage和ChatSession对象,我们可以在Expression Blend 中用它们来绑定到我们的UI控件了。
在我上个星期的《教程第五部分:用 ListBox 和 DataBinding 显示列表数据》 (木野狐译)中,我介绍了Silverlight和WPF中数据绑定的工作原理。在今天的贴子里,我们将使用Expression Blend 来连接数据绑定表达式,而不是手工输入这些表达式。我们将先使用Blend中Project面板下的"Data"面板:
我们将点击Data面板中的“+ CLR Object”链接,调出一个对话框,允许我们挑选任何.NET对象来数据绑定到我们的UI控件。我们将用它来选择我们刚创建的“ChatSession”对象:
这会把ChatSession对象加到我们的Data托盘上去,将它的属性(以及子属性)显示在一个树形视图里:
然后我们就可以在设计视图里通过选择Data托盘里的这些属性,把它们拖放到设计表面上的UI控件上,来绑定任意一个UI控件到这些属性上。例如,我们可以把RemoteUserName属性从Data托盘上拖拉到静态的"ScottGu"标签上,将它换成{Binding RemoteUserName} 数据绑定表达式:
当我们把“RemoteUserName”属性拖放到TextBlock上时,Blend会象上面那样问我们,是绑定这个属性到现有的TextBlock,还是创建一个新的控件来代表这个属性。如果我们选择默认的行为(绑定到现有的控件上),Blend就会询问我们想要的绑定表达式的类型:
我们表明我们要“OneWay(单程)”绑定到TextBlock的“Text”属性上去。当我们点击OK时,我们的控件的“Text”属性就会被更新为 {Binding RemoteUserName} 表达式。
我们可以重复这个拖放交互过程,把Image控件绑定到RemoteAvatarUrl 属性,也把 ListBox 绑定到MessageHistory集合属性上。完成之后,Blend就会象下面这样在设计视图表面中显示我们的伪数据:
你也许会对ListBox的内容感到疑惑,为什么条目都显示成了“ChatClient.ChatMessage”?那个么,目前ListBox是绑定到了自定义的.NET 对象的集合,“ChatClient.ChatMessage”字符串是调用ChatMessage实例的“ToString()”方法返回的值。
我们可以象这样,加一个<DataTemplate>到ListBox来修改它,让它好看些:
注: 在Blend 2.5 三月份的预览版中,你只能在源码视图中定义数据模板。在将来的预览版中,你将能够使用设计器来定义它们。这个功能已经在WPF中实现,如果你想试验一下的话。作为一个设计师,你可以交互式地创建数据的外观,完全的所见即所得的体验。去创建一个WPF项目试一下。
这么做的结果,会使得我们的UI在设计时看起来象下面这样:
在设计时显示这些“伪数据”的好处是,它允许我们对在运行时UI体验是什么样的会有一个比较好的感觉,允许设计师(或开发人员)轻松地设计UI,而不需要等待应用的其他部分的完成。
建造我们的聊天应用: 使用样式和控件模板更新我们的Button和ListBox的UI
在我的《第七部分:使用控件模板定制控件的观感 》Digg教程中谈到的一件事情是,关于Silverlight和WPF如何允许开发人员和设计师完全定制控件的观感(look and feel )的。这提供了巨大的灵活性来精雕细琢应用的UI,以创建恰如其愿的用户体验。
我们可以使用Silverlight和WPF的控件模板特性来定制我们上面聊天应用的Send按钮和ListBox结构,以构造稍微好看的观感。我们可以这么做,创建 "MessageHistory" 和 "SendButton" 样式资源,将之保存在项目的App.xaml文件中。每个样式对象可以有一个控件模板,修改了控件的观感和改变它的视觉结构。
注: 在Blend 2.5 三月份的预览版中,你只能在源码视图中定义数据模板。在将来的预览版中,你将能够使用设计器来定义它们。这个功能已经在WPF中实现,如果你想试验一下的话。作为一个设计师,你可以交互式地创建数据的外观,完全的所见即所得的体验。去创建一个WPF项目试一下。
例如,下面的ListBox控件模板可以用来去除ListBox控件周围的外圈双边框,定义一个只有列表容器卷动条的“平(flat)”的外观:
将这个模板施用到我们的ListBox上,将使得它显示出边缘周围平滑很多的样子:
我们可以用我们按钮的控件模板做得很花哨些,不光是定义一个自定义的按钮形状,还可以定义各种故事板动画来用于该形状,在它处于"MouseOver(悬浮)", "Pressed(按下)", 或"Normal(正常)"状态时, 提供自定义的UI行为(所有这些东西都可以封装在Style定义之中,意味着页面的开发人员不用做什么就可以启用这些东西):
在定义了"MessageHistory" 和"SendButton" 样式对象之后,很容易使用Expression Blend 将它们施用到设计表面的控件之上。
点击Expression Blend中的“Resources”工具窗口,它会列出我们项目中的所有资源地点:
我们可以展开“App.xaml”节点看其中我们可以使用的样式。要将一个特定样式施用到页面上的某个控件,我们只要将它拖放到该控件上就可以了。例如,这是在我们施用“SendButton”样式之前我们的发送按钮控件的样子:
将SendButton样式拖放到它之上,会将它改成使用我们自定义的控件模板形状/结构
因为我们的“SendButton”样式中定义了状态动画效果,按钮在运行时会随终端用户与之交互的方式的不同而变化。
在默认情形下,按钮看上去象这样:
当终端用户将鼠标移到按钮之上时,气球会微妙地变到比较淡的颜色:
在处于按下的状态时,按钮会陷下去,它的影子会消失:
在释放时,按钮又会冒起来。
这些微妙的动画和交互性姿态可以给应用增添一些色彩。最棒的是,设计师可以完全由他们自己建造和定制这些功能,实现页面功能的开发人员根本不用参与也不用编写任何代码,就可以启用这些功能。
在Expression Blend 2.5的将来的预览版中,设计师将不光能定义这个按钮的形状和结构,还能为它定义所有的动画过渡,全部使用设计表面(不需要编辑源码,也不用任何代码)。
实现我们的聊天功能
至此,我们使用Expression Blend对我们的控件UI做了数据绑定,还对UI的交互性做了修改和润色,让我们回到Visual Studio,来编写实现UI聊天行为功能的代码。
特别地,我们将向我们Page的构造器里添加下列代码,来开始与一个远程用户的ChatSession,然后处理“Send”按钮被点击,给远程用户发送一个消息时的场景:
在添加完上面的代码之后,重新运行我们的应用,我们将看到我们的UI现在数据绑定到了一个与RemoteUserName为"ScottGu" 的ChatSession(聊天会话),而不是我们早先定义的假的设计时数据。在消息文本框里输入文字,点击定制的Send按钮时,我们的ListBox会自动显示更新过的聊天历史:
你也许在疑惑为什么ListBox会自动更新?它这么做的原因是因为ListBox是数据绑定到ChatSession.MessageHistory属性上的,该属性的类型是ObservableCollection<ChatMessage>。这意味着,在一个新的 ChatMessage 对象添加进来时,该集合会自动触发变化通知事件,ListBox就会监测到这个事件,然后就会用新的数据更新本身。
不需要我们编写代码,就可以让ListBox对这些变化做反应。我们应用的干净的视图/模型绑定架构会自动为我们做处理。
结语
我只展示了Expression Blend支持的几个特性而已,所有这些特性在Silverlight和WPF项目中都工作的。所有这些功能都将在即将发布的Expression Blend 2.5三月份预览版中发布,不久这个预览版就可(免费)下载。
我想你会发现Visual Studio 2008 和 Expression Studio 会给建造出色的RIA解决方案带来巨大的生产力和威力。开发人员和设计师可以在开发相同项目时协作使用它们(而不用相互妨碍对方)。你还可以轻松地在一个机器上同时打开它们,用它们来同时编辑同一个应用。
在Expression Blend可以下载之后,我将在博客中对它做更多的讨论(以及我还没讨论过的其他一堆特性)。我还将在Silverlight 2 Beta1版发布之后,把上面的例程提供下载,这么你可以自己打开和运行其代码了。
希望本文对你有所帮助,
Scott
This topic provides error message tables associated with Microsoft Silverlight error events.
It contains the following sections:
- OnError Event Error Table
- MediaFailed Event Error Table
- ImageFailed Event Error Table
- DownloadFailed Event Error Table
OnError Event Error Table
The following errors might be returned by the OnError event.
ErrorMessage | ErrorType | ErrorCode | Description |
---|---|---|---|
AG_E_UNKNOWN_ERROR | ANY | 1001 | The default error code that is bubbled up if no other specific error message is available. This error can apply to any call. |
AG_E_INIT_CALLBACK | initializeError | 2100 | Error in callback to the host script engine. This error occurs on initialization of the plug-in instance. |
AG_E_INIT_ROOTVISUAL | initializeError | 2101 | Error in visual root of the XAML tree. For example, you would get this error if the XAML root element is not a Canvas. Can also be raised if there are storyboard mismatches, such as referencing a Storyboard.TargetProperty that is not supported by the object that is the Storyboard.TargetName. This error occurs on initialization of the plug-in instance. |
AG_E_RUNTIME_INVALID_CALL | runtimeError | 2201 | Error returned when the particular call is not supported on that element. This error applies to all elements. |
AG_E_RUNTIME_FINDNAME | runtimeError | 2202 | The call to the FindName method failed. This applies to any element that FindName is supposed to find but cannot. |
AG_E_RUNTIME_SETVALUE | runtimeError | 2203 | Failure to set the value of a property. This applies both to standard JavaScript dotted property syntax, and to SetValue method calls. |
AG_E_RUNTIME_GETVALUE | runtimeError | 2204 | Failure to get the value of a property. This applies both to standard JavaScript dotted property syntax, and to GetValue method calls. |
AG_E_RUNTIME_ADDEVENT | runtimeError | 2205 | The AddEventListener method failed. |
AG_E_RUNTIME_DELEVENT | runtimeError | 2206 | The RemoveEventListener method failed. |
AG_E_RUNTIME_METHOD | runtimeError | 2207 | Error in a run-time method that does not have a specific error message. In a try/catch error object, the name of the method is appended to the string (for example, "AG_E_RUNTIME_METHOD : createFromXAML"). |
AG_E_RUNTIME_GETHOST | runtimeError | 2208 | Error in getting the host object. This applies to the GetHost method. |
AG_E_RUNTIME_GETPARENT | runtimeError | 2209 | Error in getting the parent of an object. This applies to the GetParent method. Note that only Canvas objects can be parents of other objects. |
AG_E_INVALID_ARGUMENT | runtimeError | 2210 | An invalid argument has been passed. |
AG_E_UNNAMED_RESOURCE | runtimeError | 2211 | Error raised when an unnamed Storyboard is added to the Resources section of a UIElement. |
AG_E_UNABLE_TO_PLAY | mediaError | 3000 | See the MediaFailed table. |
AG_E_INVALID_FILE_FORMAT | MediaError, imageError, downloadError | 3001 | See the MediaFailed table and the ImageFailed table. |
AG_E_NOT_FOUND | MediaError, imageError | 3002 | See the MediaFailed table and the ImageFailed table. |
AG_E_ABORT_FAILED | downloadError | 4000 | See the DownloadFailed table. This error applies to the Downloader object. |
AG_E_CONNECTION_ERROR | downloadError | 4001 | See the DownloadFailed table. This error applies to the Downloader object. |
AG_E_NETWORK_ERROR | downloadError | 4002 | See the DownloadFailed table. This error applies to the Downloader object. |
MediaFailed Event Error Table
The following errors might be returned by the MediaFailed event.
ErrorMessage | Description |
---|---|
AG_E_NETWORK_ERROR | Error raised when attempting to play back a non-existent or invalid media file from a third-party domain. |
AG_E_INVALID_FILE_FORMAT | This error can be raised for the following reasons:
|
AG_E_NOT_FOUND | The player will return this error from a call to GetMediaItem or GetMediaStreamItem (the native Windows Media APIs) if the media element asks for an item whose GUID is not recognized, or if the file does not exist at the URL specified. |
ImageFailed Event Error Table
The following errors might be returned by the ImageFailed Event.
ErrorMessage | Description |
---|---|
AG_E_INVALID_FILE_FORMAT | (Same-domain only) The file indicated by the URI is not supported on this type of element. For example, this error might occur if you pass a .wmv file URI to ImageSource. This error is reported only if the source is not cross-domain. |
AG_E_NOT_FOUND | (Same-domain only) The file indicated by the URI was not found at the position indicated by the URI. This error is reported only if the source is not cross-domain. |
AG_E_NETWORK_ERROR | Error reported for any cross-domain errors, to prevent anyone who is calling Silverlight APIs from discovering the existence (or nonexistence) of files on third-party servers. |
DownloadFailed Event Error Table
The following errors might be returned by the DownloadFailed Event.
ErrorMessage | Description |
---|---|
AG_E_ABORT_FAILED | Error raised when a call to Abort failed for some reason and the connection is still in progress. |
AG_E_CONNECTION_ERROR | Error raised from a call to Send. This error occurs before accessing the server when a failure to connect to the Internet occurs on the client side. |
AG_E_NETWORK_ERROR | Error resulting from a call to Send when the error has occurred on the server side. This error can also occur if you implicitly or explicitly attempt to use the Downloader to download a file: scheme URI. |