<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">博客园_天马行空（笨笨）</title><subtitle type="text">希望下辈子不要那么笨了</subtitle><id>http://feed.cnblogs.com/blog/u/22343/rss</id><updated>2011-04-23T06:26:04Z</updated><author><name>天马行空（笨笨）</name><uri>http://www.cnblogs.com/Phoenix-Rock/</uri></author><generator>feed.cnblogs.com</generator><link rel="alternate" type="text/html" href="http://www.cnblogs.com/Phoenix-Rock/"/><link rel="self" type="application/atom+xml" href="http://feed.cnblogs.com/blog/u/22343/rss"/><entry><id>http://www.cnblogs.com/Phoenix-Rock/archive/2011/04/23/libcurl.html</id><title type="text">libcurl的使用(转)</title><summary type="text">libcurl的使用</summary><published>2011-04-23T06:01:00Z</published><updated>2011-04-23T06:01:00Z</updated><author><name>天马行空（笨笨）</name><uri>http://www.cnblogs.com/Phoenix-Rock/</uri></author><link rel="alternate" href="http://www.cnblogs.com/Phoenix-Rock/archive/2011/04/23/libcurl.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/Phoenix-Rock/archive/2011/04/23/libcurl.html"/><content type="html">&lt;p&gt;curl-&amp;gt;libcurl的手册可以查看&lt;/p&gt;&lt;p&gt;&lt;a href="http://curl.haxx.se/libcurl/c/curl_easy_setopt.html#CURLOPTWRITEDATA"&gt;http://curl.haxx.se/libcurl/c/curl_easy_setopt.html#CURLOPTWRITEDATA&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;译者：JGood(&lt;a href="http://blog.csdn.net/JGood"&gt;http://blog.csdn.net/JGood&lt;/a&gt; ) &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 译者注：这是一篇介绍如何使用libcurl的入门教程。文档不是逐字逐句按原文翻译，而是根据笔者对libcurl的理解，参考原文写成。文中用到的一些例子，可能不是出自原文，而是笔者在学习过程中，写的一些示例程序（笔者使用的libcurl版本是：7.19.6）。出现在这里主要是为了更好的说明libcurl的某些api函数的使用。许多例子都参考libcurl提供的example代码。原文example中的提供的示例程序完全使用C语言，而这里笔者提供的例子使用C++语言。因为能力有限，对于libcurl的某些理解和使用可能有误，欢迎批评指正。 &lt;/p&gt;&lt;p&gt;目标&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 本文档介绍了在应用程序开发过程中，如何正确使用libcurl的基本方式和指导原则。文档使用C语言来调用libcurl的接口，当然也适用于其他与C语言接近的语言。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 文档主要针对使用libcurl来进行开发的人员。文档所掼的应用程序泛指你写的源代码，这些代码使用了libcurl进行数据传输。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 更多关于libcurl的功能和接口信息，可以在相关的主页上查阅。 &lt;/p&gt;&lt;p&gt;编译源码&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 有很多种不同的方式来编译C语言代码。这里使用UNIX平台下的编译方式。即使你使用的是其他的操作系统，你仍然可以通过阅读本文档来获取许多有用的信息。 &lt;/p&gt;&lt;p&gt;编译 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 你的编译器必须知道libcurl头文件的位置。所以在编译的时候，你要设置头文件的包含路径。可以使用curl-config工具来获取这方面的信息： &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; $ curl-config &amp;#8211;cflags &lt;/p&gt;&lt;p&gt;链接 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 编译完源码（这时的源代码不是指libcurl的源代码，你是你自己写的程序代码）之后，你还必须把目标文件链接成单个可执行文件。你要链接libcurl库，以及libcurl所依赖的其他库，例如OpenSLL库。当然可能还需要一些其他的操作系统库。最后你还要设置一些编译选项，当然可以使用curl-config工具简化操作： &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; $curl-config &amp;#8211;libs &lt;/p&gt;&lt;p&gt;是否使用SSL &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 定制编译libcurl。与其他库不同的是，libcurl可以定制编译，根据实际需要是否支持某些特性，如是否支持SSL传输，像HTTPS和FTPS。如果决定需要支持SSL，必须在编译时正确的设置。可以使用&amp;#8217;curl-config&amp;#8217;来判断libcurl库是否支持SSL： &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; $ curl-config &amp;#8211;feature &lt;/p&gt;&lt;p&gt;autoconf宏&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 当你编写配置脚本来检测libcurl及其相应设置时，你可以使用预定义宏。文档docs/libcurl/libcurl.m4告诉你如何使用这些宏。&lt;/p&gt;&lt;p&gt;跨平台的可移植的代码 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; libcurl的开发人员花费很大的努力，使libcurl尽可能在大多数平台上正常运行。 &lt;/p&gt;&lt;p&gt;全局初始化 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 应用程序在使用libcurl之前，必须先初始化libcurl。libcurl只需初始化一次。可以使用以下语句进行初始化： &lt;/p&gt;&lt;p&gt;curl_global_init();&amp;nbsp;&amp;nbsp;&amp;nbsp; curl_global_init()接收一个参数，告诉libcurl如何初始化。参数CURL_GLOBAL_ALL 会使libcurl初始化所有的子模块和一些默认的选项，通常这是一个比较好的默认参数值。还有两个可选值： &lt;/p&gt;&lt;p&gt;CURL_GLOBAL_WIN32&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 只能应用于Windows平台。它告诉libcurl初始化winsock库。如果winsock库没有正确地初始化，应用程序就不能使用socket。在应用程序中，只要初始化一次即可。 &lt;/p&gt;&lt;p&gt;CURL_GLOBAL_SSL &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 如果libcurl在编译时被设定支持SSL，那么该参数用于初始化相应的SSL库。同样，在应用程序中，只要初始化一次即可。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; libcurl有默认的保护机制，如果在调用curl_easy_perform时它检测到还没有通过curl_global_init进行初始化，libcurl会根据当前的运行时环境，自动调用全局初始化函数。但必须清楚的是，让系统自已初始化不是一个好的选择。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 当应用程序不再使用libcurl的时候，应该调用curl_global_cleanup来释放相关的资源。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 在程序中，应当避免多次调用curl_global_init和curl_global_cleanup。它们只能被调用一次。 &lt;/p&gt;&lt;p&gt;libcurl提供的功能 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 在运行时根据libcurl支持的特性来进行开发，通常比编译时更好。可以通过调用curl_version_info函数返回的结构体来获取运行时的具体信息，从而确定当前环境下libcurl支持的一些特性。下面是笔者在visual studio2008中调用相关函数获取libcurl版本信息的截图：&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;a href="http://p.blog.csdn.net/images/p_blog_csdn_net/JGood/601714/o_pic1_1.jpg"&gt;&lt;img title="pic1" border="0" alt="pic1" src="http://p.blog.csdn.net/images/p_blog_csdn_net/JGood/601714/o_pic1_thumb_1.jpg" width="678" height="558" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;使用easy interface&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp; 首先介绍libcurl中被称为easy interface的api函数，所有这些函数都是有相同的前缀：curl_easy 。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 当前版本的libcurl也提供了multi interface，关于这些接口的详细使用，在下面的章节中会有介绍。在使用multi interface之前，你首先应该理解如何使用easy interface。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 要使用easy interface，首先必须创建一个easy handle，easy handle用于执行每次操作。基本上，每个线程都应该有自己的easy handle用于数据通信（如果需要的话）。千万不要在多线程之间共享同一个easy handle。下面的函数用于获取一个easy handle ： &lt;/p&gt;&lt;p&gt;CURL *easy_handle = curl_easy_init();&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 在easy handle上可以设置属性和操作(action)。easy handle就像一个逻辑连接，用于接下来要进行的数据传输。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 使用curl_easy_setopt函数可以设置easy handle的属性和操作，这些属性和操作控制libcurl如何与远程主机进行数据通信。一旦在easy handle中设置了相应的属性和操作，它们将一直作用该easy handle。也就是说，重复使用easy hanle向远程主机发出请求，先前设置的属性仍然生效。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; easy handle的许多属性使用字符串(以\0结尾的字节数组)来设置。通过curl_easy_setopt函数设置字符串属性时，libcurl内部会自动拷贝这些字符串，所以在设置完相关属性之后，字符串可以直接被释放掉（如果需要的话）。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; easy handle最基本、最常用的属性是URL。你应当通过CURLOPT_URL属性提供适当的URL： &lt;/p&gt;&lt;p&gt;curl_easy_setopt(easy_handle, CURLOPT_URL, "&lt;a href="http://blog.csdn.net/JGood"&gt;http://blog.csdn.net/JGood&lt;/a&gt; ");&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 假设你要获取URL所表示的远程主机上的资源。你需要写一段程序用来完成数据传输，你可能希望直接保存接收到的数据而不是简单的在输出窗口中打印它们。所以，你必须首先写一个回调函数用来保存接收到的数据。回调函数的原型如下： &lt;/p&gt;&lt;p&gt;size_t write_data(void *buffer, size_t size, size_t nmemb, void *userp); &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 可以使用下面的语句来注册回调函数，回调函数将会在接收到数据的时候被调用： &lt;/p&gt;&lt;p&gt;curl_easy_setopt(easy_handle, CURLOPT_WRITEFUNCTION, write_data); &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 可以给回调函数提供一个自定义参数，libcurl不处理该参数，只是简单的传递： &lt;/p&gt;&lt;p&gt;curl_easy_setopt(easy_handle, CURLOPT_WRITEDATA, &amp;amp;internal_struct);&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 如果你没有通过CURLOPT_WRITEFUNCTION属性给easy handle设置回调函数，libcurl会提供一个默认的回调函数，它只是简单的将接收到的数据打印到标准输出。你也可以通过CURLOPT_WRITEDATA属性给默认回调函数传递一个已经打开的文件指针，用于将数据输出到文件里。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 下面是一些平台相关的注意点。在一些平台上，libcurl不能直接操作由应用程序打开的文件。所以，如果使用默认的回调函数，同时通过CURLOPT_WRITEDATA属性给easy handle传递一个文件指针，应用程序可能会执行失败。如果你希望自己的程序能跑在任何系统上，你必须避免出现这种情况。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 如果以win32动态连接库的形式来使用libcurl，在设置CURLOPT_WRITEDATA属性时，你必须同时 使用CURLOPT_WRITEFUNCTION来注册回调函数。否则程序会执行失败（笔者尝试只传递一个打开的文件指针而不显式设置回调函数，程序并没有崩溃。可能是我使用的方式不正确。）。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 当然，libcurl还支持许多其他的属性，在接下来的篇幅里，你将会逐步地接触到它们。调用下面的函数，将执行真正的数据通信： &lt;/p&gt;&lt;p&gt;success = curl_easy_perform(easy_handle); &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; curl_easy_perfrom将连接到远程主机，执行必要的命令，并接收数据。当接收到数据时，先前设置的回调函数将被调用。libcurl可能一次只接收到1字节的数据，也可能接收到好几K的数据，libcurl会尽可能多、及时的将数据传递给回调函数。回调函数返回接收的数据长度。如果回调函数返回的数据长度与传递给它的长度不一致（即返回长度 != size * nmemb），libcurl将会终止操作，并返回一个错误代码。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 当数据传递结束的时候，curl_easy_perform将返回一个代码表示操作成功或失败。如果需要获取更多有关通信细节的信息，你可以设置CURLOPT_ERRORBUFFER属性，让libcurl缓存许多可读的错误信息。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; easy handle在完成一次数据通信之后可以被重用。这里非常建议你重用一个已经存在的easy handle。如果在完成数据传输之后，你创建另一个easy handle来执行其他的数据通信，libcurl在内部会尝试着重用上一次创建的连接。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 对于有些协议，下载文件可能包括许多复杂的子过程：日志记录、设置传输模式、选择当前文件夹，最后下载文件数据。使用libcurl，你不需要关心这一切，你只需简单地提供一个URL，libcurl会给你做剩余所有的工作。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 下面的这个例子演示了如何获取网页源码，将其保存到本地文件，并同时将获取的源码输出到控制台上。&lt;/p&gt;&lt;p&gt;/**&lt;br /&gt;&amp;nbsp;*&amp;nbsp;@brief libcurl接收到数据时的回调函数&lt;br /&gt;&amp;nbsp;*&lt;br /&gt;&amp;nbsp;*&amp;nbsp;将接收到的数据保存到本地文件中，同时显示在控制台上。&lt;br /&gt;&amp;nbsp;* *&amp;nbsp;@param [in] buffer 接收到的数据所在缓冲区 *&amp;nbsp;@param [in] size 数据长度 *&amp;nbsp;@param [in] nmemb 数据片数量 *&amp;nbsp;@param [in/out] 用户自定义指针 *&amp;nbsp;@return 获取的数据长度 */&lt;br /&gt;size_t process_data(void *buffer, size_t size, size_t nmemb, void *user_p)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;FILE *fp = (FILE *)user_p;&lt;br /&gt;&amp;nbsp;size_t return_size = fwrite(buffer, size, nmemb, fp);&lt;br /&gt;&amp;nbsp;cout &amp;lt;&amp;lt; (char *)buffer &amp;lt;&amp;lt; endl;&amp;nbsp;return return_size;&lt;br /&gt;}&lt;/p&gt;&lt;p&gt;int main(int argc, char **argv)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;// 初始化libcurl&lt;br /&gt;&amp;nbsp;CURLcode return_code;&lt;br /&gt;&amp;nbsp;return_code = curl_global_init(CURL_GLOBAL_WIN32);&lt;br /&gt;&amp;nbsp;if (CURLE_OK != return_code)&lt;br /&gt;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;cerr &amp;lt;&amp;lt; "init libcurl failed." &amp;lt;&amp;lt; endl;&lt;br /&gt;&amp;nbsp;&amp;nbsp;return -1;&lt;br /&gt;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;// 获取easy handle&lt;br /&gt;&amp;nbsp;CURL *easy_handle = curl_easy_init();&amp;nbsp;if (NULL == easy_handle)&amp;nbsp;{&amp;nbsp;&amp;nbsp;cerr &amp;lt;&amp;lt; "get a easy handle failed." &amp;lt;&amp;lt; endl;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; curl_global_cleanup(); &amp;nbsp;&amp;nbsp;return -1;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;FILE *fp = fopen("data.html", "ab+");&amp;nbsp;// &lt;br /&gt;&amp;nbsp;// 设置easy handle属性&lt;br /&gt;&amp;nbsp;curl_easy_setopt(easy_handle, CURLOPT_URL, &lt;a href="http://blog.csdn.net/JGood"&gt;http://blog.csdn.net/JGood&lt;/a&gt;);&amp;nbsp;curl_easy_setopt(easy_handle, CURLOPT_WRITEFUNCTION, &amp;amp;process_data);&amp;nbsp;curl_easy_setopt(easy_handle, CURLOPT_WRITEDATA, fp);&lt;br /&gt;&amp;nbsp;// 执行数据请求&lt;br /&gt;&amp;nbsp;curl_easy_perform(easy_handle);&amp;nbsp;&lt;br /&gt;&amp;nbsp;// 释放资源&lt;br /&gt;&amp;nbsp;fclose(fp);&amp;nbsp;curl_easy_cleanup(easy_handle);&amp;nbsp;curl_global_cleanup();&lt;br /&gt;&amp;nbsp;return 0;} &lt;br /&gt;多线程问题 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 首先一个基本原则就是：绝对不应该在线程之间共享同一个libcurl handle，不管是easy handle还是multi handle（将在下文中介绍）。一个线程每次只能使用一个handle。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; libcurl是线程安全的，但有两点例外：信号(signals)和SSL/TLS handler。 信号用于超时失效名字解析(timing out name resolves)。libcurl依赖其他的库来支持SSL/STL，所以用多线程的方式访问HTTPS或FTPS的URL时，应该满足这些库对多线程操作的一些要求。详细可以参考： &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; OpenSSL: &lt;a href="http://www.openssl.org/docs/crypto/threads.html#DESCRIPTION"&gt;http://www.openssl.org/docs/crypto/threads.html#DESCRIPTION&lt;/a&gt; &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; GnuTLS: &lt;a href="http://www.gnu.org/software/gnutls/manual/html_node/Multi_002dthreaded-applications.html"&gt;http://www.gnu.org/software/gnutls/manual/html_node/Multi_002dthreaded-applications.html&lt;/a&gt; &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; NSS: 宣称是多线程安全的。 &lt;/p&gt;&lt;p&gt;什么时候libcurl无法正常工作 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 传输失败总是有原因的。你可能错误的设置了一些libcurl的属性或者没有正确的理解某些属性的含义，或者是远程主机返回一些无法被正确解析的内容。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 这里有一个黄金法则来处理这些问题：将CURLOPT_VERBOSE属性设置为1，libcurl会输出通信过程中的一些细节。如果使用的是http协议，请求头/响应头也会被输出。将CURLOPT_HEADER设为1，这些头信息将出现在消息的内容中。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 当然不可否认的是，libcurl还存在bug。当你在使用libcurl的过程中发现bug时，希望能够提交给我们，好让我们能够修复这些bug。你在提交bug时，请同时提供详细的信息：通过CURLOPT_VERBOSE属性跟踪到的协议信息、libcurl版本、libcurl的客户代码、操作系统名称、版本、编译器名称、版本等等。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 如果你对相关的协议了解越多，在使用libcurl时，就越不容易犯错。 &lt;/p&gt;&lt;p&gt;上传数据到远程站点 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; libcurl提供协议无关的方式进行数据传输。所以上传一个文件到FTP服务器，跟向HTTP服务器提交一个PUT请求的操作方式是类似的： &lt;/p&gt;&lt;p&gt;1. 创建easy handle或者重用先前创建的easy handle。 &lt;/p&gt;&lt;p&gt;2. 设置CURLOPT_URL属性。 &lt;/p&gt;&lt;p&gt;3. 编写回调函数。在执行上传的时候，libcurl通过回调函数读取要上传的数据。（如果要从远程服务器下载数据，可以通过回调来保存接收到的数据。）回调函数的原型如下：&lt;/p&gt;&lt;p&gt;size_t function(char *bufptr, size_t size, size_t nitems, void *userp);&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; bufptr指针表示缓冲区，用于保存要上传的数据，size * nitems是缓冲区数据的长度，userp是一个用户自定义指针，libcurl不对该指针作任何操作，它只是简单的传递该指针。可以使用该指针在应用程序与libcurl之间传递信息。 &lt;/p&gt;&lt;p&gt;4. 注册回调函数，设置自定义指针。语法如下： &lt;/p&gt;&lt;p&gt;// 注册回调函数&lt;br /&gt;curl_easy_setopt(easy_handle, CURLOPT_READFUNCTION, read_function); &lt;br /&gt;// 设置自定义指针&lt;br /&gt;curl_easy_setopt(easy_handle, CURLOPT_READDATA, &amp;amp;filedata); 5. 告诉libcurl，执行的是上传操作。 &lt;/p&gt;&lt;p&gt;curl_easy_setopt(easy_handle, CURLOPT_UPLOAD, 1L);&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 有些协议在没有预先知道上传文件大小的情况下，可能无法正确判断上传是否结束，所以最好预先使用CURLOPT_INFILESIZE_LARGE属性：告诉它要上传文件的大小： &lt;/p&gt;&lt;p&gt;/* in this example, file_size must be an curl_off_t variable */&lt;br /&gt;curl_easy_setopt(easy_handle, CURLOPT_INFILESIZE_LARGE, file_size);6. 调用curl_easy_perform。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 接下来，libcurl将会完成剩下的所有工作。在上传文件过程中，libcurl会不断调用先前设置的回调函数，用于将要上传的数据读入到缓冲区，并执行上传。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 下面的例子演示如何将文件上传到FTP服务器。笔者使用的是IIS自带的FTP服务，同时在FTP上设置了可写权限。&lt;/p&gt;&lt;p&gt;/** *&amp;nbsp;@brief 读取数据的回调。 */&lt;br /&gt;size_t read_data(void *buffer, size_t size, size_t nmemb, void *user_p)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;return fread(buffer, size, nmemb, (FILE *)user_p);&lt;br /&gt;}&lt;/p&gt;&lt;p&gt;int main(int argc, char **argv)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;// 初始化libcurl&lt;br /&gt;&amp;nbsp;CURLcode code;&amp;nbsp;code = curl_global_init(CURL_GLOBAL_WIN32);&lt;br /&gt;&amp;nbsp;if (code != CURLE_OK)&lt;br /&gt;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;cerr &amp;lt;&amp;lt; "init libcurl failed." &amp;lt;&amp;lt; endl;&lt;br /&gt;&amp;nbsp;&amp;nbsp;return -1;&lt;br /&gt;&amp;nbsp;}&lt;/p&gt;&lt;p&gt;&amp;nbsp;FILE *fp = fopen("a.html", "rb");&lt;br /&gt;&amp;nbsp;if (NULL == fp)&lt;br /&gt;&amp;nbsp;{&amp;nbsp;&amp;nbsp;cout &amp;lt;&amp;lt; "can't open file." &amp;lt;&amp;lt; endl;&lt;br /&gt;&amp;nbsp;&amp;nbsp;curl_global_cleanup();&lt;br /&gt;&amp;nbsp;&amp;nbsp;return -1;&lt;br /&gt;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;// 获取文件大小&lt;br /&gt;&amp;nbsp;fseek(fp, 0, 2);&amp;nbsp;int file_size = ftell(fp);&lt;br /&gt;&amp;nbsp;rewind(fp);&lt;/p&gt;&lt;p&gt;&amp;nbsp;// 获取easy handle&lt;br /&gt;&amp;nbsp;CURL *easy_handle = NULL;&lt;br /&gt;&amp;nbsp;easy_handle = curl_easy_init();&lt;br /&gt;&amp;nbsp;if (NULL == easy_handle)&lt;br /&gt;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;cerr &amp;lt;&amp;lt; "get a easy handle failed." &amp;lt;&amp;lt; endl;&lt;br /&gt;&amp;nbsp;&amp;nbsp;fclose(fp);&lt;br /&gt;&amp;nbsp;&amp;nbsp;curl_global_cleanup();&lt;br /&gt;&amp;nbsp;&amp;nbsp;return -1;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;// 设置eash handle属性&lt;br /&gt;&amp;nbsp;curl_easy_setopt(easy_handle, CURLOPT_URL, &lt;a href="http://www.cnblogs.com/Phoenix-Rock/admin/ftp://127.0.0.1/upload.html"&gt;http://www.cnblogs.com/Phoenix-Rock/admin/ftp://127.0.0.1/upload.html&lt;/a&gt;);&lt;br /&gt;&amp;nbsp;curl_easy_setopt(easy_handle, CURLOPT_UPLOAD, 1L);&lt;br /&gt;&amp;nbsp;curl_easy_setopt(easy_handle, CURLOPT_READFUNCTION, &amp;amp;read_data);&lt;br /&gt;&amp;nbsp;curl_easy_setopt(easy_handle, CURLOPT_READDATA, fp);&lt;br /&gt;&amp;nbsp;curl_easy_setopt(easy_handle, CURLOPT_INFILESIZE_LARGE, file_size);&lt;/p&gt;&lt;p&gt;&amp;nbsp;// 执行上传操作&lt;br /&gt;&amp;nbsp;code = curl_easy_perform(easy_handle);&lt;br /&gt;&amp;nbsp;if (code == CURLE_OK)&lt;br /&gt;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;cout &amp;lt;&amp;lt; "upload successfully." &amp;lt;&amp;lt; endl;&lt;br /&gt;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;// 释放资源&lt;br /&gt;&amp;nbsp;fclose(fp);&amp;nbsp;curl_easy_cleanup(easy_handle);&amp;nbsp;curl_global_cleanup();&lt;br /&gt;&amp;nbsp;return 0;&lt;br /&gt;} &lt;br /&gt;关于密码&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 客户端向服务器发送请求时，许多协议都要求提供用户名与密码。libcurl提供了多种方式来设置它们。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 一些协议支持在URL中直接指定用户名和密码，类似于： protocol://user:password@example.com/path/。libcurl能正确的识别这种URL中的用户名与密码并执行相应的操作。如果你提供的用户名和密码中有特殊字符，首先应该对其进行URL编码。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 也可以通过CURLOPT_USERPWD属性来设置用户名与密码。参数是格式如 &amp;#8220;user:password &amp;#8221;的字符串： &lt;/p&gt;&lt;p&gt;curl_easy_setopt(easy_handle, CURLOPT_USERPWD, "user_name:password");&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; （下面这几段文字我理解地模模糊糊）有时候在访问代理服务器的时候，可能时时要求提供用户名和密码进行用户身份验证。这种情况下，libcurl提供了另一个属性CURLOPT_PROXYUSERPWD： &lt;/p&gt;&lt;p&gt;curl_easy_setopt(easy_handle, CURLOPT_PROXYUSERPWD, "user_name:password");&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 在UNIX平台下，访问FTP的用户名和密码可能会被保存在$HOME/.netrc文件中。libcurl支持直接从这个文件中获取用户名与密码：&lt;/p&gt;&lt;p&gt;curl_easy_setopt(easy_handle, CURLOPT_NETRC, 1L);&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 在使用SSL时，可能需要提供一个私钥用于数据安全传输，通过CURLOPT_KEYPASSWD来设置私钥：&lt;/p&gt;&lt;p&gt;curl_easy_setopt(easy_handle, CURLOPT_KEYPASSWD, "keypassword");&amp;nbsp; &lt;br /&gt;HTTP验证 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 上一章介绍了如何在libcurl中，对需要身份验证的URL设置用户名与密码。在使用HTTP协议时，客户端有很多种方式向服务器提供验证信息。默认的HTTP验证方法是"Basic&amp;#8221;，它将用户名与密码以明文的方式、经Base64编码后保存在HTTP请求头中，发往服务器。当然这不太安全。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 当前版本的libcurl支持的验证方法有：basic, Digest, NTLM, Negotiate, GSS-Negotiate and SPNEGO。（译者感叹：搞Web这么多年，尽然不知道这些Http的验证方式，实在惭愧。）可以通过CURLOPT_HTTPAUTH属性来设置具体的验证方式： &lt;/p&gt;&lt;p&gt;curl_easy_setopt(easy_handle, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);&amp;nbsp;&amp;nbsp;&amp;nbsp; 向代理服务器发送验证信息时，可以通过CURLOPT_PROXYAUTH设置验证方式：&lt;/p&gt;&lt;p&gt;curl_easy_setopt(easy_handle, CURLOPT_PROXYAUTH, CURLAUTH_NTLM);&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 也可以同时设置多种验证方式（通过按位与）， 使用&amp;#8216;CURLAUTH_ANY&amp;#8216;将允许libcurl可以选择任何它所支持的验证方式。通过CURLOPT_HTTPAUTH或CURLOPT_PROXYAUTH属性设置的多种验证方式，libcurl会在运行时选择一种它认为是最好的方式与服务器通信：&lt;/p&gt;&lt;p&gt;curl_easy_setopt(easy_handle, CURLOPT_HTTPAUTH,&amp;nbsp; CURLAUTH_DIGEST|CURLAUTH_BASIC); // curl_easy_setopt(easy_handle, CURLOPT_HTTPAUTH,&amp;nbsp; CURLAUTH_ANY);&amp;nbsp; &lt;br /&gt;HTTP Post &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 这一章介绍如何使用libcurl以Post方式向HTTP服务器提交数据。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 方法一，也是最简单的方式，就像html中使用&amp;lt;form&amp;gt;标签提交数据一样，只需向libcurl提供一个包含数据的字符串即可。下面是笔者学习过程中的一个demo程序：&lt;/p&gt;&lt;p&gt;int main(int argc, char **argv)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;code = curl_global_init(CURL_GLOBAL_WIN32);&lt;br /&gt;&amp;nbsp;CURL *easy_handle = curl_easy_init();&lt;/p&gt;&lt;p&gt;&amp;nbsp;curl_easy_setopt(easy_handle, CURLOPT_URL, &lt;a href="http://localhost:2210/Default.aspx"&gt;http://localhost:2210/Default.aspx&lt;/a&gt;);&lt;br /&gt;&amp;nbsp;// 单个域post&lt;br /&gt;&amp;nbsp;curl_easy_setopt(easy_handle, CURLOPT_POSTFIELDS, "name=jgood&amp;amp;address=hangzhou");&amp;nbsp;code = curl_easy_perform(easy_handle);&lt;br /&gt;&amp;nbsp;curl_easy_cleanup(easy_handle);&amp;nbsp;curl_global_cleanup();&lt;br /&gt;&amp;nbsp;return 0;&lt;br /&gt;}&lt;/p&gt;&lt;p&gt;在asp.net Web服务器上跟踪调试，得到客户程序提交上来的数据，下面是截图：&lt;/p&gt;&lt;p&gt;&lt;a href="http://p.blog.csdn.net/images/p_blog_csdn_net/JGood/601714/o_pic1.jpg"&gt;&lt;img title="pic1" border="0" alt="pic1" src="http://p.blog.csdn.net/images/p_blog_csdn_net/JGood/601714/o_pic1_thumb.jpg" width="663" height="244" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 上面的代码够简单吧~_~ 有时候，我们需要提交一些二进制数据到HTTP服务器，使用方法一就不行了，因为方法一中实际提交的是一个字符串，字符串遇到\0就表示结束了。所以在上传二进制数据的时候，必须明确的告诉libcurl要提交的数据的长度。在上传二进制数据的时候，还应该设置提交的Content-Type头信息。下面的示例代码： &lt;/p&gt;&lt;p&gt;int main(int argc, char **argv)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;curl_global_init(CURL_GLOBAL_WIN32);&amp;nbsp;CURL *easy_handle = curl_easy_init();&lt;br /&gt;&amp;nbsp;// 上传二进制数据&lt;br /&gt;&amp;nbsp;char data[] = { 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0 };&lt;br /&gt;&amp;nbsp;curl_slist *http_headers = NULL;&lt;br /&gt;&amp;nbsp;http_headers = curl_slist_append(http_headers, "Content-Type: text/xml");&lt;br /&gt;&amp;nbsp;curl_easy_setopt(easy_handle, CURLOPT_HTTPHEADER, http_headers);&amp;nbsp;curl_easy_setopt(easy_handle, CURLOPT_URL, &lt;a href="http://localhost:2210/Default.aspx"&gt;http://localhost:2210/Default.aspx&lt;/a&gt;);&lt;br /&gt;&amp;nbsp;curl_easy_setopt(easy_handle, CURLOPT_POSTFIELDS, data);&lt;br /&gt;&amp;nbsp;curl_easy_setopt(easy_handle, CURLOPT_POSTFIELDSIZE, sizeof(data));&lt;/p&gt;&lt;p&gt;&amp;nbsp;curl_easy_perform(easy_handle);&lt;/p&gt;&lt;p&gt;&amp;nbsp;curl_slist_free_all(http_headers);&lt;br /&gt;&amp;nbsp;curl_easy_cleanup(easy_handle);&lt;br /&gt;&amp;nbsp;curl_global_cleanup();&lt;br /&gt;&amp;nbsp;return 0;&lt;br /&gt;}&lt;/p&gt;&lt;p&gt;&amp;nbsp;在asp.net Web服务器上跟踪调试，得到客户程序提交上来的二进制数据，下面是截图：&lt;/p&gt;&lt;p&gt;&lt;a href="http://p.blog.csdn.net/images/p_blog_csdn_net/JGood/601714/o_pic1_2.jpg"&gt;&lt;img title="pic1" border="0" alt="pic1" src="http://p.blog.csdn.net/images/p_blog_csdn_net/JGood/601714/o_pic1_thumb_2.jpg" width="640" height="422" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 上面介绍的两种方式，可以完成大部分的HTTP POST操作。但上面的两种方式都不支持multi-part formposts。Multi-part formposts被认为是提交二进制数据(或大量数据)的更好方法，可以在RFC1867, RFC2388中找到他们的定义。何为Multi-part？其实，就我理解，就是在Post提交的时候，有不同的数据单元，每个单元有自己的名称与内容，内容可以是文本的，也可以是二进制的。同时，每个数据单元都可以有自己的消息头，MIME类型，这些数据单元组成一个链表，提交到HTTP服务器。libcurl提供了方便的api用于支持multi-part formposts。使用curl_formadd函数，可以添加不同的数据数据单元，然后提交到服务器。下面是一个multi-part formposts的例子（更详细的使用，请参考：&lt;a href="http://curl.haxx.se/libcurl/c/curl_formadd.html"&gt;http://curl.haxx.se/libcurl/c/curl_formadd.html&lt;/a&gt; ）： &lt;/p&gt;&lt;p&gt;int main()&lt;br /&gt;{&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; curl_global_init(CURL_GLOBAL_WIN32); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CURL *easy_handle = curl_easy_init();&lt;/p&gt;&lt;p&gt;&amp;nbsp;// 使用multi-parts form post&lt;br /&gt;&amp;nbsp;curl_easy_setopt(easy_handle, CURLOPT_URL, &lt;a href="http://localhost:2210/Default.aspx"&gt;http://localhost:2210/Default.aspx&lt;/a&gt;);&amp;nbsp;curl_httppost *post = NULL;&amp;nbsp;curl_httppost *last = NULL;&amp;nbsp;&lt;br /&gt;&amp;nbsp;// 文本数据&lt;br /&gt;&amp;nbsp;curl_formadd(&amp;amp;post, &amp;amp;last, CURLFORM_COPYNAME, "name", CURLFORM_COPYCONTENTS, "JGood", CURLFORM_END);&amp;nbsp;curl_formadd(&amp;amp;post, &amp;amp;last, CURLFORM_COPYNAME, "address", CURLFORM_COPYCONTENTS, "HangZhou", CURLFORM_END);&lt;br /&gt;&amp;nbsp;// 文本文件中的数据&lt;br /&gt;&amp;nbsp;curl_formadd(&amp;amp;post, &amp;amp;last, CURLFORM_COPYNAME, "file", CURLFORM_FILECONTENT, "ReadMe.txt", CURLFORM_END);&lt;br /&gt;&amp;nbsp;curl_easy_setopt(easy_handle, CURLOPT_HTTPPOST, post);&lt;br /&gt;&amp;nbsp;curl_easy_perform(easy_handle);&lt;br /&gt;&amp;nbsp;curl_formfree(post);&lt;br /&gt;&amp;nbsp;curl_easy_cleanup(easy_handle);&lt;br /&gt;&amp;nbsp;curl_global_cleanup();&lt;/p&gt;&lt;p&gt;&amp;nbsp;return 0;&lt;br /&gt;}&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 最后要说明的是，所有在easy handle上设置的属性都是&amp;#8221;sticky&amp;#8221;的，什么意思？就是说在easy handle上设置的属性都将被保存，即使执行完curl_easy_perform之后，这些属性值仍然存在。通过将CURLOPT_HTTPGET设为1可以使easy handle回到最原始的状态： &lt;/p&gt;&lt;p&gt;curl_easy_setopt(easy_handle, CURLOPT_HTTPGET, 1L);&amp;nbsp; &lt;br /&gt;显示进度 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; libcurl支持通信过程中的进度控制。通过将CURLOPT_NOPROCESS设置为0开启进度支持。该选项默认值为1。对大多数应用程序，我们需要提供一个进度显示回调。libcurl会不定期的将当前传输的进度通过回调函数告诉你的程序。回调函数的原型如下： &lt;/p&gt;&lt;p&gt;int progress_callback(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow);&amp;nbsp;&amp;nbsp;&amp;nbsp; 通过CURLOPT_PROGRESSFUNCTION注册该回调函数。参数clientp是一个用户自定义指针，应用程序通过CURLOPT_PROCESSDATA属性将该自定义指定传递给libcurl。libcurl对该参数不作任何处理，只是简单将其传递给回调函数。 &lt;/p&gt;&lt;p&gt;在C++中使用libcurl &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 在C++中使用libcurl跟在C语言中没有任何区别，只有一个地方要注意：回调函数不能是类的非静态成员函数。例如： &lt;/p&gt;&lt;p&gt;class AClass { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; static size_t write_data(void *ptr, size_t size, size_t nmemb, void *ourpointer) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /* do what you want with the data */&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;}&amp;nbsp; &lt;br /&gt;代理 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 什么是代理？Merrian-Webster的解释是：一个通过验证的用户扮演另一个用户。今天，代理已经被广泛的使用。许多公司提供网络代理服务器，允许员工的网络客户端访问、下载文件。代理服务器处理这些用户的请求。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; libcurl支持SOCKS和HTTP代理。使用代理，libcurl会把用户输入的URL提交给代理服务器，而不是直接根据URL去访问远程资源。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 当前版本的libcurl并不支持SOCKS代理的所有功能。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 对于HTTP代理来说，即使请求的URL不是一个合法的HTTP URL（比方你提供了一个ftp的url），它仍然会先被提交到HTTP代理。 &lt;/p&gt;&lt;p&gt;代理选项&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; CURLOPT_PROXY属性用于设置libcurl使用的代理服务器地址： &lt;/p&gt;&lt;p&gt;curl_easy_setopt(easy_handle, CURLOPT_PROXY, "proxy-host.com:8080");&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 可以把主机名与端口号分开设置： &lt;/p&gt;&lt;p&gt;curl_easy_setopt(easy_handle, CURLOPT_PROXY, "proxy-host.com"); &lt;br /&gt;curl_easy_setopt(easy_handle, CURLOPT_PROXYPORT, "8080");&amp;nbsp; // 端口号是用字符串还是整数？？&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 有些代理服务器要求用户通过验证之后才允许接受其请求，此时应该先提供验证信息： &lt;/p&gt;&lt;p&gt;curl_easy_setopt(easy_handle, CURLOPT_PROXYUSERPWD, "user:password");&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 还要告诉libcurl使用的代理类型（如果没有提供，libcurl会认为是HTTP代理）： &lt;/p&gt;&lt;p&gt;curl_easy_setopt(easy_handle, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS4);&amp;nbsp; &lt;br /&gt;环境变量&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 对于有些协议，libcurl会自动检测并使用一些环境变量，并根据这些环境变量来确定要使用的代理服务器。这些环境变量的名称格式一般是"[protocol]_proxy"（注意小写）。例如输入一个HTTP的URL，那么名称为"http_proxy"的环境变量就会被检测是否存在，如果存在，libcurl会使用该环境变量指定的代理。相同的规则也适用于FTP。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 这些环境变量的值的格式必须是这样的："[protocol://][user:password@]machine[:port]"。libcurl会忽略掉[protocol://]，如果没有提供端口号，libcurl使用该协议的默认端口。&amp;nbsp; &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 有两个比较特殊的环境变量：'all_proxy'与'no_proxy'。如果一个URL所对应的协议，它的环境变量没有设置，那么'all_proxy'指定的代理将被使用。'no_proxy'则指定了一个不应被使用的代理主机的列表。例如：no_proxy的值是'192.168.1.10'，即使存在http_proxy，它的值也是'192.168.1.10'，'192.168.1.10'也不会被作为代理。no_proxy=&amp;#8221;*&amp;#8221;表示不允许使用任何代理。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 显式地将CURLOPT_PROXY属性设置为空，可以禁止libcurl检查并使用环境变量来使用代理。&lt;/p&gt;&lt;p&gt;SSL和代理&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SSL为点到点通信提供安全保障。它包含一些强壮的加密措施和其他安全检测，这使得上面讲到的代理方式不适用于SSL。除非代理服务器提供专用通道，对进出该代理服务器的数据不作任何检测或禁止。通过HTTP代理服务器打开SSL连接，意味着代理服务器要直接连接到目标主机的指定端口。因为代理服务器对在专用通道上传输的数据的类型毫无所知，所以它往往会使某些机制失效，如缓存机制。许多组织只允许在443端口上创建这种类型的数据通道。&lt;/p&gt;&lt;p&gt;代理通道(Tunneling Through Proxy)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 正如上面讲到的，要使SSL工作必须在代理服务器创建专用数据通道，通常专用通道只被限制应用于HTTPS。通过HTTP代理在应用程序与目标之间创建一个专用数据通道，应该预防在该专有通道上执行非HTTP的操作，如进行FTP上传或执行FTP命令。代理服务器管理员应该禁止非法的操作。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 通过CURLOPT_HTTPPROXYTUNNEL属性来告诉libcurl使用代理通道：&lt;/p&gt;&lt;p&gt;curl_easy_setopt(easy_handle, CURLOPT_HTTPPROXYTUNNEL, 1L);&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 有时候你想通过代理通道执行平常的HTTP操作，而实际上却可能使你不经过代理服务器而直接与远程主机进行交互。libcurl不会代替这种新引入的行为。&lt;/p&gt;&lt;p&gt;自动配置代理&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 许多浏览器支持自动配置代理，例如NetScape。libcurl并不支持这些。 &lt;/p&gt;&lt;p&gt;持久化的好处(Persistence Is The Way to Happiness) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 当需要发送多次请求时，应该重复使用easy handle。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 每次执行完curl_easy_perform，licurl会继续保持与服务器的连接。接下来的请求可以使用这个连接而不必创建新的连接（如果目标主机是同一个的话）。这样可以减少网络开销。 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 即使连接被释放了，libcurl也会缓存这些连接的会话信息，这样下次再连接到目标主机上时，就可以使用这些信息，从而减少重新连接所需的时间。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; FTP连接可能会被保存较长的时间。因为客户端要与FTP服务器进行频繁的命令交互。对于有访问人数上限的FTP服务器，保持一个长连接，可以使你不需要排除等待，就直接可以与FTP服务器通信。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; libcurl会缓存DNS的解析结果。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 在今后的libcurl版本中，还会添加一些特性来提高数据通信的效率。 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 每个easy handle都会保存最近使用的几个连接，以备重用。默认是5个。可以通过CURLOPT_MAXCONNECTS属性来设置保存连接的数量。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 如果你不想重用连接，将CURLOPT_FRESH_CONNECT属性设置为1。这样每次提交请求时，libcurl都会先关闭以前创建的连接，然后重新创建一个新的连接。也可以将CURLOPT_FORBID_REUSE设置为1，这样每次执行完请求，连接就会马上关闭。&lt;/p&gt;&lt;p&gt;libcurl使用的HTTP消息头&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 当使用libcurl发送http请求时，它会自动添加一些http头。我们可以通过CURLOPT_HTTPHEADER属性手动替换、添加或删除相应的HTTP消息头。 &lt;/p&gt;&lt;p&gt;Host &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; http1.1（大部分http1.0)版本都要求客户端请求提供这个信息头。 &lt;/p&gt;&lt;p&gt;Pragma &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "no-cache"。表示不要缓冲数据。 &lt;/p&gt;&lt;p&gt;Accept &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "*/*"。表示允许接收任何类型的数据。 &lt;/p&gt;&lt;p&gt;Expect &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 以POST的方式向HTTP服务器提交请求时，libcurl会设置该消息头为"100-continue"，它要求服务器在正式处理该请求之前，返回一个"OK"消息。如果POST的数据很小，libcurl可能不会设置该消息头。 &lt;/p&gt;&lt;p&gt;自定义选项&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 当前越来越多的协议都构建在HTTP协议之上（如：soap），这主要归功于HTTP的可靠性，以及被广泛使用的代理支持（可以穿透大部分防火墙）。 这些协议的使用方式与传统HTTP可能有很大的不同。对此，libcurl作了很好的支持。 &lt;/p&gt;&lt;p&gt;自定义请求方式(CustomRequest) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; HTTP支持GET, HEAD或者POST提交请求。可以设置CURLOPT_CUSTOMREQUEST来设置自定义的请求方式，libcurl默认以GET方式提交请求： &lt;/p&gt;&lt;p&gt;curl_easy_setopt(easy_handle, CURLOPT_CUSTOMREQUEST, "MYOWNREQUEST");&amp;nbsp; &lt;br /&gt;修改消息头&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; HTTP协议提供了消息头，请求消息头用于告诉服务器如何处理请求；响应消息头则告诉浏览器如何处理接收到的数据。在libcurl中，你可以自由的添加这些消息头：&lt;/p&gt;&lt;p&gt;struct curl_slist *headers=NULL; /* init to NULL is important */&lt;br /&gt;headers = curl_slist_append(headers, "Hey-server-hey: how are you?");&lt;br /&gt;headers = curl_slist_append(headers, "X-silly-content: yes");&lt;br /&gt;/* pass our list of custom made headers */&lt;br /&gt;curl_easy_setopt(easyhandle, CURLOPT_HTTPHEADER, headers);&lt;br /&gt;curl_easy_perform(easyhandle); /* transfer http */&lt;br /&gt;curl_slist_free_all(headers); /* free the header list */&amp;nbsp;&amp;nbsp;&amp;nbsp; 对于已经存在的消息头，可以重新设置它的值：&lt;/p&gt;&lt;p&gt;headers = curl_slist_append(headers, "Accept: Agent-007");&amp;nbsp; &lt;br /&gt;headers = curl_slist_append(headers, "Host: munged.host.line");&amp;nbsp; &lt;br /&gt;删除消息头 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 对于一个已经存在的消息头，设置它的内容为空，libcurl在发送请求时就不会同时提交该消息头： &lt;/p&gt;&lt;p&gt;headers = curl_slist_append(headers, "Accept:");&amp;nbsp; &lt;br /&gt;强制分块传输(Enforcing chunked transfer-encoding)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; （这段文字理解可能有误码）以非GET的方式提交HTTP请求时，如果设置了自定义的消息头&amp;#8221;Transfer-Encoding:chunked&amp;#8221;，libcurl会分块提交数据，即使要上传的数据量已经知道。在上传数据大小未知的情况下，libcurl自动采用分块上传数据。（译者注：非GET方式提交请求，提交的数据量往往比较大。）&lt;/p&gt;&lt;p&gt;HTTP版本 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 每一次http请求，都包含一个表示当前使用http版本的消息头。libcurl默认使用HTTP 1.1。可以通过CURLOPT_HTTP_VERSION属性来设置具体的版本号：&lt;/p&gt;&lt;p&gt;curl_easy_setopt(easy_handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);&amp;nbsp; &lt;br /&gt;FTP自定义命令&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 并不是所以的协议都像HTTP那样，通过消息头来告诉服务器如何处理请求。对于FTP，你就要使用另外的方式来处理。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 发送自定义的命令到ftp服务器，意味着你发送的命令必须是能被ftp服务器理解的命令（FTP协议中定义的命令，参考rfc959）。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 下面是一个简单的例子，在文件传输操作操作之前删除指定文件：&lt;/p&gt;&lt;p&gt;headers = curl_slist_append(headers, "DELE file-to-remove");/* pass the list of custom commands to the handle */&lt;br /&gt;curl_easy_setopt(easyhandle, CURLOPT_QUOTE, headers);// curl_easy_setopt(easyhandle, CURLOPT_POSTQUOTE, headers); // 在数据传输之后操行删除操作curl_easy_perform(easyhandle); /* transfer ftp data! */&lt;br /&gt;curl_slist_free_all(headers); /* free the header list */&amp;nbsp;&amp;nbsp;&amp;nbsp; FTP服务器执行命令的顺序，同这些命令被添加到列表中顺序是一致的。发往服务器的命令列表中，只要有一个命令执行失败，ftp服务器就会返回一个错误代码，此时libcurl将直接返回CURLE_QUOTE_ERROR，不再执行剩余的FTP命令。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 将CURLOPT_HEADER设置为1，libcurl获取目标文件的信息，并以HTTP消息头的样式来输出消息头。 &lt;/p&gt;&lt;p&gt;FTP自定义CUSTOMREQUEST &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 使用CURLOPT_CUSTOMREQUEST属性，可以向FTP服务器发送命令。"NLST"是ftp默认的列出文件列表的命令。 下面的代码用于列出FTP服务器上的文件列表：&lt;/p&gt;&lt;p&gt;int main(int argc, char **argv)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;curl_global_init(CURL_GLOBAL_WIN32);&amp;nbsp;CURL *easy_handle = curl_easy_init();&lt;br /&gt;&amp;nbsp;curl_easy_setopt(easy_handle, CURLOPT_URL, "&lt;a href="http://www.cnblogs.com/Phoenix-Rock/admin/ftp://127.0.0.1/"&gt;http://www.cnblogs.com/Phoenix-Rock/admin/ftp://127.0.0.1/&lt;/a&gt;");&lt;br /&gt;&amp;nbsp;curl_easy_setopt(easy_handle, CURLOPT_CUSTOMREQUEST, "NLST");&amp;nbsp;curl_easy_perform(easy_handle);&lt;br /&gt;&amp;nbsp;curl_easy_cleanup(easy_handle);&lt;br /&gt;&amp;nbsp;curl_global_cleanup();&lt;/p&gt;&lt;p&gt;&amp;nbsp;return 0;} &lt;br /&gt;Cookies Without Chocolate Chips&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cookie是一个键值对的集合，HTTP服务器发给客户端的cookie，客户端提交请求的时候，也会将cookie发送到服务器。服务器可以根据cookie来跟踪用户的会话信息。cookie有过期时间，超时后cookie就会失效。cookie有域名和路径限制，cookie只能发给指定域名和路径的HTTP服务器。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; cookie以消息头&amp;#8221;Set-Cookie&amp;#8221;的形式从HTTP服务器发送到客户端；客户端发以消息头&amp;#8221;Cookie&amp;#8221;的形式将Cookie提交到HTTP服务器。为了对这些东西有个直观的概念，下图是FireFox中，使用Firebug跟踪到的cookie消息头： &lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;a href="http://p.blog.csdn.net/images/p_blog_csdn_net/JGood/601714/o_pic1_4.jpg"&gt;&lt;img title="pic1" border="0" alt="pic1" src="http://p.blog.csdn.net/images/p_blog_csdn_net/JGood/601714/o_pic1_thumb_4.jpg" width="631" height="526" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp; 在libcurl中，可以通过CURLOPT_COOKIE属性来设置发往服务器的cookie： &lt;/p&gt;&lt;p&gt;curl_easy_setopt(easy_handle, CURLOPT_COOKIE, "name1=var1; name2=var2;");&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 下面的例子演示了如何使用libcurl发送cookie信息给HTTP服务器，代码非常的简单：&lt;/p&gt;&lt;p&gt;int main(int argc, char **argv)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;curl_global_init(CURL_GLOBAL_WIN32);&lt;br /&gt;&amp;nbsp;CURL *easy_handle = curl_easy_init();&lt;/p&gt;&lt;p&gt;&amp;nbsp;curl_easy_setopt(easy_handle, CURLOPT_URL, &lt;a href="http://localhost:2210/Default.aspx"&gt;http://localhost:2210/Default.aspx&lt;/a&gt;);&lt;br /&gt;&amp;nbsp;curl_easy_setopt(easy_handle, CURLOPT_COOKIE, "name=JGood; address=HangZhou");&lt;/p&gt;&lt;p&gt;&amp;nbsp;curl_easy_perform(easy_handle);&lt;br /&gt;&amp;nbsp;curl_easy_cleanup(easy_handle);&lt;br /&gt;&amp;nbsp;curl_global_cleanup();&lt;/p&gt;&lt;p&gt;&amp;nbsp;return 0;&lt;br /&gt;}&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;下图是在ASP.NET Web服务器上调试时跟踪到的Cookie数据：&lt;/p&gt;&lt;p&gt;&lt;a href="http://p.blog.csdn.net/images/p_blog_csdn_net/JGood/601714/o_pic1_5.jpg"&gt;&lt;img title="pic1" border="0" alt="pic1" src="http://p.blog.csdn.net/images/p_blog_csdn_net/JGood/601714/o_pic1_thumb_5.jpg" width="554" height="282" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 在实在的应用场景中，你可能需要保存服务器发送给你的cookie，并在接下来的请求中，把这些cookie一并发往服务器。所以，可以把上次从服务器收到的所有响应头信息保存到文本文件中，当下次需要向服务器发送请求时，通过CURLOPT_COOKIEFILE属性告诉libcurl从该文件中读取cookie信息。 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 设置CURLOPT_COOKIEFILE属性意味着激活libcurl的cookie parser。在cookie parser被激活之前，libcurl忽略所以之前接收到的cookie信息。cookie parser被激活之后，cookie信息将被保存内存中，在接下来的请求中，libcurl会自动将这些cookie信息添加到消息头里，你的应用程序不需要做任何事件。大多数情况下，这已经足够了。需要注意的是，通过CURLOPT_COOKIEFILE属性来激活cookie parser，给CURLOPT_COOKIEFILE属性设置的一个保存cookie信息的文本文件路径，可能并不需要在磁盘上物理存在。 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 如果你需要使用NetScape或者FireFox浏览器的cookie文件，你只要用这些浏览器的cookie文件的路径来初始化CURLOPT_COOKIEFILE属性，libcurl会自动分析cookie文件，并在接下来的请求过程中使用这些cookie信息。 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; libcurl甚至能够把接收到的cookie信息保存成能被Netscape/Mozilla的浏览器所识别的cookie文件。通过把这些称为cookie-jar。通过设置CURLOPT_COOKIEJAR选项，在调用curl_easy_cleanup释放easy handle的时候，所有的这些cookie信息都会保存到cookie-jar文件中。这就使得cookie信息能在不同的easy handle甚至在浏览器之间实现共享。 &lt;/p&gt;&lt;p&gt;FTP Peculiarities We Need &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 在使用FTP协议进行数据传输的时候，需要创建两个连接。第一个连接用于传输控制命令，另一个连接用于传输数据。（关于FTP的通信过程，请参考这篇文章：&lt;a href="http://www.wangjia.net/bo-blog/post/698/"&gt;http://www.wangjia.net/bo-blog/post/698/&lt;/a&gt;）。 FTP通信需要创建两个连接这个事实往往被很多人忽略。根据第二个连接的发起方是谁，可以分为主动模式与被动模式。libcurl对此都提供了支持。libcurl默认使用被动模式，因为被动模式可以方便的穿透防火墙，NAT等问题。在被动模式下，libcurl要求ftp服务器打开一个新的端口监听，然后libcurl连接该端口用于数据传输。如果使用主动模式，程序必须告诉FTP服务器你监听的IP与端口，通过设置CURLOPT_FTPPORT属性来完成。 &lt;/p&gt;&lt;p&gt;Headers Equal Fun &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; （这段文字我理解的很模糊，请读者参考原文）有些协议提供独立于正常数据的 消息头、meta-data。正常的数据流里通常不包括 信息头和元数据。可以将CURLOPT_HEADER设置为1，使信息头、元数据也能出现在数据流中。libcurl的强大之处在于，它能够从数据流中解析出消息头，&amp;#8230;.&lt;/p&gt;&lt;p&gt;Post Transfer Information &lt;br /&gt;[ curl_easy_getinfo ] &lt;/p&gt;&lt;p&gt;安全考虑&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 请参考原文，此处略。 &lt;/p&gt;&lt;p&gt;使用multi interface同时进行多项传输&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 上面介绍的easy interface以同步的方式进行数据传输，curl_easy_perform会一直阻塞到数据传输完毕后返回，且一次操作只能发送一次请求，如果要同时发送多个请求，必须使用多线程。 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 而multi interface以一种简单的、非阻塞的方式进行传输，它允许在一个线程中，同时提交多个相同类型的请求。 在使用multi interface之前，你应该掌握easy interface的基本使用。因为multi interface是建立在easy interface基础之上的，它只是简单的将多个easy handler添加到一个multi stack，而后同时传输而已。 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 使用multi interface很简单，首先使用curl_multi_init()函数创建一个multi handler，然后使用curl_easy_init()创建一个或多个easy handler，并按照上面几章介绍的接口正常的设置相关的属性，然后通过curl_multi_add_handler将这些easy handler添加到multi handler，最后调用curl_multi_perform进行数据传输。 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; curl_multi_perform是异步的、非阻塞的函数。如果它返回CURLM_CALL_MULTI_PERFORM，表示数据通信正在进行。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 通过select()来操作multi interface将会使工作变得简单（译者注：其实每个easy handler在低层就是一个socket，通过select()来管理这些socket，在有数据可读/可写/异常的时候，通知应用程序）。在调用select()函数之前，应该使用curl_multi_fdset来初始化fd_set变量。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; select()函数返回时，说明受管理的低层socket可以操作相应的操作（接收数据或发送数据，或者连接已经断开），此时应该马上调用curl_multi_perform，libcurl将会执行相应操作。使用select()时，应该设置一个较短的超时时间。在调用select()之前，造成不要忘记通过curl_multi_fdset来初始化fd_set，因为每次操作，fd_set中的文件描述符可能都不一样。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 如果你想中止multi stack中某一个easy handle的数据通信，可以调用curl_multi_remove_handle函数将其从multi stack中取出。千万另忘记释放掉easy handle（通过curl_easy_cleanup()函数）。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 当multi stack中的一个eash handle完成数据传输的时候，同时运行的传输任务数量就会减少一个。当数量降到0的时候，说明所有的数据传输已经完成。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; curl_multi_info_read用于获取当前已经完成的传输任务信息，它返回每一个easy handle的CURLcode状态码。可以根据这个状态码来判断每个easy handle传输是否成功。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 下面的例子，演示了如何使用multi interface进行网页抓取：&lt;/p&gt;&lt;p&gt;int main(int argc, char **argv)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;// 初始化&lt;br /&gt;&amp;nbsp;curl_global_init(CURL_GLOBAL_WIN32);&lt;br /&gt;&amp;nbsp;CURLM *multi_handle = NULL;&lt;br /&gt;&amp;nbsp;CURL *easy_handle1 = NULL;&lt;br /&gt;&amp;nbsp;CURL *easy_handle2 = NULL;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;extern size_t save_sina_page(void *buffer, size_t size, size_t count, void *user_p);&lt;br /&gt;&amp;nbsp;extern size_t save_sohu_page(void *buffer, size_t size, size_t count, void *user_p);&lt;br /&gt;&amp;nbsp;FILE *fp_sina = fopen("sina.html", "ab+");&lt;br /&gt;&amp;nbsp;FILE *fp_sohu = fopen("sohu.html", "ab+");&lt;/p&gt;&lt;p&gt;&amp;nbsp;multi_handle = curl_multi_init();&lt;/p&gt;&lt;p&gt;&amp;nbsp;// 设置easy handle&lt;br /&gt;&amp;nbsp;easy_handle1 = curl_easy_init();&lt;br /&gt;&amp;nbsp;curl_easy_setopt(easy_handle1, CURLOPT_URL, "&lt;a href="http://www.sina.com.cn/"&gt;http://www.sina.com.cn/&lt;/a&gt;");&lt;br /&gt;&amp;nbsp;curl_easy_setopt(easy_handle1, CURLOPT_WRITEFUNCTION, &amp;amp;save_sina_page);&lt;br /&gt;&amp;nbsp;curl_easy_setopt(easy_handle1, CURLOPT_WRITEDATA, fp_sina);&lt;/p&gt;&lt;p&gt;&amp;nbsp;easy_handle2 = curl_easy_init();&lt;br /&gt;&amp;nbsp;curl_easy_setopt(easy_handle2, CURLOPT_URL, "&lt;a href="http://www.sohu.com/"&gt;http://www.sohu.com/&lt;/a&gt;");&lt;br /&gt;&amp;nbsp;curl_easy_setopt(easy_handle2, CURLOPT_WRITEFUNCTION, &amp;amp;save_sohu_page);&lt;br /&gt;&amp;nbsp;curl_easy_setopt(easy_handle2, CURLOPT_WRITEDATA, fp_sohu);&lt;/p&gt;&lt;p&gt;&amp;nbsp;// 添加到multi stack&lt;br /&gt;&amp;nbsp;curl_multi_add_handle(multi_handle, easy_handle1);&lt;br /&gt;&amp;nbsp;curl_multi_add_handle(multi_handle, easy_handle2);&lt;/p&gt;&lt;p&gt;&amp;nbsp;// &lt;br /&gt;&amp;nbsp;int running_handle_count;&lt;br /&gt;&amp;nbsp;while (CURLM_CALL_MULTI_PERFORM == curl_multi_perform(multi_handle, &amp;amp;running_handle_count))&lt;br /&gt;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;cout &amp;lt;&amp;lt; running_handle_count &amp;lt;&amp;lt; endl;&lt;br /&gt;&amp;nbsp;}&lt;/p&gt;&lt;p&gt;&amp;nbsp;while (running_handle_count)&lt;br /&gt;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;timeval tv;&lt;br /&gt;&amp;nbsp;&amp;nbsp;tv.tv_sec = 1;&lt;br /&gt;&amp;nbsp;&amp;nbsp;tv.tv_usec = 0;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;int max_fd;&lt;br /&gt;&amp;nbsp;&amp;nbsp;fd_set fd_read;&lt;br /&gt;&amp;nbsp;&amp;nbsp;fd_set fd_write;&lt;br /&gt;&amp;nbsp;&amp;nbsp;fd_set fd_except;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;FD_ZERO(&amp;amp;fd_read);&lt;br /&gt;&amp;nbsp;&amp;nbsp;FD_ZERO(&amp;amp;fd_write);&lt;br /&gt;&amp;nbsp;&amp;nbsp;FD_ZERO(&amp;amp;fd_except);&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;curl_multi_fdset(multi_handle, &amp;amp;fd_read, &amp;amp;fd_write, &amp;amp;fd_except, &amp;amp;max_fd);&lt;br /&gt;&amp;nbsp;&amp;nbsp;int return_code = select(max_fd + 1, &amp;amp;fd_read, &amp;amp;fd_write, &amp;amp;fd_except, &amp;amp;tv);&lt;br /&gt;&amp;nbsp;&amp;nbsp;if (SOCKET_ERROR == return_code)&lt;br /&gt;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;cerr &amp;lt;&amp;lt; "select error." &amp;lt;&amp;lt; endl;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;break;&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;else&lt;br /&gt;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;while (CURLM_CALL_MULTI_PERFORM == curl_multi_perform(multi_handle, &amp;amp;running_handle_count))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cout &amp;lt;&amp;lt; running_handle_count &amp;lt;&amp;lt; endl;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;}&lt;/p&gt;&lt;p&gt;&amp;nbsp;// 释放资源&lt;br /&gt;&amp;nbsp;fclose(fp_sina);&lt;br /&gt;&amp;nbsp;fclose(fp_sohu);&lt;br /&gt;&amp;nbsp;curl_easy_cleanup(easy_handle1);&lt;br /&gt;&amp;nbsp;curl_easy_cleanup(easy_handle2);&lt;br /&gt;&amp;nbsp;curl_multi_cleanup(multi_handle);&lt;br /&gt;&amp;nbsp;curl_global_cleanup();&lt;/p&gt;&lt;p&gt;&amp;nbsp;return 0;&lt;br /&gt;}&lt;/p&gt;&lt;p&gt;size_t save_sina_page(void *buffer, size_t size, size_t count, void *user_p)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;return fwrite(buffer, size, count, (FILE *)user_p);&lt;br /&gt;}&lt;/p&gt;&lt;p&gt;size_t save_sohu_page(void *buffer, size_t size, size_t count, void *user_p)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;return fwrite(buffer, size, count, (FILE *)user_p);&lt;br /&gt;}&lt;/p&gt;&lt;img src="http://www.cnblogs.com/Phoenix-Rock/aggbug/2025634.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/Phoenix-Rock/archive/2011/04/23/libcurl.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/Phoenix-Rock/archive/2010/08/11/VS2010-Model.html</id><title type="text">使用Visual Studio 2010 Team System中的架构师工具（设计与建模）</title><summary type="text">使用Visual Studio 2010 Team System中的架构师工具（设计与建模）</summary><published>2010-08-11T06:49:00Z</published><updated>2010-08-11T06:49:00Z</updated><author><name>天马行空（笨笨）</name><uri>http://www.cnblogs.com/Phoenix-Rock/</uri></author><link rel="alternate" href="http://www.cnblogs.com/Phoenix-Rock/archive/2010/08/11/VS2010-Model.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/Phoenix-Rock/archive/2010/08/11/VS2010-Model.html"/><content type="html">&lt;p&gt;&lt;a name="_Toc142568388"&gt;&lt;/a&gt;&lt;a name="_Toc142540302"&gt;&lt;/a&gt;&lt;a name="_Toc142539759"&gt;&lt;/a&gt;&lt;a name="_Toc145818307"&gt;&lt;/a&gt;&lt;a name="_Toc145298435"&gt;&lt;/a&gt;&lt;a name="_Toc144549578"&gt;&lt;/a&gt;&lt;a name="_Toc142971970"&gt;&lt;/a&gt;&lt;a name="_Toc142725900"&gt;&lt;/a&gt;&lt;strong&gt;&lt;em&gt; &lt;/em&gt;&lt;/strong&gt;&lt;em&gt;&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;a name="_Toc145818308"&gt;&lt;/a&gt;&lt;a name="_Toc137338491"&gt;&lt;/a&gt;&lt;a name="_Toc130671587"&gt;Lab 1: &lt;/a&gt;应用程序建模 &lt;p&gt;&lt;strong&gt;实验目标&lt;/strong&gt; &lt;p&gt;这个实验的目的是展示如何在Visual Studio 2010旗舰版中进行应用程序建模。团队中的架构师会通过建模确定应用程序是否满足客户的需求。 你可以创建不同级别的详细模型，并将它们彼此结合、测试然后发布到你的开发计划里。 &lt;p&gt;在这个实验中, 我们将重点放在如何创建一系列简单的系统建模图形上. &lt;p&gt;每个练习应该在 30分钟内完成. &lt;p&gt;&lt;a name="_Toc11402523"&gt;&lt;/a&gt;&lt;a name="_Toc536017583"&gt;&lt;/a&gt;&lt;a name="_Toc145818310"&gt;&lt;/a&gt;&lt;a name="_Toc137338493"&gt;&lt;/a&gt;&lt;a name="_Toc130671589"&gt;Exercise 1 &amp;#8211; &lt;/a&gt;理解用户需求 &lt;p&gt;绘制活动、类以及其他UML图形能帮助架构师清晰辨别客户的习惯、业务规则以及其他需求，从而使设计与客户需求保持一致。 &lt;p&gt;微软Visual Studio 2010旗舰版可以让你绘制关于客户的活动以及你的系统如何帮助客户达到他们的预期，这样有助于你理解用户需求，并能够与客户进行良好的沟通和讨论。 &lt;p&gt;需求模型可以帮助你： &lt;p&gt;l 专注于系统的外部行为，并与系统内部设计分离。 &lt;p&gt;l 使用比自然语言更少的更精准的方法描述客户以及投资者的需求。 &lt;p&gt;l 定义一个可以由客户、开发人员以及测试人员一致使用的术语词汇。 &lt;p&gt;l 减少需求中的差距和分歧。 &lt;p&gt;l 降低针对需求变化的响应所付出的工作量。 &lt;p&gt;l 规划哪些功能需要开发。 &lt;p&gt;l 使用模型作为系统测试的基础，使其成为客户需求与测试人员之间的纽带。当需求变更时，这种纽带可以帮助你迅速更新测试。这样可以使系统尽快满足新的需求。 &lt;p&gt;如果你将重点放在每次迭代开始时与客户的讨论上，那么需求模型会给你提供很大的便利。而且你不能在完成设计之前编写详细代码。部分应用程序功能，即使它非常简单，通常也是构成与用户讨论时最敏感的需求基础。模型可以有效地总结讨论结果。 &lt;p&gt;&lt;a name="_Toc145818311"&gt;&lt;/a&gt;&lt;a name="_Toc137338494"&gt;&lt;/a&gt;&lt;a name="_Toc130671590"&gt;&lt;strong&gt;Task 1 &amp;#8211;&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;用户需求建模&amp;#8212;&amp;#8212;&lt;/strong&gt;&lt;strong&gt;用例图&lt;/strong&gt;&lt;strong&gt;&lt;/strong&gt; &lt;p&gt;创建用例图来描述谁使用该系统，以及他们如何使用。用例图代表一个系统用户的目标，以及他们执行程序的流程。 &lt;p&gt;这个任务中，客户需要一个在线餐饮销售系统。该系统必须允许客户从菜单中选择食品，而且必须提供销售商更新食品品种的菜单。你可以使用以下步骤实现该用例图： &lt;p&gt;1. 启动 &lt;strong&gt;Microsoft Visual Studio 2010&lt;/strong&gt;. &lt;p&gt;2. 选择 &lt;strong&gt;文件&lt;/strong&gt;-&amp;gt;新建-&amp;gt;项目，如下所示：. &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image004_2.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image004" border="0" alt="clip_image004" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image004_thumb.gif" width="5" height="5" /&gt;&lt;/a&gt; &lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image006_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image006" border="0" alt="clip_image006" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image006_thumb.jpg" width="329" height="484" /&gt;&lt;/a&gt; &lt;p&gt;&lt;a name="_Ref130569020"&gt;Figure &lt;/a&gt;1: 打开新建项目对话框 &lt;p&gt;3. 在&lt;strong&gt;新建项目&lt;/strong&gt;对话框中, 选择项目类型下的&lt;strong&gt;建模项目&lt;/strong&gt;，然后在右侧&lt;strong&gt;项目模板&lt;/strong&gt;中选择&lt;strong&gt;建模项目&lt;/strong&gt;&lt;strong&gt;.&lt;/strong&gt; &lt;p&gt;修改&lt;strong&gt;项目名称&lt;/strong&gt;为&lt;strong&gt;ModelingProjectDinnerNow&lt;/strong&gt;. 保持默认项目路径. &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image008_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image008" border="0" alt="clip_image008" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image008_thumb.jpg" width="644" height="365" /&gt;&lt;/a&gt; &lt;p&gt;&lt;a name="_Ref137338482"&gt;Figure &lt;/a&gt;2: 创建新建模项目 &lt;p&gt;4. 单击&lt;strong&gt;确定&lt;/strong&gt;，应用你的选择，打开一个空的建模项目.&lt;a name="_Ref130647104"&gt;&lt;br /&gt;&lt;/a&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image010_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image010" border="0" alt="clip_image010" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image010_thumb.jpg" width="644" height="384" /&gt;&lt;/a&gt; &lt;p&gt;&lt;a name="_Ref130673690"&gt;Figure &lt;/a&gt;3: 空的建模项目 &lt;p&gt;5. 在解决方案浏览器中右键单击&lt;strong&gt;ModelingProjectDinnerNow&lt;/strong&gt;&lt;strong&gt;项目&lt;/strong&gt;根节点，在弹出菜单中选择&lt;strong&gt;添加&lt;/strong&gt;&lt;strong&gt;-&amp;gt;&lt;/strong&gt;&lt;strong&gt;添加新项&lt;/strong&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image012_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image012" border="0" alt="clip_image012" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image012_thumb.jpg" width="644" height="279" /&gt;&lt;/a&gt; &lt;p&gt;Figure 4: 添加新项菜单 &lt;p&gt;6. 在弹出的&lt;strong&gt;添加新项&lt;/strong&gt;对话框中，选择&lt;strong&gt;UML&lt;/strong&gt;&lt;strong&gt;用例图&lt;/strong&gt;模板，并修改用例图的名称为&lt;strong&gt;UMLUseCaseDiagramDinnerNow.usecasediagram&lt;/strong&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image014_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image014" border="0" alt="clip_image014" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image014_thumb.jpg" width="644" height="363" /&gt;&lt;/a&gt; &lt;p&gt;Figure 5: 添加新项对话框 &lt;p&gt;7. 单击&lt;strong&gt;添加&lt;/strong&gt;，此时会打开空白用例图 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image016_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image016" border="0" alt="clip_image016" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image016_thumb.jpg" width="644" height="449" /&gt;&lt;/a&gt; &lt;p&gt;Figure 6: 空白用例图UMLUseCaseDiagramDinnerNow.usecasediagram &lt;p&gt;8. 根据案例用户需求，从左侧&lt;strong&gt;工具箱&lt;/strong&gt;中的&lt;strong&gt;UML&lt;/strong&gt;&lt;strong&gt;用例图&lt;/strong&gt;节点下拖拽两个&lt;strong&gt;用例&lt;/strong&gt;图标到右侧设计界面。 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image018_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image018" border="0" alt="clip_image018" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image018_thumb.jpg" width="644" height="449" /&gt;&lt;/a&gt; &lt;p&gt;Figure 7: 从工具箱中拖拽两个用例图标 &lt;p&gt;9. 点选&lt;strong&gt;用例图标&lt;/strong&gt;的&amp;#8221;UseCase1&amp;#8221;文字部分，使其变为可编辑状态，然后将其内容修改为&lt;strong&gt;Order a Meal&lt;/strong&gt; &lt;p&gt;10. 重复步骤9的操作，将&lt;strong&gt;用例&lt;/strong&gt;&lt;strong&gt;2&lt;/strong&gt;的用例内容修改为&lt;strong&gt;Update Menu&lt;/strong&gt;&lt;strong&gt;。&lt;/strong&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image020_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image020" border="0" alt="clip_image020" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image020_thumb.jpg" width="644" height="449" /&gt;&lt;/a&gt; &lt;p&gt;Figure 8: 用例定义修改后的效果 &lt;p&gt;11. 根据案例用户需求，从左侧&lt;strong&gt;工具箱&lt;/strong&gt;中的&lt;strong&gt;UML&lt;/strong&gt;&lt;strong&gt;用例图&lt;/strong&gt;节点下拖拽两个&lt;strong&gt;活动者&lt;/strong&gt;图标到右侧用例图设计界面 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image022_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image022" border="0" alt="clip_image022" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image022_thumb.jpg" width="644" height="449" /&gt;&lt;/a&gt; &lt;p&gt;Figure 9: 从工具箱中添加活动者 &lt;p&gt;12. 点选用&lt;strong&gt;活动者图标&lt;/strong&gt;的&amp;#8221;Actor1&amp;#8221;文字部分，使其变为可编辑状态，然后将其内容修改为&lt;strong&gt;Customer&lt;/strong&gt; &lt;p&gt;13. 重复步骤12的操作，将&lt;strong&gt;活动者&lt;/strong&gt;&lt;strong&gt;2&lt;/strong&gt;的定义修改为&lt;strong&gt;Restaurant&lt;/strong&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image024_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image024" border="0" alt="clip_image024" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image024_thumb.jpg" width="644" height="448" /&gt;&lt;/a&gt; &lt;p&gt;Figure 10: 定义活动者后的效果 &lt;p&gt;14. 在工具箱中选中&lt;strong&gt;Association&lt;/strong&gt;图标，然后在设计界面中首先点选&lt;strong&gt;Customer&lt;/strong&gt;图标，并保持鼠标按下，拖拽到&lt;strong&gt;Order a Meal&lt;/strong&gt;用例上。 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image026_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image026" border="0" alt="clip_image026" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image026_thumb.jpg" width="644" height="449" /&gt;&lt;/a&gt; &lt;p&gt;Figure 11: 选择Association图标后的效果 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image028_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image028" border="0" alt="clip_image028" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image028_thumb.jpg" width="644" height="448" /&gt;&lt;/a&gt; &lt;p&gt;Figure 12: 拖拽过程中的效果 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image030_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image030" border="0" alt="clip_image030" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image030_thumb.jpg" width="644" height="449" /&gt;&lt;/a&gt; &lt;p&gt;Figure 13: 拖拽完成的效果 &lt;p&gt;15. 按照步骤14的方法，为&lt;strong&gt;Restaurant&lt;/strong&gt;&lt;strong&gt;活动者&lt;/strong&gt;与&lt;strong&gt;Update Menu&lt;/strong&gt;&lt;strong&gt;用例&lt;/strong&gt;建立联系 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image032_2.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image032" border="0" alt="clip_image032" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image032_thumb.gif" width="410" height="160" /&gt;&lt;/a&gt; &lt;p&gt;Figure 14: 用例图初步完成效果 &lt;p&gt;16. 还可以生成更精确的用例图。例如，订餐只是购买活动的一个步骤。整个购买活动应该还包含付款和交货等。 &lt;p&gt;17. 在工具箱中选择&lt;strong&gt;子系统&lt;/strong&gt;图标，并将其拖拽到设计界面中，放置于前一步骤中完成的用例图的下方 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image034_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image034" border="0" alt="clip_image034" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image034_thumb.jpg" width="567" height="484" /&gt;&lt;/a&gt; &lt;p&gt;Figure 15: 添加子系统图标 &lt;p&gt;18. 点选子系统图标中左上角的&amp;#8220;&lt;strong&gt;SubSystem1&amp;#8221;&lt;/strong&gt;&lt;strong&gt;文字&lt;/strong&gt;，使其可以编辑。将&amp;#8220;&lt;strong&gt;SubSystem1&amp;#8221;&lt;/strong&gt;文本修改为&amp;#8220;&lt;strong&gt;Dinner Now System&amp;#8221;&lt;/strong&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image036_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image036" border="0" alt="clip_image036" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image036_thumb.jpg" width="569" height="484" /&gt;&lt;/a&gt; &lt;p&gt;Figure 16: 修改子系统名称 &lt;p&gt;19. 选中上面我们定义的两个用例：Order a Meal、Update Menu。将其拖拽到子系统图标内，并调整相互位置。 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image038_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image038" border="0" alt="clip_image038" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image038_thumb.jpg" width="568" height="484" /&gt;&lt;/a&gt; &lt;p&gt;Figure 17: 将用例拖拽到子系统内 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image040_2.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image040" border="0" alt="clip_image040" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image040_thumb.gif" width="458" height="260" /&gt;&lt;/a&gt; &lt;p&gt;Figure 18: 目前为止完成的更精确的用例图 &lt;p&gt;20. 从工具箱中拖拽两次&lt;strong&gt;用例图标&lt;/strong&gt;到&lt;strong&gt;子系统图标&lt;/strong&gt;内，分别定义为&lt;strong&gt;Buy a Meal&lt;/strong&gt;&lt;strong&gt;、&lt;/strong&gt;&lt;strong&gt;Pay for Meal&lt;/strong&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image042_2.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image042" border="0" alt="clip_image042" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image042_thumb.gif" width="458" height="284" /&gt;&lt;/a&gt; &lt;p&gt;Figure 19: 添加子系统内部用例后的效果 &lt;p&gt;21. 由于订餐和付款共同属于购买行为的组成部分，所以Order a Meal、Pay for Meal都包含在Buy a Meal中。需要在工具箱中选中&lt;strong&gt;包含图标，&lt;/strong&gt;分别在&lt;strong&gt;Buy a Meal &lt;/strong&gt;&lt;strong&gt;与&lt;/strong&gt;&lt;strong&gt; Order a Meal&lt;/strong&gt; ；&lt;strong&gt;Buy a Meal &lt;/strong&gt;&lt;strong&gt;与&lt;/strong&gt;&lt;strong&gt;Pay for Meal&lt;/strong&gt;之间建立包含关系。 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image044_2.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image044" border="0" alt="clip_image044" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image044_thumb.gif" width="458" height="284" /&gt;&lt;/a&gt; &lt;p&gt;Figure 20: 建立Buy a Meal包含关系后的效果 &lt;p&gt;22. 由于Buy a Meal 作为客户使用的总用例，所以这里&lt;strong&gt;删除&lt;/strong&gt;&lt;strong&gt;Customer&lt;/strong&gt;&lt;strong&gt;活动者与&lt;/strong&gt;&lt;strong&gt;Order a Meal&lt;/strong&gt;&lt;strong&gt;用例的联系&lt;/strong&gt;，&lt;strong&gt;建立&lt;/strong&gt;&lt;strong&gt;Customer&lt;/strong&gt;&lt;strong&gt;活动者与&lt;/strong&gt;&lt;strong&gt;Buy a Meal&lt;/strong&gt;&lt;strong&gt;用例的联系。&lt;/strong&gt;调整用例之间的位置。 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image046_2.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image046" border="0" alt="clip_image046" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image046_thumb.gif" width="530" height="308" /&gt;&lt;/a&gt; &lt;p&gt;Figure 21: 修改Customer活动者关系后的效果 &lt;p&gt;23. 由于送餐并不属于Dinner Now System的功能，可能会有专门的物流或快递系统负责，这里，将送餐定义在Dinner Now System系统的外部。&lt;strong&gt;在&lt;/strong&gt;&lt;strong&gt;Dinner Now System&lt;/strong&gt;&lt;strong&gt;子系统图标外部&lt;/strong&gt;添加一个新的用例，定义为&lt;strong&gt;Deliver Meal&lt;/strong&gt;&lt;strong&gt;。&lt;/strong&gt;并指定它与&lt;strong&gt;Restaurant&lt;/strong&gt;&lt;strong&gt;活动者&lt;/strong&gt;之间的&lt;strong&gt;联系&lt;/strong&gt;。 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image048_2.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image048" border="0" alt="clip_image048" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image048_thumb.gif" width="542" height="392" /&gt;&lt;/a&gt; &lt;p&gt;Figure 22: 添加送餐用例后的效果 &lt;p&gt;24. 送餐用例虽不属于Dinner Now System系统的功能，但是也是购买行为的组成部分，这里需要建立&lt;strong&gt;Buy a Meal&lt;/strong&gt;&lt;strong&gt;用例与&lt;/strong&gt;&lt;strong&gt;Deliver Meal&lt;/strong&gt;&lt;strong&gt;用例&lt;/strong&gt;之间的&lt;strong&gt;包含关系&lt;/strong&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image050_2.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image050" border="0" alt="clip_image050" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image050_thumb.gif" width="542" height="412" /&gt;&lt;/a&gt; &lt;p&gt;Figure 23: 最终用例图完成的效果 &lt;p&gt;25. 到此用例图设计完成，保存并关闭当前设计界面。 &lt;p&gt;你还可以定义哪些用例包含在你系统的开发范围之内。例如，我们案例中的Deliver Meal用例就不需要开发。这就帮助开发人员界定了他们的工作内容。一般用例图中的子系统图标用来代表系统或组成部份。 &lt;p&gt;用例图还可以帮助你的团队讨论功能发布的连续性。如，你可以决定是否在最初的版本中包括付费功能，或者可以不包含。如果系统中不包含付费功能，那么也可以由客户在餐厅直接支付，而不经过系统。这样，你就可能不在你的系统最初版本中包含付费功能。 &lt;p&gt;用例图只是一个总体的描述，而要想得到更详细的用例描述，你可以将你的用例图中的每个用例都导航到一个用例文档中。用详细的用例文档来描述用例。 &lt;p&gt;&lt;a name="_Toc145818312"&gt;&lt;/a&gt;&lt;a name="_Toc137338495"&gt;&lt;/a&gt;&lt;a name="_Toc130671591"&gt;&lt;strong&gt;Task 2 &amp;#8211; &lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;概念类图&lt;/strong&gt;&lt;strong&gt;&lt;/strong&gt; &lt;p&gt;你可以使用UML 类图来开发用于下列用途的概念模型： &lt;p&gt;l 客户可以自己参与到系统的开发过程中 &lt;p&gt;l 描述用户的需求，例如，在描述用例、业务规则以及用户使用习惯方面。 &lt;p&gt;l 系统中的API或用户界面的信息类型变更 &lt;p&gt;l 描述系统或验收测试 &lt;p&gt;出于这样的目的，UML类图的概念就被定义为概念类图。 &lt;p&gt;在一个概念类图中，你只需要展示必要的需求描述，而不需要展示系统内部的设计。概念模型中不应该出现操作或接口。 &lt;p&gt;你可以使用如下步骤定义概念模型： &lt;p&gt;1. 在解决方案浏览器中&lt;strong&gt;右键&lt;/strong&gt;单击&lt;strong&gt;ModelingProjectDinnerNow&lt;/strong&gt;&lt;strong&gt;项目根节点&lt;/strong&gt;，在菜单中选择&lt;strong&gt;添加&lt;/strong&gt;&lt;strong&gt;-&amp;gt;&lt;/strong&gt;&lt;strong&gt;添加新项&lt;/strong&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image052_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image052" border="0" alt="clip_image052" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image052_thumb.jpg" width="644" height="363" /&gt;&lt;/a&gt; &lt;p&gt;Figure 24: 添加新项对话框中选择UML类图 &lt;p&gt;2. 在添加新项对话框中选择&lt;strong&gt;UML&lt;/strong&gt;&lt;strong&gt;类图模板&lt;/strong&gt;，并定义名称为&lt;strong&gt;UMLClassDiagramDinnerNow.classdiagram&lt;/strong&gt;. 效果如上图所示。 &lt;p&gt;3. 点击&lt;strong&gt;添加&lt;/strong&gt;按钮，打开空白&lt;strong&gt;UML&lt;/strong&gt;&lt;strong&gt;类图设计界面&lt;/strong&gt;. &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image054_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image054" border="0" alt="clip_image054" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image054_thumb.jpg" width="635" height="484" /&gt;&lt;/a&gt; &lt;p&gt;Figure 25: 空白UML类图设计界面 &lt;p&gt;4. 在Task 1中我们设计到了两个对象：订单、菜单。根据经验我们知道，订单和菜单分别都要有各自的小项，即订单小项、菜单小项。所以我们首先从工具箱中拖拽&lt;strong&gt;四个类图标&lt;/strong&gt;到设计界面，分别定义为Menu、MenuItem、Order、OrderItem。 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image056_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image056" border="0" alt="clip_image056" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image056_thumb.jpg" width="637" height="484" /&gt;&lt;/a&gt; &lt;p&gt;Figure 26: 建立四个对象 &lt;p&gt;5. 由于菜单和菜单小项、订单与订单小项是1对多的包含关系，所以我们需要在Menu与MenuItem、Order与OrderItem之间建立&amp;#8220;构成&amp;#8221;关系.从工具箱中选中Composition图标，然后点选Menu对象。保持鼠标按下状态，拖拽到MenuItem对象上，生成Menu与MenuItem对象之间&amp;#8220;构成&amp;#8221;关系 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image058_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image058" border="0" alt="clip_image058" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image058_thumb.jpg" width="636" height="484" /&gt;&lt;/a&gt; &lt;p&gt;Figure 27: 拖拽关系 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image060_2.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image060" border="0" alt="clip_image060" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image060_thumb.gif" width="404" height="250" /&gt;&lt;/a&gt; &lt;p&gt;Figure 28: 建立Menu与MenuItem的构成关系 &lt;p&gt;6. 由于Menu与MenuItem是1对多的包含关系，所以，选中设计界面中在上一步骤生成的&lt;strong&gt;Composition&lt;/strong&gt;&lt;strong&gt;图标&lt;/strong&gt;，点选右侧下方的&lt;strong&gt;1&lt;/strong&gt;文本，使其可以编辑。将其更改为&lt;strong&gt;*&lt;/strong&gt;。选中左侧下方的&lt;strong&gt;MenuItem&lt;/strong&gt;文本，将其修改为&lt;strong&gt;Contents&lt;/strong&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image062_2.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image062" border="0" alt="clip_image062" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image062_thumb.gif" width="404" height="250" /&gt;&lt;/a&gt; &lt;p&gt;Figure 29: Menu对象与MenuItem对象之间的Composition关系 &lt;p&gt;7. 重复5、6步骤，设置&lt;strong&gt;Order&lt;/strong&gt;&lt;strong&gt;对象与&lt;/strong&gt;&lt;strong&gt;OrderItem&lt;/strong&gt;&lt;strong&gt;对象&lt;/strong&gt;之间的&lt;strong&gt;Composition&lt;/strong&gt;&lt;strong&gt;关系&lt;/strong&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image064_2.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image064" border="0" alt="clip_image064" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image064_thumb.gif" width="404" height="250" /&gt;&lt;/a&gt; &lt;p&gt;Figure 30: Order对象与OrderItem对象之间的Composition关系 &lt;p&gt;8. Menu对象与Order对象之间存在1对多的联系，同样，MenuItem与OrderItem之间也存在着1对多的联系。所以，重复5、6步，在&lt;strong&gt;Menu&lt;/strong&gt;&lt;strong&gt;与&lt;/strong&gt;&lt;strong&gt;Order&lt;/strong&gt;&lt;strong&gt;之间&lt;/strong&gt;和&lt;strong&gt;MenuItem&lt;/strong&gt;&lt;strong&gt;与&lt;/strong&gt;&lt;strong&gt;OrderItem&lt;/strong&gt;&lt;strong&gt;之间&lt;/strong&gt;分别建立&lt;strong&gt;Association&lt;/strong&gt;&lt;strong&gt;关系&lt;/strong&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image066_2.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image066" border="0" alt="clip_image066" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image066_thumb.gif" width="452" height="255" /&gt;&lt;/a&gt; &lt;p&gt;Figure 31: 建立Association关系 &lt;p&gt;9. 由于MenuItem和OrderItem在数据上有一个明显的不同就是，OrderItem必须包含数量，而MenuItem不需要包含。所以我们要在OrderItem中定义一个数量属性。在&lt;strong&gt;OrderItem&lt;/strong&gt;&lt;strong&gt;对象&lt;/strong&gt;中的&lt;strong&gt;属性&lt;/strong&gt;一栏上点击右键，在弹出的菜单中选择&lt;strong&gt;添加&lt;/strong&gt;&lt;strong&gt;-&amp;gt;&lt;/strong&gt;&lt;strong&gt;属性&lt;/strong&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image068_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image068" border="0" alt="clip_image068" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image068_thumb.jpg" width="635" height="484" /&gt;&lt;/a&gt; &lt;p&gt;Figure 32: 为OrderItem对象添加属性 &lt;p&gt;10. 此时OrderItem对象中出现可编辑的属性，其文本为Attribute1。将Attribute1文本修改为quantity，然后右键选择quantity属性，在属性选项卡中修改属性的数据类型为Integer &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image070_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image070" border="0" alt="clip_image070" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image070_thumb.jpg" width="634" height="484" /&gt;&lt;/a&gt; &lt;p&gt;Figure 33: 定义quantity属性 &lt;p&gt;11. 至此 ，我们完成了概念模型的设计。保存并关闭当前概念类模型设计界面 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image072_2.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image072" border="0" alt="clip_image072" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image072_thumb.gif" width="452" height="270" /&gt;&lt;/a&gt; &lt;p&gt;Figure 34: 初步完成概念模型设计 &lt;p&gt;概念模型提供了一系列你在整个需求建模阶段需要使用的词汇和条件。例如，在Order a Meal用例的详细描述中，可以这样写： &lt;p&gt;客户可以选择菜单来生成订单。通过在菜单中选择一个菜单项，系统在订单中生成订单项。 &lt;p&gt;注意，上面描述中使用的词汇就是我们在模型中使用的类名。现在删除概念模型中类与类之间的不准确的关系。例如，图中明确显示了每个订单只关联一个菜单。 &lt;p&gt;对客户需求的误解可以追溯到对词汇详细解释的误解。例如，大多数餐馆都有约定俗成的菜单和订单，但是订单项与菜单项的不同却区分并不明显。当与客户讨论需求时，暴露这些分歧是很重要的。类图是一个很有用的工具，它可以帮助你明确对象以及对象之间的关系。 &lt;p&gt;业务规则是一个不与特定用例相关的需求，应该是从整个系统层面考虑。 &lt;p&gt;许多业务规则是对概念模型中类之间关系的约束。你可以为概念类图中的相关类，定义一些通用静态业务规则。例如： &lt;p&gt;在概念模型中&lt;strong&gt;右键单击&lt;/strong&gt;&lt;strong&gt;Order&lt;/strong&gt;&lt;strong&gt;对象&lt;/strong&gt;，在菜单中选择&lt;strong&gt;添加&lt;/strong&gt;&lt;strong&gt;-&amp;gt;&lt;/strong&gt;&lt;strong&gt;添加注释&lt;/strong&gt;添加如下约束：&amp;#8220;&lt;strong&gt;在任何订单中，所有的订单项只能来自于同一个选中的菜单&lt;/strong&gt;&amp;#8221; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image074_2.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image074" border="0" alt="clip_image074" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image074_thumb.gif" width="452" height="330" /&gt;&lt;/a&gt; &lt;p&gt;Figure 35: 对概念模型添加约束注释 &lt;p&gt;动态业务规则限制的是事件发生的顺序。例如，你可以使用一个顺序或活动图来展示：一个用户必须登录才能执行你的系统上的操作。 &lt;p&gt;因此，许多动态规则能够取代动态规则更有效更通用的执行约束。例如，你也许能添加一个布尔类型的属性&amp;#8220;Logged In&amp;#8221;到概念类模型中。你还会将登录成功作为登录用例的后置条件，还可以将登录成功作为其它用例的前置条件。这种方法可以让你定义一系列事件的组成顺序。当你需要添加新的用例到用例模型时，动态约束更加灵活。 &lt;p&gt;&lt;a name="_Toc145818313"&gt;&lt;/a&gt;&lt;a name="_Toc137338496"&gt;&lt;/a&gt;&lt;a name="_Toc130671592"&gt;&lt;strong&gt;Task 3 &amp;#8211; &lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;活动图&lt;/strong&gt;&lt;strong&gt;&lt;/strong&gt; &lt;p&gt;你可以使用活动图来显示不同用例之间的工作流程。在需求建模的开始阶段绘制活动图是非常有用的。它可以展示用户执行的主要任务&amp;#8212;&amp;#8212;包含系统内外的交互。 &lt;p&gt;这里以订餐为例：客户订餐时首先需要选择一个菜单，然后在菜单中选择某样菜品。客户可以在某个菜单内部重复多次的选择相同或不同的菜品。当菜品选择完毕后，客户可以将选中的菜品一并结账付款。 &lt;p&gt;1. 在解决方案浏览器中右键单击&lt;strong&gt;ModelingProjectDinnerNow&lt;/strong&gt;&lt;strong&gt;项目根节点，&lt;/strong&gt;在菜单中选择&lt;strong&gt;添加&lt;/strong&gt;&lt;strong&gt;-&amp;gt;&lt;/strong&gt;&lt;strong&gt;添加新项&lt;/strong&gt;. &lt;p&gt;2. 在添加新项对话框中选择UML活动图模板，并定义&lt;strong&gt;名称&lt;/strong&gt;为&lt;strong&gt;UMLActivityDiagramDinnerNow.activitydiagram&lt;/strong&gt;. 效果如上图示. &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image076_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image076" border="0" alt="clip_image076" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image076_thumb.jpg" width="644" height="363" /&gt;&lt;/a&gt; &lt;p&gt;Figure 36: 添加新项-&amp;gt;UML活动图 &lt;p&gt;3. 此时会打开活动图设计界面。点选设计界面的空白处，在&lt;strong&gt;属性&lt;/strong&gt;选项卡中修改活动图的&lt;strong&gt;名称&lt;/strong&gt;属性为&lt;strong&gt;Order Meal&lt;/strong&gt;.此时活动图左上角的标签应该变为act Order Meal &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image078_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image078" border="0" alt="clip_image078" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image078_thumb.jpg" width="636" height="484" /&gt;&lt;/a&gt; &lt;p&gt;Figure 37: 修改活动图的名称属性 &lt;p&gt;4. 任何活动都从一个初始化节点开始的，所以从&lt;strong&gt;工具箱&lt;/strong&gt;中的&lt;strong&gt;UML &lt;/strong&gt;&lt;strong&gt;活动图&lt;/strong&gt;节点下选择&lt;strong&gt;初始节点&lt;/strong&gt;图标，并拖拽到设计界面中. &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image080_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image080" border="0" alt="clip_image080" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image080_thumb.jpg" width="634" height="484" /&gt;&lt;/a&gt; &lt;p&gt;Figure 38: 拖拽初始节点图标 &lt;p&gt;5. 根据案例的描述，订餐活动中应该有选择菜单、选择菜品、付款三项主要活动。这里从&lt;strong&gt;工具箱&lt;/strong&gt;中拖拽三个&lt;strong&gt;活动&lt;/strong&gt;图标到设计界面，分别定义活动内容为&amp;#8220;Choose Menu&amp;#8221;、&amp;#8220;Select Menu Item&amp;#8221;、&amp;#8220;Pay&amp;#8221;. &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image082_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image082" border="0" alt="clip_image082" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image082_thumb.jpg" width="635" height="484" /&gt;&lt;/a&gt; &lt;p&gt;Figure 39: 定义活动 &lt;p&gt;6. 活动图定义的结尾，应该是活动的结束节点。从工具箱中拖拽&lt;strong&gt;活动结束&lt;/strong&gt;节点到设计界面 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image084_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image084" border="0" alt="clip_image084" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image084_thumb.jpg" width="636" height="484" /&gt;&lt;/a&gt; &lt;p&gt;Figure 40: 定义活动结束 &lt;p&gt;7. 在工具箱中选中连接器图标，在设计界面点选初始图标并保持鼠标按下，拖拽到右侧Choose Menu活动图标上。 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image086_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image086" border="0" alt="clip_image086" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image086_thumb.jpg" width="636" height="484" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;41&lt;/strong&gt;&lt;strong&gt;: &lt;/strong&gt;&lt;strong&gt;拖拽活动之间的连接器&lt;/strong&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image088_2.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image088" border="0" alt="clip_image088" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image088_thumb.gif" width="320" height="200" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;42&lt;/strong&gt;&lt;strong&gt;: &lt;/strong&gt;&lt;strong&gt;定义第一个连接器后的效果&lt;/strong&gt; &lt;p&gt;8. 根据任务中需求的描述，客户选择菜单后，可以再浏览选择菜品，即菜单项。而且客户可以反复浏览菜单和菜品。这样在选择菜品和选择菜单两个活动之间就形成了循环的关系。所以我们需要在&lt;strong&gt;Choose Menu&lt;/strong&gt;&lt;strong&gt;活动&lt;/strong&gt;的下方放置一个&lt;strong&gt;合并节点&lt;/strong&gt;，然后在&lt;strong&gt;Select Menu Item&lt;/strong&gt;&lt;strong&gt;活动&lt;/strong&gt;的下方放置一个&lt;strong&gt;分支节点&lt;/strong&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image090_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image090" border="0" alt="clip_image090" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image090_thumb.jpg" width="635" height="484" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;43&lt;/strong&gt;&lt;strong&gt;: &lt;/strong&gt;&lt;strong&gt;添加合并节点和分支节点&lt;/strong&gt; &lt;p&gt;9. 从&lt;strong&gt;Choose Menu&lt;/strong&gt;&lt;strong&gt;活动&lt;/strong&gt;开始，以此向下添加连接器，直到&lt;strong&gt;Pay&lt;/strong&gt;&lt;strong&gt;活动&lt;/strong&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image092_2.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image092" border="0" alt="clip_image092" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image092_thumb.gif" width="332" height="296" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;44&lt;/strong&gt;&lt;strong&gt;: &lt;/strong&gt;&lt;strong&gt;添加正常流程连接器&lt;/strong&gt; &lt;p&gt;10. 为了说明客户可以在菜单中反复选择菜品，我们需要从分支节点到合并节点添加一个连接器，用来表示循环，并对循环活动添加注释。在分支节点的&lt;strong&gt;指向下方&lt;/strong&gt;活动的&lt;strong&gt;连接器&lt;/strong&gt;的&lt;strong&gt;Guard&lt;/strong&gt;属性中添加如下提示：&lt;strong&gt;Customer has finished choosing&lt;/strong&gt;.在&lt;strong&gt;返回上方的连接器&lt;/strong&gt;的&lt;strong&gt;Guard&lt;/strong&gt;属性中添加如下提示：&lt;strong&gt;Customer wants to choose more.&lt;/strong&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image094_2.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image094" border="0" alt="clip_image094" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image094_thumb.gif" width="381" height="308" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;45&lt;/strong&gt;&lt;strong&gt;: &lt;/strong&gt;&lt;strong&gt;添加循环活动&lt;/strong&gt; &lt;p&gt;11. 当客户选择完所须的菜品后，任务就完结。这里我们从&lt;strong&gt;Pay&lt;/strong&gt;&lt;strong&gt;活动&lt;/strong&gt;到&lt;strong&gt;活动结束节点&lt;/strong&gt;添加&lt;strong&gt;连接器&lt;/strong&gt;。 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image096_2.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image096" border="0" alt="clip_image096" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image096_thumb.gif" width="381" height="308" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;46&lt;/strong&gt;&lt;strong&gt;: &lt;/strong&gt;&lt;strong&gt;订餐活动终结&lt;/strong&gt; &lt;p&gt;12. 至此，订餐功能的活动图我们就构建完成。 &lt;p&gt;你可以利用用例图和活动图来展示针对相同信息的不同观点。用例图可以有效地显示在大的功能中的嵌套的小的活动，但它不包含活动之间的流程。 &lt;p&gt;例如，同样是描述订餐功能，使用用例图描述如下 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image098_2.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image098" border="0" alt="clip_image098" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image098_thumb.gif" width="465" height="236" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;47&lt;/strong&gt;&lt;strong&gt;: &lt;/strong&gt;&lt;strong&gt;用例图中的订餐活动&lt;/strong&gt;&lt;strong&gt;&lt;/strong&gt; &lt;p&gt;&lt;strong&gt;&lt;br /&gt;&lt;/strong&gt;&lt;p&gt;&lt;a name="_Toc130671593"&gt;&lt;/a&gt;&lt;a name="_Toc145818314"&gt;&lt;/a&gt;&lt;a name="_Toc137338497"&gt;&lt;strong&gt;Task 4 &amp;#8211; &lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;顺序图&lt;/strong&gt; &lt;p&gt;你可以使用顺序图来显示你的系统与外部活动者之间，或者系统与系统之间的信息交互。顺序图提供了一种用例，它可以非常清晰地展示系统模块之间的互操作步骤。顺序图在描述多个用例之间的交互时非常有效，而且为你的系统提供一些API。 &lt;p&gt;1. 在解决方案浏览器中右键单击&lt;strong&gt;ModelingProjectDinnerNow&lt;/strong&gt;&lt;strong&gt;项目根节点&lt;/strong&gt;，在菜单中选择&lt;strong&gt;添加&lt;/strong&gt;&lt;strong&gt;-&amp;gt;&lt;/strong&gt;&lt;strong&gt;添加新项&lt;/strong&gt;. &lt;p&gt;2. 在添加新项对话框中选择&lt;strong&gt;UML&lt;/strong&gt;&lt;strong&gt;顺序图&lt;/strong&gt;模板，并定义名称为&lt;strong&gt;UMLSequenceDiagramDinnerNow.sequencediagram&lt;/strong&gt;. &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image100_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image100" border="0" alt="clip_image100" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image100_thumb.jpg" width="644" height="362" /&gt;&lt;/a&gt; &lt;p&gt;Figure 48 新建UML 顺序图界面 &lt;p&gt;3. Dinner Now系统中的功能主要是四个对象之间的交互，他们是客户、Dinner Now 系统、餐厅、银行。打开&lt;strong&gt;UML&lt;/strong&gt;&lt;strong&gt;模型浏览器&lt;/strong&gt;，可以看到已经包含&lt;strong&gt;客户活动者、&lt;/strong&gt;&lt;strong&gt;Dinner Now&lt;/strong&gt;&lt;strong&gt;子系统&lt;/strong&gt;以及&lt;strong&gt;餐厅活动者&lt;/strong&gt;，所以可以直接拖拽这三个用例到顺序图设计界面 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image102_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image102" border="0" alt="clip_image102" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image102_thumb.jpg" width="644" height="419" /&gt;&lt;/a&gt; &lt;p&gt;Figure 49 添加客户、DinnerNow子系统、餐厅三个生命线 &lt;p&gt;4. 由于我们之前设计的用例中暂时不包含银行用例，所以我们需要从&lt;strong&gt;工具箱&lt;/strong&gt;中拖拽一个&lt;strong&gt;生命线图标&lt;/strong&gt;到设计界面，并在空生命线的&lt;strong&gt;属性面板&lt;/strong&gt;中修改&lt;strong&gt;名称&lt;/strong&gt;属性为&lt;strong&gt;Bank&lt;/strong&gt;，修改&lt;strong&gt;Type&lt;/strong&gt;属性为&lt;strong&gt;None&lt;/strong&gt;。 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image104_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image104" border="0" alt="clip_image104" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image104_thumb.jpg" width="644" height="418" /&gt;&lt;/a&gt; &lt;p&gt;Figure 50 从工具箱中拖拽生命线图标到设计界面 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image106_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image106" border="0" alt="clip_image106" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image106_thumb.jpg" width="644" height="419" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;51&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;修改&lt;/strong&gt;&lt;strong&gt;Bank&lt;/strong&gt;&lt;strong&gt;生命线属性&lt;/strong&gt; &lt;p&gt;5. 根据需求我们知道客户需要在菜单中不断的浏览，不断的选择，系统也是不断的将客户选中的菜品添加到订单中。所以我们首先在Dinner Now System生命线上添加一个异步的调用。首先在&lt;strong&gt;工具箱&lt;/strong&gt;中选中&lt;strong&gt;异步图标&lt;/strong&gt;，然后在设计界面上选中客户生命线，保持鼠标按下，拖拽到Dinner Now System生命线上 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image108_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image108" border="0" alt="clip_image108" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image108_thumb.jpg" width="644" height="418" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;52&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;拖拽异步图标从&lt;/strong&gt;&lt;strong&gt;Customer&lt;/strong&gt;&lt;strong&gt;生命线到&lt;/strong&gt;&lt;strong&gt;Dinner Now System&lt;/strong&gt;&lt;strong&gt;生命线&lt;/strong&gt;&lt;strong&gt;&lt;/strong&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image110_2.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image110" border="0" alt="clip_image110" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image110_thumb.gif" width="712" height="201" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;53&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;建立异步调用后的效果&lt;/strong&gt;&lt;strong&gt;&lt;/strong&gt; &lt;p&gt;6. 单击&lt;strong&gt;Message1&lt;/strong&gt;&lt;strong&gt;文本&lt;/strong&gt;，使其可编辑，将&lt;strong&gt;Message1&lt;/strong&gt;&lt;strong&gt;文本&lt;/strong&gt;修改为&lt;strong&gt; Add Order Item&lt;/strong&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image112_2.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image112" border="0" alt="clip_image112" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image112_thumb.gif" width="712" height="215" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;54&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;修改调用的名称&lt;/strong&gt; &lt;p&gt;7. 因为客户挑选菜品的过程是一个循环往复的过程，所以需要标注循环。右键单击&lt;strong&gt;Add Order Item&lt;/strong&gt;&lt;strong&gt;调用&lt;/strong&gt;，在弹出的菜单中选择&lt;strong&gt;包围&lt;/strong&gt;-&amp;gt;&lt;strong&gt;循环组件片段&lt;/strong&gt;。 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image114_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image114" border="0" alt="clip_image114" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image114_thumb.jpg" width="644" height="421" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;55&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;添加循环组件片段菜单&lt;/strong&gt;&lt;strong&gt;&lt;/strong&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image116_2.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image116" border="0" alt="clip_image116" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image116_thumb.gif" width="712" height="277" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;56&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;添加循环片段的效果&lt;/strong&gt; &lt;p&gt;8. 在循环片段左上角的&lt;strong&gt;Loop&lt;/strong&gt;&lt;strong&gt;文本下方&lt;/strong&gt;单击空白区域，出现可编辑文本框，定义文本内容为&lt;strong&gt;until complete&lt;/strong&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image118_2.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image118" border="0" alt="clip_image118" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image118_thumb.gif" width="712" height="306" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;57&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;编辑循环标签&lt;/strong&gt; &lt;p&gt;9. 当客户选择完菜品后，需要最终确认并提交订单。重复&lt;strong&gt;步骤&lt;/strong&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;strong&gt;、&lt;/strong&gt;&lt;strong&gt;6&lt;/strong&gt;，&lt;strong&gt;从客户生命线到&lt;/strong&gt;&lt;strong&gt;Dinner Now &lt;/strong&gt;&lt;strong&gt;系统生命线&lt;/strong&gt;建立&lt;strong&gt;异步调用&lt;/strong&gt;，并修改调用&lt;strong&gt;名称&lt;/strong&gt;为&lt;strong&gt;Confirm Order&lt;/strong&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image120_2.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image120" border="0" alt="clip_image120" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image120_thumb.gif" width="712" height="372" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;58&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;添加&lt;/strong&gt;&lt;strong&gt;Confirm Order&lt;/strong&gt;&lt;strong&gt;异步调用&lt;/strong&gt; &lt;p&gt;10. 客户确认订单后，系统会将订单发送给餐厅等待处理，此时，餐厅需要通过系统反馈给客户一个订单发送是否成功的确认。我们需要从工具箱中拖拽一个&lt;strong&gt;同步调用&lt;/strong&gt;。在设计界面中，从&lt;strong&gt;Dinner Now&lt;/strong&gt;&lt;strong&gt;系统生命线&lt;/strong&gt;上生成的&lt;strong&gt;矩形图标&lt;/strong&gt;，拖拽到右侧的&lt;strong&gt;餐厅生命线&lt;/strong&gt;上 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image122_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image122" border="0" alt="clip_image122" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image122_thumb.jpg" width="644" height="421" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;59&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;在&lt;/strong&gt;&lt;strong&gt;Confirm Order&lt;/strong&gt;&lt;strong&gt;调用与餐厅生命线之间建立同步调用&lt;/strong&gt;&lt;strong&gt;&lt;/strong&gt; &lt;p&gt;11. 将指向右侧的调用文本&lt;strong&gt;Message1&lt;/strong&gt;，修改为&lt;strong&gt;Send Order&lt;/strong&gt;。将下方指向左侧的回调文本&lt;strong&gt;return&lt;/strong&gt;，修改为&lt;strong&gt;OK&lt;/strong&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image124_2.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image124" border="0" alt="clip_image124" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image124_thumb.gif" width="712" height="404" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;60&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;修改回调方法名称&lt;/strong&gt; &lt;p&gt;12. 系统收到餐厅的确认后，客户就可以付款了。系统会请求客户提交付款的详细信息。付款成功的信息会直接返回给客户。重复&lt;strong&gt;步骤&lt;/strong&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;strong&gt;、&lt;/strong&gt;&lt;strong&gt;11&lt;/strong&gt;，从&lt;strong&gt;客户生命线&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;到&lt;/strong&gt;&lt;strong&gt;Dinner Now &lt;/strong&gt;&lt;strong&gt;系统生命线&lt;/strong&gt;之间建立同步调用，将&lt;strong&gt;指向右侧&lt;/strong&gt;的调用名称修改为&lt;strong&gt;Payment detail&lt;/strong&gt;，将&lt;strong&gt;指向左侧&lt;/strong&gt;的消息回调名称修改为&lt;strong&gt;confirmed&lt;/strong&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image126_2.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image126" border="0" alt="clip_image126" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image126_thumb.gif" width="712" height="507" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;61&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;添加付款功能调用和确认&lt;/strong&gt; &lt;p&gt;13. 客户提交付款详细信息后，系统会直接与银行之间执行付款操作流程。而系统与银行之间的付款流程完成后，银行也会返回给Dinner Now 系统一个确认信息。所以重复&lt;strong&gt;步骤&lt;/strong&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;strong&gt;、&lt;/strong&gt;&lt;strong&gt;11&lt;/strong&gt;，从&lt;strong&gt;Dinner Now&lt;/strong&gt;&lt;strong&gt;系统上的&lt;/strong&gt;&lt;strong&gt;Payment detail&lt;/strong&gt;&lt;strong&gt;调用矩形图标，到银行生命线&lt;/strong&gt;建立&lt;strong&gt;同步调用&lt;/strong&gt;。将&lt;strong&gt;指向右侧&lt;/strong&gt;的&lt;strong&gt;调用名称&lt;/strong&gt;修改为&lt;strong&gt;Process Payment&lt;/strong&gt;，将&lt;strong&gt;指向左侧&lt;/strong&gt;的&lt;strong&gt;回发调用名称&lt;/strong&gt;修改为&lt;strong&gt;OK&lt;/strong&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image128_2.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image128" border="0" alt="clip_image128" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image128_thumb.gif" width="712" height="552" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;62&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;添加执行付款调用和确认&lt;/strong&gt; &lt;p&gt;14. Dinner Now系统收到银行的付款确认后，会将确认信息和最终订单发送给餐厅。而餐厅收到订单这个调用应该先于系统给客户的确认。所以我们需要在&lt;strong&gt;Dinner Now&lt;/strong&gt;&lt;strong&gt;系统生命线&lt;/strong&gt;中的&lt;strong&gt;Payment detail&lt;/strong&gt;&lt;strong&gt;调用矩形图标&lt;/strong&gt;上，在银行反馈给系统付款确认信息之后，建立一个&lt;strong&gt;到餐厅生命线&lt;/strong&gt;的&lt;strong&gt;异步调用&lt;/strong&gt;。并将异步调用的名字改为&lt;strong&gt;Confirm Order&lt;/strong&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image130_2.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image130" border="0" alt="clip_image130" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image130_thumb.gif" width="712" height="786" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;63&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;添加确认订单调用&lt;/strong&gt; &lt;p&gt;15. 当Dinner Now系统向客户返回了订餐成功的最终确认后，餐厅就可以为客户送餐了。而送餐的动作不需要经过Dinner Now系统，所以，在Payment detail 调用结束后，直接从餐厅生命线上的&lt;strong&gt;Confirm Order&lt;/strong&gt;&lt;strong&gt;调用&lt;/strong&gt;上，向&lt;strong&gt;客户生命线&lt;/strong&gt;添加一个&lt;strong&gt;返回&lt;/strong&gt;的&lt;strong&gt;异步调用&lt;/strong&gt;&lt;strong&gt;Deliver Food&lt;/strong&gt;。且confirmed回发，和Deliver Food调用应该是并行的 。 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image132_2.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image132" border="0" alt="clip_image132" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image132_thumb.gif" width="712" height="786" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;64&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;添加送餐调用&lt;/strong&gt; &lt;p&gt;16. 到此我们的顺序图就绘制完成，保存并关闭设计界面。&lt;a name="_Toc130671599"&gt;&lt;/a&gt;&lt;a name="_Toc137338503"&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;总结&lt;/strong&gt; &lt;p&gt;创建模型往往可以大幅减少需求分析中与客户的需求相矛盾或含糊不清的地方。不同的利益相关者往往对系统运行的业务流程有不同的理解。因此你的第一个任务就是解决这些你和客户之间的分歧。 &lt;p&gt;你会发现 ， &lt;p&gt;&lt;a name="_Toc145818326"&gt;&lt;/a&gt;&lt;a name="_Toc137338505"&gt;&lt;/a&gt;&lt;a name="_Toc130671600"&gt;Exercise 2 &amp;#8211; &lt;/a&gt;软件设计建模 &lt;p&gt;图形建模可以帮助你了解、澄清你的系统必须实现的客户需求，并使你的代码能够与客户进行良好的意见沟通。例如，你可以使用统一建模语言（UML）的用例图、活动图、类图以及顺序图来描述用户需求。你可以使用UML的组件图、类图、活动图、顺序图来描绘系统的功能。 &lt;p&gt;&lt;a name="_Toc145818327"&gt;&lt;/a&gt;&lt;a name="_Toc137338506"&gt;&lt;/a&gt;&lt;a name="_Toc130671601"&gt;&lt;strong&gt;Task 1 &lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;&amp;#8211; &lt;/strong&gt;&lt;strong&gt;活动图&lt;/strong&gt; &lt;p&gt;这个案例中我们需要参考在需求分析建模中构建的活动图&lt;strong&gt;UMLActivityDiagramDinnerNow.activitydiagram&lt;/strong&gt;&lt;strong&gt;。&lt;/strong&gt;但是在软件设计阶段和需求分析阶段的活动图略有不同，例如&lt;strong&gt;UMLActivityDiagramDinnerNow.activitydiagram&lt;/strong&gt;中的Pay活动其实并不经过Dinner Now系统，所以我们需要对需求分析建模中的&lt;strong&gt;Pay&lt;/strong&gt;&lt;strong&gt;活动&lt;/strong&gt;进行修改。将其换成一个&lt;strong&gt;行为调用活动&lt;/strong&gt;，并命名为&lt;strong&gt;Confirm Order&lt;/strong&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image134_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image134" border="0" alt="clip_image134" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image134_thumb.jpg" width="589" height="484" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;65&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;修改调用活动&lt;/strong&gt;&lt;strong&gt;&lt;/strong&gt; &lt;p&gt;通过需求分析建模中用例图和活动图的描述，我们得知，创建订单时，配货与付款是并发的两件事。所以我们需要在软件设计建模中的活动途中对其加以细化。 &lt;p&gt;1. 在解决方案浏览器中右键单击&lt;strong&gt;ModelingProjectDinnerNow&lt;/strong&gt;项目根节点，在菜单中选择&lt;strong&gt;添加&lt;/strong&gt;&lt;strong&gt;-&amp;gt;&lt;/strong&gt;&lt;strong&gt;添加新项&lt;/strong&gt; &lt;p&gt;2. 在添加新项对话框中选择&lt;strong&gt;UML&lt;/strong&gt;&lt;strong&gt;活动图模板&lt;/strong&gt;，并定义名称为&lt;strong&gt;UMLActivityDiagramCreateOrder.activitydiagram.&lt;/strong&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image136_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image136" border="0" alt="clip_image136" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image136_thumb.jpg" width="644" height="364" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;66&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;新建创建订单活动图&lt;/strong&gt; &lt;p&gt;3. 从工具箱中拖拽活动的&lt;strong&gt;起点图标&lt;/strong&gt;到设计界面，命名为&lt;strong&gt;InitialCreateOrder&lt;/strong&gt;，然后再拖拽第一个&lt;strong&gt;活动&lt;/strong&gt;到设计界面，命名为&lt;strong&gt;Create Order&lt;/strong&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image138_2.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image138" border="0" alt="clip_image138" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image138_thumb.gif" width="128" height="104" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;67&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;创建订单活动图的起始阶段&lt;/strong&gt; &lt;p&gt;4. 从工具箱中拖拽一个&lt;strong&gt;并行分支节点&lt;/strong&gt;到设计界面并命名为&lt;strong&gt;ForkCreateOrder&lt;/strong&gt;，以此来表示任何进入这里的处理流程都会被分解为若干个并行的处理进程。然后添加从&lt;strong&gt;Create Order&lt;/strong&gt;&lt;strong&gt;活动&lt;/strong&gt;到&lt;strong&gt;并行分支节点&lt;/strong&gt;的&lt;strong&gt;连接器&lt;/strong&gt;。 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image140_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image140" border="0" alt="clip_image140" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image140_thumb.jpg" width="589" height="484" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;68&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;添加并行分支节点&lt;/strong&gt; &lt;p&gt;5. 在并行分支节点的右侧，首先建立&lt;strong&gt;配货活动&lt;/strong&gt;的进程。从工具箱中拖拽一个&lt;strong&gt;活动&lt;/strong&gt;到设计界面中，放置在并行分支节点的下方偏右侧区域，命名为&lt;strong&gt;Dispatch goods&lt;/strong&gt;&lt;strong&gt;。&lt;/strong&gt;建立分支节点指向Dispatch goods活动的连接器。 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image142_2.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image142" border="0" alt="clip_image142" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image142_thumb.gif" width="200" height="260" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;69&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;添加配货活动&lt;/strong&gt; &lt;p&gt;6. 在并行分支节点的左侧，建立与配货进程并行的付款进程。通过需求分析建模中顺序图的描述，我们 了解到，付款行为并不真正由系统完成，而是客户首先出发系统的付款事件，然后系统会直接将事件请求发送到银行，并同样利用事件机制监听银行端发回的付款确认。由此我们需要两个新的活动。一个是用来发送请求的事件活动，一个是用来接收回发的事件活动。因此，从工具箱中首先拖拽一个&lt;strong&gt;发送请求活动&lt;/strong&gt;到设计界面中并行分支活动的左侧，命名为&lt;strong&gt;Send invoice&lt;/strong&gt;。并建立从并行分支活动到Send invoice活动的连接器。 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image144_2.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image144" border="0" alt="clip_image144" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image144_thumb.gif" width="272" height="260" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;70&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;添加与配货活动并行的发送请求活动&lt;/strong&gt; &lt;p&gt;7. 在发送请求Send invoice活动的下方，再从工具箱中拖拽一个&lt;strong&gt;接收事件活动&lt;/strong&gt;，命名为&lt;strong&gt;Receive payment&lt;/strong&gt;。建立从Send invoice活动到Receive payment活动的连接器。 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image146_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image146" border="0" alt="clip_image146" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image146_thumb.jpg" width="588" height="484" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;71&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;添加接收付款确认事件&lt;/strong&gt; &lt;p&gt;8. 两个并行处理进程定义好之后，需要最终汇集到主要处理流程上继续执行，所以需要从工具箱中拖拽一个并行汇总图标到设计界面的下方，命名为&lt;strong&gt;JoinCreateOrder&lt;/strong&gt;。分别从Receive payment活动和Dispatch goods活动向并行汇总图标建立连接器 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image148_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image148" border="0" alt="clip_image148" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image148_thumb.jpg" width="594" height="484" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;72&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;添加并行汇总节点&lt;/strong&gt; &lt;p&gt;9. 最后是关闭订单，也代表着订单处理成功。所以需要从工具箱中拖拽一个活动到设计界面的下方，命名为&lt;strong&gt;Close Order&lt;/strong&gt;。在Close Order活动的下方再放置一个活动终结图标。分别从上到下建立连接线。 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image150_2.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image150" border="0" alt="clip_image150" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image150_thumb.gif" width="272" height="452" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;73&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;完成创建订单活动图&lt;/strong&gt; &lt;p&gt;到此创建订单的活动就完成了。保存并关闭当前设计界面。 &lt;p&gt;&lt;strong&gt;Task &lt;/strong&gt;&lt;strong&gt;2 &lt;/strong&gt;&lt;strong&gt;&amp;#8211; &lt;/strong&gt;&lt;strong&gt;数据流图&lt;/strong&gt; &lt;p&gt;你还可以使用数据流图来描述数据从一个动作流向另一个动作。这个任务中，我们模拟订单生成过程中数据的流向及其对存储介质以及活动的影响。在生成订单过程中，订单小项和客户地址分别会有不同的数据流向，也会影响不同的活动，所以我们以订单中的这两部分数据作为任务的开始。 &lt;p&gt;1. 在解决方案浏览器中右键单击&lt;strong&gt;ModelingProjectDinnerNow&lt;/strong&gt;项目根节点，在菜单中选择&lt;strong&gt;添加&lt;/strong&gt;&lt;strong&gt;-&amp;gt;&lt;/strong&gt;&lt;strong&gt;添加新项&lt;/strong&gt; &lt;p&gt;2. 在添加新项对话框中选择&lt;strong&gt;UML&lt;/strong&gt;&lt;strong&gt;活动图模板&lt;/strong&gt;，并定义名称为&lt;strong&gt;UMLActivityDiagramOrderDataflows.activitydiagram.&lt;/strong&gt; &lt;p&gt;3. 从工具箱中拖拽两个&lt;strong&gt;活动参数&lt;/strong&gt;图标到设计界面，水平并排放置，通过单击图标上的文本，使其可编辑。分别命名为&lt;strong&gt;Item list&lt;/strong&gt;和&lt;strong&gt;Customer Address&lt;/strong&gt;。 &lt;p&gt;4. 订单生成的过程首先会按照当前订单中的商品列表，在商品库存中找到相应的商品。所以需要从工具箱中拖拽一个&lt;strong&gt;活动&lt;/strong&gt;到设计界面中，&lt;strong&gt;Item list&lt;/strong&gt;&lt;strong&gt;的下方&lt;/strong&gt;。命名为&lt;strong&gt;Find goods in warehouse&lt;/strong&gt;。 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image152_2.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image152" border="0" alt="clip_image152" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image152_thumb.gif" width="356" height="140" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;74&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;添加查找库存货物活动&lt;/strong&gt; &lt;p&gt;5. 由于Item list是以参数的形式进入Find goods in warehouse活动的。所以我们需要给Find goods in warehouse活动定义输入接口。&lt;strong&gt;右键&lt;/strong&gt;单击&lt;strong&gt;Find goods in warehouse&lt;/strong&gt;&lt;strong&gt;活动&lt;/strong&gt;，在右键菜单中选择&lt;strong&gt;添加&lt;/strong&gt;&lt;strong&gt;-&amp;gt;Input pin&lt;/strong&gt;。通过&lt;strong&gt;单击&lt;/strong&gt;接口上的文本&lt;strong&gt;Input1&lt;/strong&gt;，使其可编辑，并将文本定义为&lt;strong&gt;Item list&lt;/strong&gt;。然后从&lt;strong&gt;Item list&lt;/strong&gt;&lt;strong&gt;参数&lt;/strong&gt;图标，到新建的&lt;strong&gt;输入接口&lt;/strong&gt;添加&lt;strong&gt;连接器&lt;/strong&gt;。 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image154_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image154" border="0" alt="clip_image154" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image154_thumb.jpg" width="587" height="484" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;75&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;添加输入参数接口的右键菜单&lt;/strong&gt;&lt;strong&gt;&lt;/strong&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image156_2.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image156" border="0" alt="clip_image156" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image156_thumb.gif" width="356" height="140" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;76&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;为&lt;/strong&gt;&lt;strong&gt;Find goods in warehouse&lt;/strong&gt;&lt;strong&gt;活动添加输入参数&lt;/strong&gt;&lt;strong&gt;Item list&lt;/strong&gt; &lt;p&gt;6. 客户的地址需要生成为派送货物时的地址标签。所以Customer Address应该是Print address label活动的输入参数。所以，重复步骤4、5。添加Print address label活动，并为其添加输入参数接口Customer Address。 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image158_2.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image158" border="0" alt="clip_image158" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image158_thumb.gif" width="356" height="140" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;77&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;添加&lt;/strong&gt;&lt;strong&gt;Print address label&lt;/strong&gt;&lt;strong&gt;活动，并定义它的&lt;/strong&gt;&lt;strong&gt;Customer Address&lt;/strong&gt;&lt;strong&gt;输入参数&lt;/strong&gt; &lt;p&gt;7. 当系统在物品库存中找到了客户选择的物品后，会完成两个工作。一是把每个购买物品的数量从库存数量中减去。二是生成订单号，以便唯一记录或查阅订单。要完成第一个任务，我们需要定义一个对象，来保存需要修改的物品数量记录。所以，从工具箱中拖拽一个&lt;strong&gt;对象节点&lt;/strong&gt;图标到设计界面中Find goods in warehouse活动的下方，单击文本&lt;strong&gt;Object1&lt;/strong&gt;将其内容修改为&lt;strong&gt;Stock Update Record&lt;/strong&gt;。由于不存在参数的关系，所以只需直接从&lt;strong&gt;Find goods in warehouse&lt;/strong&gt;&lt;strong&gt;活动&lt;/strong&gt;到&lt;strong&gt;Stock Update Record&lt;/strong&gt;&lt;strong&gt;对象&lt;/strong&gt;建立&lt;strong&gt;连接器&lt;/strong&gt;。 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image160_2.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image160" border="0" alt="clip_image160" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image160_thumb.gif" width="356" height="224" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;78&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;添加&lt;/strong&gt;&lt;strong&gt;Stock Update Record&lt;/strong&gt;&lt;strong&gt;对象&lt;/strong&gt; &lt;p&gt;8. 系统会使用专门的活动来将Stock Update Record对象中保留的数据，更新到实际的数据库中。从工具箱中拖拽一个&lt;strong&gt;活动&lt;/strong&gt;到设计界面，放置在Stock Update Record对象的下方，并将其命名为&lt;strong&gt;Update stock database&lt;/strong&gt;。并建立从Stock Update Record对象到Update stock database活动的连接器。（这里不使用参数的原因是由于Stock Update Record是对象，可以拥有并调用自己专属的方法，而不是将自己作为参数传递给别人的活动） &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image162_2.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image162" border="0" alt="clip_image162" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image162_thumb.gif" width="356" height="296" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;79&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;添加&lt;/strong&gt;&lt;strong&gt;Update stock database&lt;/strong&gt;&lt;strong&gt;活动&lt;/strong&gt; &lt;p&gt;9. 步骤7中提到的第二件事就是生成订单号，而订单号会与打印的地址标签一同成为配送物品的重要依据。所以从工具箱中拖拽一个 新的&lt;strong&gt;活动&lt;/strong&gt;，放置在Find goods in warehouse活动和Print address label活动的下方。将其命名为pack goods。 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image164_2.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image164" border="0" alt="clip_image164" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image164_thumb.gif" width="356" height="296" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;80&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;添加&lt;/strong&gt;&lt;strong&gt;Pack goods&lt;/strong&gt;&lt;strong&gt;活动&lt;/strong&gt; &lt;p&gt;10. Pack goods活动需要的两个输入参数：订单号和地址标签，分别来自于Find goods in warehouse活动和Print address label活动。所以可以参照步骤4、5分别为&lt;strong&gt;Find goods in warehouse&lt;/strong&gt;&lt;strong&gt;活动&lt;/strong&gt;和&lt;strong&gt;Print address label&lt;/strong&gt;&lt;strong&gt;活动&lt;/strong&gt;添加&lt;strong&gt;输出参数接口&lt;/strong&gt;，分别命名为&lt;strong&gt;Order Id&lt;/strong&gt;和&lt;strong&gt;Address label&lt;/strong&gt;。与之对应的，要在&lt;strong&gt;Pack goods&lt;/strong&gt;&lt;strong&gt;活动&lt;/strong&gt;上建立&lt;strong&gt;两个输入参数接口&lt;/strong&gt;用来接收Order Id和Address label。最后，分别从&lt;strong&gt;Order Id&lt;/strong&gt;&lt;strong&gt;输出参数接口&lt;/strong&gt;和&lt;strong&gt;Address label&lt;/strong&gt;&lt;strong&gt;接口&lt;/strong&gt;，到&lt;strong&gt;Pack goods&lt;/strong&gt;&lt;strong&gt;活动&lt;/strong&gt;上各自给定的&lt;strong&gt;输入参数接口&lt;/strong&gt;，建立&lt;strong&gt;连接器&lt;/strong&gt;。 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image166_2.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image166" border="0" alt="clip_image166" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image166_thumb.gif" width="432" height="296" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;81&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;为&lt;/strong&gt;&lt;strong&gt;Pack goods&lt;/strong&gt;&lt;strong&gt;活动提供参数来源&lt;/strong&gt; &lt;p&gt;11. 当Pack goods活动完成后，就可以发货给客户。此时在Pack goods活动下方简单添加一个&lt;strong&gt;活动&lt;/strong&gt;，命名为&lt;strong&gt;Ship goods to customer&lt;/strong&gt;。 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image168_2.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image168" border="0" alt="clip_image168" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image168_thumb.gif" width="444" height="296" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;82&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;添加送货活动&lt;/strong&gt; &lt;p&gt;12. 到此，关于生成订单与送货的数据流程图就完成了，保存并关闭当前设计界面。 &lt;p&gt;&lt;strong&gt;Task &lt;/strong&gt;&lt;strong&gt;3 &lt;/strong&gt;&lt;strong&gt;&amp;#8211; &lt;/strong&gt;&lt;strong&gt;组件图&lt;/strong&gt; &lt;p&gt;在Visual Studio 旗舰版中，组件图展示的是软件系统设计的组成部分。组件图可以帮助你可视化的定义高层次的系统结构以及服务行为的接口与调用。这个任务中我们模拟客户使用Web浏览器与我们的Dinner Now系统完成订餐过程的组件间关系。 &lt;p&gt;1. 在解决方案浏览器中右键单击&lt;strong&gt;ModelingProjectDinnerNow&lt;/strong&gt;项目根节点，在菜单中选择&lt;strong&gt;添加&lt;/strong&gt;&lt;strong&gt;-&amp;gt;&lt;/strong&gt;&lt;strong&gt;添加新项&lt;/strong&gt; &lt;p&gt;2. 在添加新项对话框中选择&lt;strong&gt;UML&lt;/strong&gt;&lt;strong&gt;组件图模板&lt;/strong&gt;，并定义名称为&lt;strong&gt;UMLComponentDiagramDinnerNow.componentdiagram.&lt;/strong&gt;点击添加，进入组件图设计界面。 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image170_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image170" border="0" alt="clip_image170" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image170_thumb.jpg" width="644" height="362" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;83&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;新建组件图&lt;/strong&gt; &lt;p&gt;3. 从工具箱中拖拽一个&lt;strong&gt;组件图标&lt;/strong&gt;到设计界面，单击文本&lt;strong&gt;Component1&lt;/strong&gt;，将其修改为&lt;strong&gt;Web Browser&lt;/strong&gt;。单击Web Browser组件左上角的&lt;strong&gt;收放箭头&lt;/strong&gt;，将其收缩。 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image172_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image172" border="0" alt="clip_image172" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image172_thumb.jpg" width="586" height="484" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;84&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;添加&lt;/strong&gt;&lt;strong&gt;Web Browser&lt;/strong&gt;&lt;strong&gt;组件&lt;/strong&gt; &lt;p&gt;4. 从工具箱中拖拽另一个&lt;strong&gt;组件图标&lt;/strong&gt;到设计界面，单击&lt;strong&gt;Component1&lt;/strong&gt;文本，将其修改为&lt;strong&gt;DinnerNow Web Service&lt;/strong&gt;。调整其大小如下图所示 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image174_2.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image174" border="0" alt="clip_image174" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image174_thumb.gif" width="452" height="390" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;85&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;添加&lt;/strong&gt;&lt;strong&gt;Web Browser&lt;/strong&gt;&lt;strong&gt;组件&lt;/strong&gt; &lt;p&gt;5. 在 DinnerNow Web Service组件中应该提供了餐厅所拥有的功能，如招待客户订餐的服务和进行餐饮烹饪的服务。所以，模仿步骤3，在&lt;strong&gt;DinnerNow Web Service&lt;/strong&gt;&lt;strong&gt;组件&lt;/strong&gt;中放置&lt;strong&gt;两个小的组件&lt;/strong&gt;，分别命名为&lt;strong&gt;Customer Web Server&lt;/strong&gt;和&lt;strong&gt;Kitchen Server&lt;/strong&gt;&lt;strong&gt;。&lt;/strong&gt;在属性选项卡中，修改名称属性为相应的名称。 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image176_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image176" border="0" alt="clip_image176" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image176_thumb.jpg" width="586" height="484" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;86&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;在&lt;/strong&gt;&lt;strong&gt;DinnerNow Web Server&lt;/strong&gt;&lt;strong&gt;组件中添加&lt;/strong&gt;&lt;strong&gt;Customer Web Server &lt;/strong&gt;&lt;strong&gt;组件和&lt;/strong&gt;&lt;strong&gt;Kitchen Server &lt;/strong&gt;&lt;strong&gt;组件，并重命名&lt;/strong&gt; &lt;p&gt;6. 客户通过浏览器请求访问到DinnerNow Web Service组件中的Customer Web Server组件，进行餐饮相关的检索和订餐。所以&lt;strong&gt;右键&lt;/strong&gt;单击&lt;strong&gt;Web Browser&lt;/strong&gt;&lt;strong&gt;组件&lt;/strong&gt;，选择&lt;strong&gt;添加&lt;/strong&gt;&lt;strong&gt;-&amp;gt;&lt;/strong&gt;&lt;strong&gt;请求接口&lt;/strong&gt;。 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image178_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image178" border="0" alt="clip_image178" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image178_thumb.jpg" width="588" height="484" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;87&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;添加请求接口菜单项&lt;/strong&gt;&lt;strong&gt;&lt;/strong&gt; &lt;p&gt;7. 由于浏览器请求DinnerNow Web Service使用HTTP协议，单击请求接口的文本&lt;strong&gt;Interface1&lt;/strong&gt;，修改为&lt;strong&gt;HTTP&lt;/strong&gt;，并在属性选项卡中将HTTP请求接口名称&lt;strong&gt;Port1&lt;/strong&gt;修改为&lt;strong&gt;HTTP&lt;/strong&gt;。 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image180_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image180" border="0" alt="clip_image180" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image180_thumb.jpg" width="587" height="484" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;88&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;添加&lt;/strong&gt;&lt;strong&gt;HTTP&lt;/strong&gt;&lt;strong&gt;请求接口&lt;/strong&gt; &lt;p&gt;8. Web Browser组件的请求要想进入DinnerNow Web Service组件，后者必须提供一个提供程序接口用来响应。所以&lt;strong&gt;右键&lt;/strong&gt;单击&lt;strong&gt;DinnerNow Web Service&lt;/strong&gt;&lt;strong&gt;组件&lt;/strong&gt;，选择&lt;strong&gt;添加&lt;/strong&gt;&lt;strong&gt;-&amp;gt;&lt;/strong&gt;&lt;strong&gt;提供程序接口&lt;/strong&gt;。 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image182_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image182" border="0" alt="clip_image182" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image182_thumb.jpg" width="590" height="484" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;89&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;为&lt;/strong&gt;&lt;strong&gt;DinnerNow WebService&lt;/strong&gt;&lt;strong&gt;添加提供程序接口&lt;/strong&gt; &lt;p&gt;9. 单击提供程序接口上的文本&lt;strong&gt;Interface2&lt;/strong&gt;，将其修改为&lt;strong&gt;Customer Web Site&lt;/strong&gt;。在属性选项卡中，将&lt;strong&gt;名称&lt;/strong&gt;&lt;strong&gt;Port1&lt;/strong&gt;修改为&lt;strong&gt;Customer Web Site&lt;/strong&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image184_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image184" border="0" alt="clip_image184" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image184_thumb.jpg" width="589" height="484" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;90&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;定义&lt;/strong&gt;&lt;strong&gt;DinnerNow WebService&lt;/strong&gt;&lt;strong&gt;提供程序接口的名称&lt;/strong&gt; &lt;p&gt;10. &lt;strong&gt;右键&lt;/strong&gt;单击Web Browser组件的&lt;strong&gt;HTTP&lt;/strong&gt;&lt;strong&gt;请求接口&lt;/strong&gt;，选择&lt;strong&gt;添加&lt;/strong&gt;&lt;strong&gt;-&amp;gt;&lt;/strong&gt;&lt;strong&gt;依赖。&lt;/strong&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image186_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image186" border="0" alt="clip_image186" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image186_thumb.jpg" width="590" height="484" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;91&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;添加依赖关系的右键菜单&lt;/strong&gt; &lt;p&gt;11. 将依赖关系的另一头拖放到DinnerNow Web Service组件的&lt;strong&gt;Customer Web Site&lt;/strong&gt;&lt;strong&gt;提供程序接口&lt;/strong&gt;，并&lt;strong&gt;单击&lt;/strong&gt;。 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image188_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image188" border="0" alt="clip_image188" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image188_thumb.jpg" width="589" height="484" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;92&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;拖放依赖关系&lt;/strong&gt;&lt;strong&gt;&lt;/strong&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image190_2.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image190" border="0" alt="clip_image190" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image190_thumb.gif" width="578" height="425" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;93&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;建立依赖关系后的效果&lt;/strong&gt; &lt;p&gt;12. 客户的订餐请求经过Customer Web Site接收后，进入DinnerNow Web Service执行，但是要想让内部的组件获得外部的请求，同样需要在内部组件上建立提供程序接口用来接收进入DinnerNow Web Service的请求。参考&lt;strong&gt;步骤&lt;/strong&gt;&lt;strong&gt;10&lt;/strong&gt;，为&lt;strong&gt;Customer Web Server&lt;/strong&gt;&lt;strong&gt;组件&lt;/strong&gt;添加一个名称为&lt;strong&gt;Sales&lt;/strong&gt;&lt;strong&gt;的提供程序接口&lt;/strong&gt;。 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image192_2.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image192" border="0" alt="clip_image192" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image192_thumb.gif" width="578" height="425" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;94&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;建立&lt;/strong&gt;&lt;strong&gt;Sales&lt;/strong&gt;&lt;strong&gt;接口&lt;/strong&gt; &lt;p&gt;13. 在组件内部的各个部分之间，存在着消息或事件的传递，就是委托。所以，在消息内部的接口之间使用委托关系来表示消息的流向和事件的响应。参考&lt;strong&gt;步骤&lt;/strong&gt;&lt;strong&gt;11&lt;/strong&gt;，在&lt;strong&gt;Customer Web Site&lt;/strong&gt;&lt;strong&gt;接口&lt;/strong&gt;与&lt;strong&gt;Sales&lt;/strong&gt;&lt;strong&gt;接口&lt;/strong&gt;之间建立&lt;strong&gt;委托关系&lt;/strong&gt;&lt;strong&gt;.&lt;/strong&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image194_2.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image194" border="0" alt="clip_image194" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image194_thumb.gif" width="578" height="425" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;95&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;建立从&lt;/strong&gt;&lt;strong&gt;Customer Web Site&lt;/strong&gt;&lt;strong&gt;接口到&lt;/strong&gt;&lt;strong&gt;Sales&lt;/strong&gt;&lt;strong&gt;接口的委托关系&lt;/strong&gt; &lt;p&gt;14. 进入Customer Web Server组件的订餐请求，经过处理之后，会执行两件事。一是向银行发送付款验证，二是将客户的菜单发送到厨房进行加工。由于银行属于DinnerNow Web Service组件的外部，且DinnerNow Web Service只需向银行发送付款验证请求即可。所以，参考&lt;strong&gt;步骤&lt;/strong&gt;&lt;strong&gt;6&lt;/strong&gt;&lt;strong&gt;、7&lt;/strong&gt;，为&lt;strong&gt;Customer Web Server&lt;/strong&gt;&lt;strong&gt;组件&lt;/strong&gt;添加&lt;strong&gt;PaymentAuthorization&lt;/strong&gt;&lt;strong&gt;请求接口&lt;/strong&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image196_2.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image196" border="0" alt="clip_image196" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image196_thumb.gif" width="578" height="425" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;96&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;为&lt;/strong&gt;&lt;strong&gt;Customer Web Server&lt;/strong&gt;&lt;strong&gt;组件添加&lt;/strong&gt;&lt;strong&gt;PaymentAuthorization&lt;/strong&gt;&lt;strong&gt;请求接口&lt;/strong&gt; &lt;p&gt;15. DinnerNow Web Service组件内部的部件要想将消息发送到组件外部的其他系统中，也需要一个向外的请求接口。所以参考&lt;strong&gt;步骤&lt;/strong&gt;&lt;strong&gt;8&lt;/strong&gt;&lt;strong&gt;、9&lt;/strong&gt;，在&lt;strong&gt;DinnerNow Web Service&lt;/strong&gt;&lt;strong&gt;组件左侧 &lt;/strong&gt;&lt;strong&gt;边框&lt;/strong&gt;上添加一个&lt;strong&gt;PaymentAuthorization&lt;/strong&gt;&lt;strong&gt;请求接口&lt;/strong&gt;，用来将Customer Web Server组件的PaymentAuthorization接口发送的消息传递到DinnerNow Web Service组件外部 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image198_2.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image198" border="0" alt="clip_image198" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image198_thumb.gif" width="591" height="425" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;97&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;为&lt;/strong&gt;&lt;strong&gt;DinnerNow Web Service&lt;/strong&gt;&lt;strong&gt;组件添加&lt;/strong&gt;&lt;strong&gt;PaymentAuthorization&lt;/strong&gt;&lt;strong&gt;请求接口&lt;/strong&gt; &lt;p&gt;16. 参考&lt;strong&gt;步骤&lt;/strong&gt;&lt;strong&gt;13&lt;/strong&gt;，从&lt;strong&gt;Customer Web Server&lt;/strong&gt;&lt;strong&gt;组件&lt;/strong&gt;的&lt;strong&gt;PaymentAuthorization&lt;/strong&gt;&lt;strong&gt;请求接口&lt;/strong&gt;到&lt;strong&gt;DinnerNow Web Service&lt;/strong&gt;&lt;strong&gt;组件&lt;/strong&gt;的&lt;strong&gt;PaymentAuthorization&lt;/strong&gt;&lt;strong&gt;请求接口&lt;/strong&gt;建立&lt;strong&gt;委托关系&lt;/strong&gt;。这样就完成了Customer Web Server向外部银行的消息传递。 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image200_2.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image200" border="0" alt="clip_image200" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image200_thumb.gif" width="591" height="425" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;98&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;从内部&lt;/strong&gt;&lt;strong&gt;PaymentAuthorization&lt;/strong&gt;&lt;strong&gt;接口到外部&lt;/strong&gt;&lt;strong&gt;PaymentAuthorization&lt;/strong&gt;&lt;strong&gt;接口建立委托关系&lt;/strong&gt; &lt;p&gt;17. Customer Web Server组件的另一个功能是将客户的菜单送到厨房进行加工。所以，参考&lt;strong&gt;步骤&lt;/strong&gt;&lt;strong&gt;14&lt;/strong&gt;，为&lt;strong&gt;Customer Web Server&lt;/strong&gt;&lt;strong&gt;组件&lt;/strong&gt;建立另一个&lt;strong&gt;请求接口&lt;/strong&gt;，名称为&lt;strong&gt;MealOrdering&lt;/strong&gt;&lt;strong&gt;。&lt;/strong&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image202_2.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image202" border="0" alt="clip_image202" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image202_thumb.gif" width="591" height="413" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;99&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;为&lt;/strong&gt;&lt;strong&gt;Customer Web Server&lt;/strong&gt;&lt;strong&gt;组件添加&lt;/strong&gt;&lt;strong&gt;MealOrdering&lt;/strong&gt;&lt;strong&gt;接口&lt;/strong&gt; &lt;p&gt;18. 参考步骤12，为&lt;strong&gt;Kitchen Server&lt;/strong&gt;&lt;strong&gt;组件&lt;/strong&gt;添加一个&lt;strong&gt;提供程序接口&lt;/strong&gt;，命名为&lt;strong&gt;MealOrdering&lt;/strong&gt;。 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image204_2.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image204" border="0" alt="clip_image204" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image204_thumb.gif" width="591" height="413" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;100&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;为&lt;/strong&gt;&lt;strong&gt;Kitchen Server&lt;/strong&gt;&lt;strong&gt;组件添加&lt;/strong&gt;&lt;strong&gt;MealOrdering&lt;/strong&gt;&lt;strong&gt;接口&lt;/strong&gt; &lt;p&gt;19. 由于Customer Web Server和Kitchen Server 两个组件同处在DinnerNow Web Service组件内部，所以 不需要消息的传递和事件机制，而应该建立直接的调用关系。&lt;strong&gt;右键&lt;/strong&gt;单击&lt;strong&gt;Customer Web Server&lt;/strong&gt;&lt;strong&gt;组件的MealOrdering&lt;/strong&gt;&lt;strong&gt;请求接口&lt;/strong&gt;，选择&lt;strong&gt;添加&lt;/strong&gt;&lt;strong&gt;-&amp;gt;&lt;/strong&gt;&lt;strong&gt;部件引用&lt;/strong&gt;。然后将鼠标拖放到&lt;strong&gt;Kitchen Server&lt;/strong&gt;&lt;strong&gt;组件的MealOrdering&lt;/strong&gt;&lt;strong&gt;提供程序接口&lt;/strong&gt;上，建立 直接的程序集调用关系。 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image206_2.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image206" border="0" alt="clip_image206" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image206_thumb.gif" width="591" height="413" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;101&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;从&lt;/strong&gt;&lt;strong&gt; Customer Web Server&lt;/strong&gt;&lt;strong&gt;组件的&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;请求接口&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;到&lt;/strong&gt;&lt;strong&gt; Kitchen Server&lt;/strong&gt;&lt;strong&gt;组件的&lt;/strong&gt;&lt;strong&gt; MealOrdering&lt;/strong&gt;&lt;strong&gt;提供程序接口建立部件程序集引用关系&lt;/strong&gt; &lt;p&gt;20. Kitchen Server组件将接受来自厨房提交的菜品制作顺序，而Kitchen Server会按照制作顺序进行制作。真实的厨房应该属于DinnerNow Web Service组件外部的元素。所以，参考&lt;strong&gt;步骤&lt;/strong&gt;&lt;strong&gt;8&lt;/strong&gt;&lt;strong&gt;、9&lt;/strong&gt;，在&lt;strong&gt;DinnerNow Web Service&lt;/strong&gt;&lt;strong&gt;组件&lt;/strong&gt;的&lt;strong&gt;右边界&lt;/strong&gt;，添加一个&lt;strong&gt;提供程序接口&lt;/strong&gt;，命名为&lt;strong&gt;Kitchen Web Site&lt;/strong&gt;。再参照&lt;strong&gt;步骤&lt;/strong&gt;&lt;strong&gt;18&lt;/strong&gt;，在&lt;strong&gt;Kitchen Server&lt;/strong&gt;&lt;strong&gt;组件&lt;/strong&gt;上添加一个&lt;strong&gt;提供程序接口&lt;/strong&gt;，命名为&lt;strong&gt;KitchenWorkQueue&lt;/strong&gt;。并参考&lt;strong&gt;步骤&lt;/strong&gt;&lt;strong&gt;13&lt;/strong&gt;，&lt;strong&gt;从前者到后者&lt;/strong&gt;建立&lt;strong&gt;委托关系&lt;/strong&gt;。 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image208_2.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image208" border="0" alt="clip_image208" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image208_thumb.gif" width="759" height="453" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;102&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;建立&lt;/strong&gt;&lt;strong&gt;Kitchen Web Site&lt;/strong&gt;&lt;strong&gt;提供程序接口和&lt;/strong&gt;&lt;strong&gt;KitchenWorkQueue&lt;/strong&gt;&lt;strong&gt;提供程序接口，并建立二者之间的委托关系&lt;/strong&gt; &lt;p&gt;21. 至此，我们完成了客户订餐到厨房加工几个环节的组件图，保存并关闭设计界面 &lt;p&gt;&lt;strong&gt;Task &lt;/strong&gt;&lt;strong&gt;4 &lt;/strong&gt;&lt;strong&gt;&amp;#8211; &lt;/strong&gt;&lt;strong&gt;类图&lt;/strong&gt; &lt;p&gt;软件设计建模中的UML类图描述了你的应用程序中使用的对象和消息结构。这些对象和消息，既包括系统内部的调用，又包含系统与用户的交互信息。它所描述的信息没有任何实现。它的类和关系可以使用多种方式实现，如数据库表、XML节点、或者软件对象组件。这个案例中，我们需要对用户需求建模中的概念类图进行一定的修改 &lt;p&gt;1. 在&lt;strong&gt;解决方案浏览器&lt;/strong&gt;中的&lt;strong&gt;ModelingProjectDinnerNow&lt;/strong&gt;解决方案下，&lt;strong&gt;双击&lt;/strong&gt;类图&lt;strong&gt;UMLClassDiagramDinnerNow.classdiagram&lt;/strong&gt;，在设计界面中打开类图。 &lt;p&gt;2. 由于菜单与菜单项之间是所有权的关系，而订单与订单项是整体与部分的关系，所以这里要修改Menu与MenuItem之间的关系为所有权关系。单击选中&lt;strong&gt;Menu&lt;/strong&gt;&lt;strong&gt;类&lt;/strong&gt;与&lt;strong&gt;MenuItem&lt;/strong&gt;&lt;strong&gt;类&lt;/strong&gt;之间的&lt;strong&gt;关系&lt;/strong&gt;，并保持选中状态。打开&lt;strong&gt;属性&lt;/strong&gt;选项卡，依次展开&lt;strong&gt;Navigation-&amp;gt;First Role&lt;/strong&gt;组。在First Role组中，找到&lt;strong&gt;Aggregation&lt;/strong&gt;属性，并在下拉列表选项中将值&lt;strong&gt;Composite&lt;/strong&gt;，修改为&lt;strong&gt;Shared&lt;/strong&gt;，此时效果如下图所示，Menu与MenuItem类之间的关系变成了空心菱形的所有权关系 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image210_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image210" border="0" alt="clip_image210" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image210_thumb.jpg" width="589" height="484" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;103&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;修改&lt;/strong&gt;&lt;strong&gt;Menu&lt;/strong&gt;&lt;strong&gt;类与&lt;/strong&gt;&lt;strong&gt;MenuItem&lt;/strong&gt;&lt;strong&gt;类之间的关系为所有权关系&lt;/strong&gt; &lt;p&gt;3. 通常订单总是需要一个订单总价，所以我们为Order类添加一个保存总价的属性。单击Order类左上角的扩展箭头，展开Order类。 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image212_2.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image212" border="0" alt="clip_image212" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image212_thumb.gif" width="452" height="330" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;104&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;展开&lt;/strong&gt;&lt;strong&gt;Order&lt;/strong&gt;&lt;strong&gt;类&lt;/strong&gt; &lt;p&gt;4. 右键单击&lt;strong&gt;Order&lt;/strong&gt;&lt;strong&gt;类&lt;/strong&gt;的&lt;strong&gt;Attributes&lt;/strong&gt;组，在弹出的菜单中选择&lt;strong&gt;添加&lt;/strong&gt;&lt;strong&gt;-&amp;gt;&lt;/strong&gt;&lt;strong&gt;属性&lt;/strong&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image214_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image214" border="0" alt="clip_image214" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image214_thumb.jpg" width="586" height="484" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;105&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;添加属性右键菜单&lt;/strong&gt; &lt;p&gt;5. 此时，在Order类的属性组内出现一个可编辑的属性，文本为+Attribute1。保持可编缉状态，将文本&lt;strong&gt;+Attribute1&lt;/strong&gt;修改为&lt;strong&gt;+TotalPrice&lt;/strong&gt;。然后按下&lt;strong&gt;回车&lt;/strong&gt;，确认修改。 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image216_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image216" border="0" alt="clip_image216" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image216_thumb.jpg" width="587" height="484" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;106&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;修改&lt;/strong&gt;&lt;strong&gt;TotalPrice&lt;/strong&gt;&lt;strong&gt;属性名&lt;/strong&gt; &lt;p&gt;6. 再次单击选中&lt;strong&gt;TotalPrice&lt;/strong&gt;属性，在属性窗口中的&lt;strong&gt;常用属性&lt;/strong&gt;组中找到&lt;strong&gt;类型&lt;/strong&gt;属性。在下拉列表中输入&lt;strong&gt;Money&lt;/strong&gt;。表示这个总价属性是货币类型。 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image218_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image218" border="0" alt="clip_image218" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image218_thumb.jpg" width="585" height="484" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;107&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;修改&lt;/strong&gt;&lt;strong&gt;TotalPrice&lt;/strong&gt;&lt;strong&gt;属性的数据类型&lt;/strong&gt;&lt;strong&gt;&lt;/strong&gt; &lt;p&gt;7. 在Order类中，常用的对订单的操作，这里举两个例子。一个是添加订单项，一个是删除订单项。右键单击&lt;strong&gt;Order&lt;/strong&gt;&lt;strong&gt;类&lt;/strong&gt;的&lt;strong&gt;操作&lt;/strong&gt;组，在右键菜单中选择&lt;strong&gt;添加&lt;/strong&gt;&lt;strong&gt;-&amp;gt;&lt;/strong&gt;&lt;strong&gt;操作&lt;/strong&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image220_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image220" border="0" alt="clip_image220" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image220_thumb.jpg" width="586" height="484" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;108&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;为&lt;/strong&gt;&lt;strong&gt;Order&lt;/strong&gt;&lt;strong&gt;类添加方法菜单&lt;/strong&gt; &lt;p&gt;8. 此时，在操作组内会出现一个可编辑的操作，文本为+ Operation1()，将其修改为+ AddItem()。按下&lt;strong&gt;回车&lt;/strong&gt;，确认修改。 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image222_2.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image222" border="0" alt="clip_image222" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image222_thumb.gif" width="452" height="330" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;109&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;为&lt;/strong&gt;&lt;strong&gt;Order&lt;/strong&gt;&lt;strong&gt;类添加&lt;/strong&gt;&lt;strong&gt;AddItem&lt;/strong&gt;&lt;strong&gt;方法&lt;/strong&gt; &lt;p&gt;9. Order类中的添加订单项方法，如果要执行，必须接受一个订单项，作为待插入的资源。单击&lt;strong&gt;AddItem&lt;/strong&gt;操作，在&lt;strong&gt;属性&lt;/strong&gt;选项卡中找到&lt;strong&gt;参数列表属性&lt;/strong&gt;，单击属性值文本框中的&lt;strong&gt;省略号按钮&lt;/strong&gt;，打开 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image224_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image224" border="0" alt="clip_image224" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image224_thumb.jpg" width="586" height="484" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;110&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;打开参数列表属性的省略号按钮&lt;/strong&gt;&lt;strong&gt;&lt;/strong&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image226_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image226" border="0" alt="clip_image226" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image226_thumb.jpg" width="644" height="459" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;111&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;操作参数集合编辑器&lt;/strong&gt; &lt;p&gt;10. 如上图所示，点击左下角的&lt;strong&gt;添加&lt;/strong&gt;按钮。在&lt;strong&gt;成员列表&lt;/strong&gt;中选中自动添加的&lt;strong&gt;Parameter1&lt;/strong&gt;参数，在右侧属性列表中，找到&lt;strong&gt;Name&lt;/strong&gt;&lt;strong&gt;属性&lt;/strong&gt;，将其修改为&lt;strong&gt;MenuItem&lt;/strong&gt;，在&lt;strong&gt;Type&lt;/strong&gt;属性的下拉列表中，选择&lt;strong&gt;ModelingProjectDinnerNow::MenuItem&lt;/strong&gt;。单击&lt;strong&gt;确定&lt;/strong&gt;完成参数的定义 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image228_2.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image228" border="0" alt="clip_image228" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image228_thumb.gif" width="512" height="366" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;112&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;为&lt;/strong&gt;&lt;strong&gt;AddItem&lt;/strong&gt;&lt;strong&gt;方法添加&lt;/strong&gt;&lt;strong&gt;MenuItem&lt;/strong&gt;&lt;strong&gt;参数&lt;/strong&gt; &lt;p&gt;11. 参照&lt;strong&gt;步骤&lt;/strong&gt;&lt;strong&gt;9&lt;/strong&gt;&lt;strong&gt;、10&lt;/strong&gt;，为&lt;strong&gt;Order&lt;/strong&gt;&lt;strong&gt;类&lt;/strong&gt;添加&lt;strong&gt;DeleteItem&lt;/strong&gt;&lt;strong&gt;方法&lt;/strong&gt;，并添加&lt;strong&gt;MenuItem&lt;/strong&gt;&lt;strong&gt;参数&lt;/strong&gt;。 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image230_2.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image230" border="0" alt="clip_image230" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image230_thumb.gif" width="524" height="366" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;113&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;添加&lt;/strong&gt;&lt;strong&gt;DeleteItem&lt;/strong&gt;&lt;strong&gt;方法&lt;/strong&gt; &lt;p&gt;12. 通常餐厅除了支持网上下单外，更灵活的方式是电话订餐。此时生成的订单是电话订单。而电话订单中包含了普通订单的所有数据，但是却拥有一个特殊的属性，就是订单反馈的电话。在设计界面的右下角&lt;strong&gt;空白处&lt;/strong&gt;，&lt;strong&gt;单击右键&lt;/strong&gt;，选择&lt;strong&gt;添加&lt;/strong&gt;&lt;strong&gt;-&amp;gt;&lt;/strong&gt;&lt;strong&gt;类&lt;/strong&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image232_2.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image232" border="0" alt="clip_image232" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image232_thumb.gif" width="620" height="366" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;114&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;添加新类&lt;/strong&gt; &lt;p&gt;13. 单击&lt;strong&gt;Class1&lt;/strong&gt;&lt;strong&gt;类&lt;/strong&gt;名部分，使其可编辑。将文本&lt;strong&gt;Class1&lt;/strong&gt;修改为&lt;strong&gt;PhoneOrder&lt;/strong&gt;。 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image234_2.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image234" border="0" alt="clip_image234" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image234_thumb.gif" width="620" height="366" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;115&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;修改&lt;/strong&gt;&lt;strong&gt;PhoneOrder&lt;/strong&gt;&lt;strong&gt;类名&lt;/strong&gt; &lt;p&gt;14. 参照&lt;strong&gt;步骤&lt;/strong&gt;&lt;strong&gt;4&lt;/strong&gt;&lt;strong&gt;、5&lt;/strong&gt;&lt;strong&gt;、6&lt;/strong&gt;，为&lt;strong&gt;PhoneOrder&lt;/strong&gt;&lt;strong&gt;类&lt;/strong&gt;添加一个&lt;strong&gt;字符串&lt;/strong&gt;类型属性：&lt;strong&gt;CallbackNumber&lt;/strong&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image236_2.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image236" border="0" alt="clip_image236" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image236_thumb.gif" width="656" height="366" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;116&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;为&lt;/strong&gt;&lt;strong&gt;PhoneOrder&lt;/strong&gt;&lt;strong&gt;类添加&lt;/strong&gt;&lt;strong&gt;CallbackNumber&lt;/strong&gt;&lt;strong&gt;属性&lt;/strong&gt; &lt;p&gt;15. &lt;strong&gt;右键&lt;/strong&gt;单击&lt;strong&gt;PhoneOrder&lt;/strong&gt;&lt;strong&gt;类&lt;/strong&gt;，在菜单中选择&lt;strong&gt;添加&lt;/strong&gt;&lt;strong&gt;-&amp;gt;&lt;/strong&gt;&lt;strong&gt;继承&lt;/strong&gt;。 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image238_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image238" border="0" alt="clip_image238" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image238_thumb.jpg" width="589" height="484" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;117&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;添加继承菜单&lt;/strong&gt; &lt;p&gt;16. 将鼠标移动到Order类上，直到出现连接标识。点击Order类，确认建立继承关系 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image240_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image240" border="0" alt="clip_image240" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image240_thumb.jpg" width="585" height="484" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;118&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;建立&lt;/strong&gt;&lt;strong&gt;PhoneOrder&lt;/strong&gt;&lt;strong&gt;类到&lt;/strong&gt;&lt;strong&gt;Order&lt;/strong&gt;&lt;strong&gt;类的继承关系&lt;/strong&gt;&lt;strong&gt;&lt;/strong&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image242_2.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image242" border="0" alt="clip_image242" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image242_thumb.gif" width="656" height="366" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;119&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;建立&lt;/strong&gt;&lt;strong&gt;PhoneOrder&lt;/strong&gt;&lt;strong&gt;类到&lt;/strong&gt;&lt;strong&gt;Order&lt;/strong&gt;&lt;strong&gt;类的继承关系完成&lt;/strong&gt; &lt;p&gt;17. 至此，更详细的类图的设计就完成了。保存并关闭当前设计界面 &lt;p&gt;&lt;a name="_Toc145818330"&gt;&lt;/a&gt;&lt;a name="_Toc137338509"&gt;Exercise 3 &lt;/a&gt;代码浏览器 &lt;p&gt;&lt;strong&gt;概述&lt;/strong&gt; &lt;p&gt;当你需要修改现有软件系统时，Visual Studio旗舰版可以帮助你以可视化的方式理解组织结构、关系以及代码中的行为。在你修改代码之前，使用Visual Studio 旗舰版来浏览这些更改如何影响代码，从而帮助你评估风险和工作量。 &lt;p&gt;&lt;strong&gt;&lt;br /&gt;&lt;/strong&gt;&lt;p&gt;&lt;a name="_Toc137338511"&gt;&lt;/a&gt;&lt;a name="_Toc145818332"&gt;&lt;strong&gt;Task 1 &amp;#8211; &lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;从现有代码生成图形化文档&amp;#8212;&amp;#8212;查看Visual Studio解决方案中的源代码概要 &lt;/strong&gt;&lt;p&gt;1. 打开需要查看的Visual Studio 解决方案，这里我们使用&lt;strong&gt;PetShop&lt;/strong&gt;.&lt;strong&gt; &lt;/strong&gt;&lt;p&gt;2. 在Visual Studio 2010的顶部菜单中选择&lt;strong&gt;架构&lt;/strong&gt;菜单。在架构菜单中选择&lt;strong&gt;生成依赖图形&lt;/strong&gt;。接下来可选择以下选项之一执行 &lt;table border="1" cellspacing="0" cellpadding="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td valign="top" width="151"&gt;&lt;p&gt;&lt;strong&gt;生成依赖图形&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;td valign="top" width="643"&gt;&lt;p&gt;&lt;strong&gt;图形显示的内容&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top" width="151"&gt;&lt;p&gt;&lt;strong&gt;按照程序集引用&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;td valign="top" width="643"&gt;&lt;p&gt;解决方案中的所有程序集间，以及内部程序集与外部依赖项之间的聚集依赖关系。 &lt;p&gt;为了查看命名空间、类和内部方法，以图形化的方式展开引用。外部组件，只显示在项目中使用到的。&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top" width="151"&gt;&lt;p&gt;&lt;strong&gt;按照命名空间&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;td valign="top" width="643"&gt;&lt;p&gt;解决方案中的所有命名空间之间，以及内部命名空间与外部依赖的命名空间之间的聚集依赖关系。 &lt;p&gt;为了查看命名空间里的类和方法，以图形化的方式展开命名空间。外部命名空间，只显示在项目中使用到的。&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top" width="151"&gt;&lt;p&gt;&lt;strong&gt;按照类&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;td valign="top" width="643"&gt;&lt;p&gt;解决方案中的所有类之间的聚集依赖关系。不会出现用到的外部类的信息。&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image244_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image244" border="0" alt="clip_image244" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image244_thumb.jpg" width="644" height="277" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;120&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;生成依赖图形的菜单项&lt;/strong&gt;&lt;strong&gt;&lt;/strong&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image246_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image246" border="0" alt="clip_image246" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image246_thumb.jpg" width="898" height="708" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;121&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;按程序集引用浏览的架构图&lt;/strong&gt;&lt;strong&gt;&lt;/strong&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image248_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image248" border="0" alt="clip_image248" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image248_thumb.jpg" width="910" height="725" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;122&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;按命名空间浏览的架构图&lt;/strong&gt;&lt;strong&gt;&lt;/strong&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image250_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image250" border="0" alt="clip_image250" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image250_thumb.jpg" width="914" height="1338" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;123&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;按类结构浏览的架构图&lt;/strong&gt; &lt;p&gt;&lt;a name="_Toc145818333"&gt;&lt;/a&gt;&lt;a name="_Toc137338512"&gt;&lt;strong&gt;Task 2 &amp;#8211;&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;从现有代码生成图形化文档&amp;#8212;&amp;#8212;&lt;/strong&gt;&lt;strong&gt;查看Visual Studio 解决方案中的源代码的特定依赖&lt;/strong&gt;&lt;strong&gt;&lt;/strong&gt; &lt;p&gt;利用架构资源管理可视化的查看你需要的代码和关系。 &lt;p&gt;1. 打开需要查看的Visual Studio 解决方案，这里我们使用&lt;strong&gt;PetShop&lt;/strong&gt;. &lt;p&gt;2. 如果架构浏览器没有打开，在&lt;strong&gt;架构&lt;/strong&gt;菜单中，点击&lt;strong&gt;Windows-&amp;gt;&lt;/strong&gt;&lt;strong&gt;架构浏览器&lt;/strong&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image252_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image252" border="0" alt="clip_image252" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image252_thumb.jpg" width="644" height="276" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;124&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;从菜单打开架构浏览器&lt;/strong&gt; &lt;p&gt;3. 在架构浏览器的第一列中的Visual Studio节点下选择如下两项： &lt;p&gt;l 类视图：用来查看代码的逻辑结构。以命名空间、类、方法等形式浏览。 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image254_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image254" border="0" alt="clip_image254" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image254_thumb.jpg" width="644" height="292" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;125&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;类视图效果&lt;/strong&gt; &lt;p&gt;l 解决方案视图：用来查看代码的物理结构。以项目、源文件等形式浏览。 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image256_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image256" border="0" alt="clip_image256" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image256_thumb.jpg" width="644" height="290" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;126&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;解决方案视图效果&lt;/strong&gt; &lt;p&gt;4. 选中&lt;strong&gt;类视图&lt;/strong&gt;&lt;strong&gt;/&lt;/strong&gt;&lt;strong&gt;解决方案&lt;/strong&gt;视图，右侧会出现&lt;strong&gt;命名空间&lt;/strong&gt;&lt;strong&gt;/&lt;/strong&gt;&lt;strong&gt;项目&lt;/strong&gt;列表。在列表选择你想查看的命名空间/项目。全选使用&lt;strong&gt;Ctrl+A&lt;/strong&gt;。多选时，按住&lt;strong&gt;Ctrl&lt;/strong&gt;。在第二列选择要查看的对象同时，第三列会弹出&lt;strong&gt;类&lt;/strong&gt;&lt;strong&gt;/&lt;/strong&gt;&lt;strong&gt;文件&lt;/strong&gt;列表 &lt;p&gt;5. 重复步骤4，选中你想要查看的对象。这里我们在&lt;strong&gt;命名空间&lt;/strong&gt;&lt;strong&gt;/&lt;/strong&gt;&lt;strong&gt;项目&lt;/strong&gt;列表中选中：&lt;strong&gt;BLL&lt;/strong&gt;。并使用&lt;strong&gt;Ctrl+A&lt;/strong&gt;全选&lt;strong&gt;类型和成员&lt;/strong&gt;列表中的&lt;strong&gt;所有项。&lt;/strong&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image258_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image258" border="0" alt="clip_image258" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image258_thumb.jpg" width="644" height="282" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;127&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;创建新的图形文档的按钮&lt;/strong&gt; &lt;p&gt;6. 需要为你选中的对象建立新的关系图，请在架构浏览器的左上角&lt;strong&gt;标题栏下方&lt;/strong&gt;，单击&lt;strong&gt;为你选择的节点创建一个新的图形文档&lt;/strong&gt;按钮。此时Visual Studio 就会创建一个&lt;strong&gt;向导图形文档&lt;/strong&gt;（.dgml）,并打开它。 &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image260_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image260" border="0" alt="clip_image260" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/VisualStudio2010TeamSystem_9C64/clip_image260_thumb.jpg" width="951" height="774" /&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;Figure &lt;/strong&gt;&lt;strong&gt;128&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;生成的向导图形文档&lt;/strong&gt;&lt;strong&gt;&lt;/strong&gt; &lt;p&gt;7. 到此，我们就成功将现有代码展示成了可视化文档。保存并关闭当前设计界面。 &lt;/p&gt;&lt;img src="http://www.cnblogs.com/Phoenix-Rock/aggbug/1797317.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/Phoenix-Rock/archive/2010/08/11/VS2010-Model.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/Phoenix-Rock/archive/2010/08/05/Silverlight_2.html</id><title type="text">Silverlight 框架介绍</title><summary type="text">Silverlight框架介绍</summary><published>2010-08-05T06:37:00Z</published><updated>2010-08-05T06:37:00Z</updated><author><name>天马行空（笨笨）</name><uri>http://www.cnblogs.com/Phoenix-Rock/</uri></author><link rel="alternate" href="http://www.cnblogs.com/Phoenix-Rock/archive/2010/08/05/Silverlight_2.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/Phoenix-Rock/archive/2010/08/05/Silverlight_2.html"/><content type="html">&lt;div class="postTitle"&gt;&amp;nbsp;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;关键概念和技术&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&amp;#9679; 了解Silverlight的架构以及Silverlight与WPF的比较&lt;br /&gt;&amp;#9679; 实践如何安装Silverlight&lt;br /&gt;&amp;#9679; 研究支持Silverlight的编程语言&lt;br /&gt;&amp;#9679; 认识用于创建Silverlight应用程序的工具&lt;br /&gt;&amp;#9679; 集成Silverlight内容到ASP.NET AJAX&lt;br /&gt;&amp;#9679; 创建一个简单的Silverlight应用程序和一个简单的Silverlight动画&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Silverlight是微软最近主要的开发技术之一。渴望开发Silverlight应用程序的开发人员必须对Silverlight的问题和步骤有充分的认识。这篇文章中我们重点介绍创建Silverlight应用程序的过程。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;概述：&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Silverlight的发展符合微软技术的发展逻辑。微软技术中，除了用于交互以及创建Web应用程序的ASP（微软的第一个动态网页开发技术）以外的其他技术，都已经得到了很大的发展。正如前面文章所述，为了保持行业竞争力，微软决定完全重新设计并巩固所有开发技术到一个单一的平台中，即.NET Framework。所有微软开发技术从来都没有重新围绕.NET Framework设计，但是所有的技术却自2000年以来都被独立重新设计更新过。&lt;/p&gt;&lt;p&gt;.NET 框架是开发环境中应用的最流行和最通用的。.NET 框架的一个重点是ASP.NET。ASP.NET是ASP的.NET框架版本。ASP.NET用来创建非常强大的动态Web应用程序，用以处理那些在服务器上零散发生的处理流程。&lt;/p&gt;&lt;p&gt;Web经过多年的演变，企业和开发人员已经习惯了Web作为主要的开发平台。一个新词被用来形容新的Web应用程序：Web 2.0。Web 2.0规定Web应用程序应该简化原始开发人员的工作，而且应该能够引进其他公司或开发人员提供的服务。Web2.0应用程序的部分设计功能应该由最终用户参与定制到服务器上，并能够整合媒体和动画。&lt;/p&gt;&lt;p&gt;多年来，Web开发人员开始研究如何提升Web应用程序的性能。Web已经组合了数以百万计的互联网计算机，同时，大量零散的处理流程在服务器产生。Web 2.0表明网络，包括互联网，应该具有分布式计算能力的机群。绝大多数Web上的计算机，客户端计算机，多年以来一直作为哑终端。开发人员已经看到了如何利用那些连接到互联网中的客户端机器中未开发计算能力的方法。许多方法，例如ASP.NET AJAX，已经开发出了比标准Web应用程序能更多的在客户端机器上运行处理的平台。ASP.NET AJAX使用JavaScript，以XML的格式异步传输数据到服务器端，从而改善了用户对性能的感知，实现了更好的用户体验。旨在提高性能，为用户提供一个更好的用户体验的Web应用程序，被称为丰富的交互式应用程序（RIA）。&lt;/p&gt;&lt;p&gt;标准RIA解决方案的缺点是，他们使用JavaScrip执行客户端处理。JavaScript功能非常强大，但是直接由客户端浏览器执行，因此能否真确执行脚本主要依赖浏览器的能力。&lt;/p&gt;&lt;p&gt;微软开始尝试扩展ASP.NET AJAX来进一步控制客户端计算机环境。微软还希望确定如何可以提供类似于WPF技术那样，创建更神奇的用户界面的技术。因此，微软开发出一种新的可下载的插件技术来扩展ASP.NET AJAX，并且包含了WPF的效果和功能。由此产生了WPF/E的技术，并最终命名为Silverlight。&lt;/p&gt;&lt;p&gt;Silverlight有三个版本：1.0、2.0和3.0。1.0版本功能相当有限，而且JavaScript是唯一的语言支持。2.0版本包括很多新的功能和许多.NET兼容的编程语言。3.0版本扩展并改进了Silverlight 2中的功能和特性。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Silverlight VS. WPF&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Silverlight是WPF的一个自己和扩展，而且它采用了很多ASP.NET AJAX的很多功能和技术。随着大量针对Web的软件开发的涌现，许多开发人员质疑有了Silverlight，为什么还要开发WPF应用程序。答案是，这两种技术各有优势。Silverlight的优势在于它在Web上的可移植性。然而，Silverlight是跨平台跨浏览器变异的，因此它是平台无关的，而且不能依赖任何特定平台的优势和硬件支持，来实现更先进的图形功能要求。更先进的图形功能要求需要硬件的支持，而且必须采用特定平台的技术优势。因此，WPF中提供了先进的3-D图形功能，而且效果非常好。而Silverlight是不能提供这些功能的。Silverlight中不能依赖任何硬件，尤其是现在，更限制了它对3-D图像、语音和语音识别、录音等的硬件支持能力。尽管有少量第三方开发商在用Silverlight模拟3-D环境。&lt;/p&gt;&lt;p&gt;Silverlight 3同样限制在客户端访问本地硬件。然而，Silverlight 3引入了一个利用2-D图像模拟3-D的环境的新3-D仿真功能。新的3-D仿真功能叫做视角3-D。视角3-D使用一个简单的XAML元素来调整观察者的图片视角。视角3-D会在下篇文章中介绍。&lt;/p&gt;&lt;p&gt;Silverlight功能必须执行在一个安全的沙箱区域中，以提供安全的客户端环境。但是，安全的沙箱限制了Silverlight直接与宿主操作系统互操作的能力，以及直接进行I/O操作的能力。Silverlight 3通过&amp;#8220;文件另存为&amp;#8221;对话框扩展了一些客户端I/O交互的功能，而且用户还可以拥有离线浏览（OOB）运行Silverlight应用程序的能力。使用&amp;#8220;文件另存为&amp;#8221;对话框以及创建离线浏览应用程序，会在后面文章中介绍。&lt;/p&gt;&lt;p&gt;Silverlight和WPF的能力和约束实际上是设计平台环境影响的结果，使他们各自针对不同的平台。Silverlight是WPF的子集也仅仅是因为无法像WPF中那样充分应用色域。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Silverlight的性能&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Silverlight中有许多明显的竞争优势，包括它速度极快的渲染引擎和性能。一般应用在Web上的性能测试工具都可以说明Silverlight的性能优势。一个典型的工具就是BubbleMark，可在&lt;a href="http://bubblemark.com/"&gt;&lt;font color="#729773"&gt;http://bubblemark.com下载到&lt;/font&gt;&lt;/a&gt;。该工具可以用来比较时下绝大多数开发环境的渲染速度。下图显示了BubbleMark的主页。&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/Silverlight_EF6D/image_4.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/Silverlight_EF6D/image_thumb_1.png" width="610" height="484" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;&lt;strong&gt;Figure 3-1 BubbleMark.com 首页&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;BubbleMark.com还推出了一个使用Silverlight模拟3-D环境的示例，如下图所示：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/Silverlight_EF6D/image_6.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/Silverlight_EF6D/image_thumb_2.png" width="644" height="463" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;&lt;strong&gt;Figure 3-2 BubbleMark.com 模拟的3-D环境&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;安装Silverlight&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Silverlight插件可以直接下载和安装。用户只需要有一个支持的操作系统，并具有一个支持Silverlight应用程序的Web浏览器。&lt;/p&gt;&lt;p&gt;作为Silverlight 3的入门开发人员，你需要在Windows中安装4个组件：&lt;/p&gt;&lt;p&gt;&amp;#9679; Silverlight 3 运行时&lt;br /&gt;&amp;#9679; Silverlight 3 软件开发包 (SDK)&lt;br /&gt;&amp;#9679; Silverlight 3 的Visual Studio 工具&lt;br /&gt;&amp;#9679; Silverlight 3 控件包 &lt;p&gt;此外作为一个资深的Silverlight开发人员，你可能需要安装Expression Blend 3.Expression Blend是Expressiong 套件的组件之一，在后面文章会详细介绍。 &lt;p&gt;预计要使用服务器端数据开发Silverlight应用程序的开发人员，需要安装.NET RIA服务网。.NET RIA服务会在后面文章中详细介绍。 &lt;p&gt;Silverlight 3的帮助文档可以通过在线或手动下载的方式独立查看CHM帮助文件。 &lt;p&gt;&lt;strong&gt;Silverlight运行时&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Silverlight 3运行时的安装初始窗体如下图所示。从这个窗体中，单击&amp;#8220;立即安装&amp;#8221;按钮开始安装。&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/Silverlight_EF6D/image_10.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/Silverlight_EF6D/image_thumb_4.png" width="644" height="301" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;&lt;strong&gt;Figure 3-3 Silverlight 3 运行时初始化安装界面&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Silverlight 3屏幕会显示安装成功。一旦安装完成后，单击&amp;#8220;关闭&amp;#8221;按钮。&lt;/p&gt;&lt;p&gt;Silverlight运行时还可以安装在Macintosh上。Silverlight 3安装向导包括一些额外的步骤和安装选项。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Silverlight Visual Studio工具&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Silverlight 开发人员使用安装在Windows上的Visual Studio 2010，需要下载和安装Silverlight 3的Visual Studio工具。Visual Studio 2010工具的下载包括了Silverlight 3运行时和Silverlight软件开发包（SDK），以及Visual Studio 2010工具。如果你以开发人员的身份安装Silverlight，那么Visual Studio 2010工具是唯一必要的。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Silverlight 3 控件包&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Silverlight 3 的工具包是对Silverlight 2的升级和增强，并加入了额外的Silverlight控件和主题。&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/Silverlight_EF6D/image_12.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/Silverlight_EF6D/image_thumb_5.png" width="616" height="484" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;&lt;strong&gt;Figure 3-4 Silverlight 3 工具包的初始化安装界面&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Expression Blend 3&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Expression Blend是微软设计工具套件Expression中的组件之一。Expression 套件中的工具是用来为WPF和Silverlight应用程序编辑媒体、图形以及用户界面的工具集。Expression Blend使用图形化的设计和XAML布局设计用户界面。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;.NET RIA Services&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;.NET RIA Services是一项新的服务平台，它运行在中间层中，控制数据访问，并提供一贯的和标准的创建RIA中间层和后端代码的方法。它可以将Silverlight和ASP.NET牢固的结合在一起。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Silverlight 帮助文档&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Silverlight 3帮助文档可以在MSDN在线库中浏览：&lt;a href="http://msdn.microsoft.com/en-us/library/cc838158(vs.96).aspx"&gt;&lt;font color="#729773"&gt;http://msdn.microsoft.com/en-us/library/cc838158(vs.96).aspx&lt;/font&gt;&lt;/a&gt;，或者自行下载微软帮助文档格式的文件。&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/Silverlight_EF6D/image_18.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/Silverlight_EF6D/image_thumb_8.png" width="644" height="351" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;&lt;strong&gt;Figure 3-5 Silverlight 帮助文档&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;2010 Silverlight工具&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;许多供应商和开发商都在为使用Silverlight而积极创造编辑工具和设计工具。这里讨论两个主要Silverlight开发工具。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Microsoft Visual Studio 2010&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;微软Visual Studio 2010是微软最新的开发工具。微软所有的开发工具都已经被集成到了Visual Studio中。下面是Visual Studio 2010的启动界面。&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/Silverlight_EF6D/image_14.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/Silverlight_EF6D/image_thumb_6.png" width="600" height="484" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;&lt;strong&gt;Figure 3-6 Visual Studio 2010 起始页面&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Visual Stuido 2010可以开发所有微软提供的其他开发技术。因此，Visual Studio 2010到目前为止，比任何微软的开发工具和环境都包含更多的的技术和功能。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Microsoft Expression Blend&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;微软已经开发并发布了一整套叫做Expression套件的工具，这些工具可以用来为WPF和Silverlight应用程序设计用户界面、图形以及媒体。Experssion 套件中主要用于创建和操作Silverlight用户界面的工具是Expression Blend。下图显示了Expression Blend的起始窗体。&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/Silverlight_EF6D/image_16.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/Silverlight_EF6D/image_thumb_7.png" width="644" height="372" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;&lt;strong&gt;Figure 3-7 Expression Blend&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;虽然Visual Studio 2010时微软所有开发人员的主要开发工具，但是Expression Blend也是满足设计者需求的必需的开发工具。通常情况下，应用程序开发人员非常喜欢Visual Studio提供的直接的技术和用户界面。而应用程序设计者去非常喜欢艺术性的富有创造性的卓越的用户界面。Expression Blend就能满足设计者的想法。&lt;/p&gt;&lt;p&gt;如前所述，无论Visual Studio 2010还是Expression Blend都支持搭建Silverlight项目架构，而且能够共享打开同一个Silverlight项目，这就使开发人员和设计者可以各自并行负责各自的工作。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Eclipse&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Eclipse是一个用于Windows和Macintosh系统的流行的开发工具。Eclipse第一个由微软以外的供应商开发的可以用于创建Silverlight应用程序的代码编辑器。针对Silverlight的Eclipse工具可以在&lt;a href="http://www.eclipse4sl.org/"&gt;&lt;font color="#729773"&gt;http://www.eclipse4sl.org&lt;/font&gt;&lt;/a&gt;找到。Eclipse新建项目对话框显示了创建一个新的Silverlight项目的选项。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Silverlight 的语言&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Silverlight 3包含一个CLR运行环境，以及基于.NET Framework的类库子集。Silverlight 3中还扩展了JavaScript和标准浏览器脚本执行环境。&lt;/p&gt;&lt;p&gt;Silverlight 有三个版本：1.0、2.0、3.0。1.0版本中，只支持JavaScript。2.0版本中扩展了执行环境，并提供了使用更多高级语言设计Silverlight应用程序的功能。此外，2.0版本中不仅开辟了可以使用跟多语言的Silverlight CLR，而且允许语言之间通过动态语言运行时进行无缝通信。&lt;/p&gt;&lt;p&gt;一个动态的编程语言是指语言和语言的运行时可以用来在运行时动态扩展应用程度功能。例如，动态语言应该可以可以在程序运行时而不是编译时加载、编译以及运行代码。Silverlight的DLR可以使Silverlight利用动态语言的优势功能。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;JavaScript&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;JavaScript创建于20世纪90年代初，是网景公司和Sun公司共同努力的结果。JavaScript不是Java语言的子集，但是由于在创建时，Java语言比较受欢迎，所以JavaScript模仿了Java语言。JavaScript是一个完全动态的语言，包括许多面向对象的特性。尽管JavaScript很强大，但是.NET框架中的高级开发以及Silverlight 3，并不依赖于JavaScript。与其在Silverlight中使用JavaScript，不如使用更高级的.NET框架程序语言，还可以发挥Silverlight框架的全部优势。最流行的.NET框架下的编程语言是C#和Visual Basic。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;C#&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;C#是微软为创建.NET框架应用程序而定义的，原名为Visual C#.NET。C# 3.0是完全动态的语言，而且完全面向对象。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Visual Basic&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Visual Basic在20世纪90年代就已经出现了，当时作为BASIC语言和开发环境的改进版本。.NET框架中的Visual Basic已经完全被重新设计过，并被重新命名为Visual Basic.NET。从那时起，所有来自微软的.NET语言都放弃了&amp;#8220;.NET&amp;#8221;后缀。&lt;/p&gt;&lt;p&gt;Visual Basic目前是9.0版本，但它并不符合动态语言的要求。然而，正在制定的10.0版本，称作VBx，将是一个更精简的Visual Basic的动态版本，可以很好的支持Silverlight应用程序。VBx会随Visual Studio 2010一起发布。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;IronPython&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;IronPython是一个Python编程语言的动态版本，是微软设计出来用于.NET框架中的。Silverlight 3运行时支持使用IronPython。但是IronPython超出了我们这里讨论的范围。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;IronRuby&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;IronRuby是另一种微软设计出来应用于.NET框架的动态编程语言。Silverlight 3运行时也支持使用IronRuby。IronRuby编程语言同样超出了我们讨论的范围。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;集成Silverlight与ASP.NET AJAX&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;ASP.NET是Web开发中的领先技术，而且充分占据着市场。现在越来越多的ASP.NET应用程序开始部署Silverlight控件的集成，或者可以完全更新为Silverlight。微软意识到需要融合这两种开发技术并在ASP.NET 3.5扩展包中发布了一些Web计算功能和控件。&lt;/p&gt;&lt;p&gt;在微软ASP.NET 3.5扩展包中的一些新功能和技术，包含对ASP.NET、ASP.NET AJAX以及ADO.NET的集成的考虑，并开始在开发人员中进行适应性试验。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;asp:Silverlight 控件&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;使用Silverlight运行时中包含的泛型类可以加载、操作和管理XAML文件。ASP.NET 3.5扩展包已经包含了一些通用控件用来在ASP.NET AJAX 页面显示Silverlight XAML文件&amp;#8212;&amp;#8212;叫做Sytem.Web.UI.SilverlightControls.Silverlight 控件。asp:Silverlight控件可以加载并显示一个Silverlight XAML文件，然后就可以使用JavaScript或服务器端语言操作该XAML文件。&lt;/p&gt;&lt;p&gt;asp:Silverlight控件最终要的属性是Source属性。Source属性识别控件将要加载的XAML文件的名字，也可以选择包含宿主这个ASP.NET AJAX页面的路径相关信息。asp:Silverlight控件抛出三个最小的事件，其中一个是发生错误时触发，还有一个是XAML文件加载时触发。&lt;/p&gt;&lt;p&gt;当你要使用Visual Studio 2010创建一个新Silverlight项目时，如果添加Silverlight应用程序对话框中的&amp;#8220;添加一个新的ASP.NET Web项目到解决方案以宿主Silverlight&amp;#8221;选项被选中，那么Web 应用程序中就会创建一个ASP.NET AJAX页面来测试你的Silverlight内容。这个ASP.NET AJAX页面的名字与Silverlight应用程序名字相同，但是在名字中追加上了&amp;#8220;TestPage&amp;#8221;。 ASP.NET AJAX测试页使用asp:Silverlight控件创建，用来显示你的Silverlight内容。&lt;/p&gt;&lt;p&gt;asp:Silverlight控件可以通过从Visual Studio 2010工具箱中拖拽，轻易添加到现有的ASP.NET AJAX页面。通过拖拽到页面或者通过声明页面的标签来添加控件。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;动手实验室：将Silverlight集成到ASP.NET AJAX&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Silverlight的内容可以使用Visual Studio提供的控件，集成进现有的ASP.NET AJAX页面。可以遵循以下步骤：&lt;/p&gt;&lt;ul&gt;&lt;li&gt;1. 启动Visual&amp;nbsp; Studio 2010.&lt;br /&gt;2. 选择 文件|新建|项目，打开新建项目对话框.&lt;br /&gt;3. 在新建项目对话框左侧的.NET 框架编程语言下的Visual C#节点下，选择Silverlight节点.&lt;br /&gt;4. 在新建项目对话框右侧的项目模板列表中，选择Silverilght应用程序.&lt;br /&gt;5. 分配新建项目的名称，选择一个位置来存储新建的项目，然后单击确定按钮.&lt;br /&gt;6. 当提示新建Silverilght应用程序对话框时，单击确认按钮以接受默认设置.&lt;br /&gt;7. 打开Web项目中的ASP.NET AJAX测试页.&lt;br /&gt;8. 找到页面中的asp:Silverlight控件。注意页面顶端的@Register指令以及页面中的asp:ScriptManager控件。由于页面中加入了@Register指令，所以asp:Silverlight才可用。由于页面中添加了asp:ScriptManager控件，所以页面中才可以使用AJAX。&lt;br /&gt;9. 修改Silverlight项目中的MainPage.xaml文件的一些标记，例如，可以添加一个TextBlock控件.&lt;br /&gt;10. 按F5来测试应用程序并显示在ASP.NET AJAX页面的Silverlight控件中。如果提示启动项目调试，单击确定按钮.&lt;br /&gt;11. Silverlight 应该显示在ASP.NET AJAX页面中。然后可以关闭Visual&amp;nbsp; Studio.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;ASP.NET AJAX页面中包含的XAML案例如下，它使用了asp:Silverlight控件：&lt;/p&gt;&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;&lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #606060" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="background-color: #ffff00"&gt;&amp;lt;%@ Page Language="C#" AutoEventWireup="true" %&amp;gt;&lt;/span&gt;&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum2"&gt;   2:&lt;/span&gt;&amp;nbsp; &lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum3"&gt;   3:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;!&lt;/span&gt;&lt;span style="color: #800000"&gt;DOCTYPE&lt;/span&gt; &lt;span style="color: #ff0000"&gt;html&lt;/span&gt; &lt;span style="color: #ff0000"&gt;PUBLIC&lt;/span&gt; &lt;span style="color: #0000ff"&gt;"-//W3C//DTD XHTML 1.0 Transitional//EN"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum4"&gt;   4:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;html&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="http://www.w3.org/1999/xhtml"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum5"&gt;   5:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;head&lt;/span&gt; &lt;span style="color: #ff0000"&gt;runat&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="server"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum6"&gt;   6:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;title&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;SilverlightApplication In ASP.NET AJAX&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;title&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum7"&gt;   7:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;style&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="text/css"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum8"&gt;   8:&lt;/span&gt;     html, body {&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum9"&gt;   9:&lt;/span&gt;         height: 100%;&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum10"&gt;  10:&lt;/span&gt;         overflow: auto;&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum11"&gt;  11:&lt;/span&gt;     }&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum12"&gt;  12:&lt;/span&gt;     body {&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum13"&gt;  13:&lt;/span&gt;         padding: 0;&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum14"&gt;  14:&lt;/span&gt;         margin: 0;&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum15"&gt;  15:&lt;/span&gt;     }&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum16"&gt;  16:&lt;/span&gt;     #silverlightControlHost {&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum17"&gt;  17:&lt;/span&gt;         height: 100%;&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum18"&gt;  18:&lt;/span&gt;         text-align:center;&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum19"&gt;  19:&lt;/span&gt;     }&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum20"&gt;  20:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;style&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum21"&gt;  21:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;script&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="text/javascript"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;src&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Silverlight.js"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;script&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt;   1:&lt;/span&gt;&amp;nbsp; &lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum2"&gt;   2:&lt;/span&gt;     &amp;lt;script type=&lt;span style="color: #006080"&gt;"text/javascript"&lt;/span&gt;&amp;gt;&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum3"&gt;   3:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;function&lt;/span&gt; onSilverlightError(sender, args) {&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum4"&gt;   4:&lt;/span&gt;             &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; appSource = &lt;span style="color: #006080"&gt;""&lt;/span&gt;;&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum5"&gt;   5:&lt;/span&gt;             &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (sender != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; sender != 0) {&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum6"&gt;   6:&lt;/span&gt;               appSource = sender.getHost().Source;&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum7"&gt;   7:&lt;/span&gt;             }&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum8"&gt;   8:&lt;/span&gt;             &lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum9"&gt;   9:&lt;/span&gt;             &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; errorType = args.ErrorType;&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum10"&gt;  10:&lt;/span&gt;             &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; iErrorCode = args.ErrorCode;&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum11"&gt;  11:&lt;/span&gt;&amp;nbsp; &lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum12"&gt;  12:&lt;/span&gt;             &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (errorType == &lt;span style="color: #006080"&gt;"ImageError"&lt;/span&gt; || errorType == &lt;span style="color: #006080"&gt;"MediaError"&lt;/span&gt;) {&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum13"&gt;  13:&lt;/span&gt;               &lt;span style="color: #0000ff"&gt;return&lt;/span&gt;;&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum14"&gt;  14:&lt;/span&gt;             }&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum15"&gt;  15:&lt;/span&gt;&amp;nbsp; &lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum16"&gt;  16:&lt;/span&gt;             &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; errMsg = &lt;span style="color: #006080"&gt;"Unhandled Error in Silverlight Application "&lt;/span&gt; +  appSource + &lt;span style="color: #006080"&gt;"\n"&lt;/span&gt; ;&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum17"&gt;  17:&lt;/span&gt;&amp;nbsp; &lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum18"&gt;  18:&lt;/span&gt;             errMsg += &lt;span style="color: #006080"&gt;"Code: "&lt;/span&gt;+ iErrorCode + &lt;span style="color: #006080"&gt;"    \n"&lt;/span&gt;;&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum19"&gt;  19:&lt;/span&gt;             errMsg += &lt;span style="color: #006080"&gt;"Category: "&lt;/span&gt; + errorType + &lt;span style="color: #006080"&gt;"       \n"&lt;/span&gt;;&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum20"&gt;  20:&lt;/span&gt;             errMsg += &lt;span style="color: #006080"&gt;"Message: "&lt;/span&gt; + args.ErrorMessage + &lt;span style="color: #006080"&gt;"     \n"&lt;/span&gt;;&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum21"&gt;  21:&lt;/span&gt;&amp;nbsp; &lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum22"&gt;  22:&lt;/span&gt;             &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (errorType == &lt;span style="color: #006080"&gt;"ParserError"&lt;/span&gt;) {&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum23"&gt;  23:&lt;/span&gt;                 errMsg += &lt;span style="color: #006080"&gt;"File: "&lt;/span&gt; + args.xamlFile + &lt;span style="color: #006080"&gt;"     \n"&lt;/span&gt;;&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum24"&gt;  24:&lt;/span&gt;                 errMsg += &lt;span style="color: #006080"&gt;"Line: "&lt;/span&gt; + args.lineNumber + &lt;span style="color: #006080"&gt;"     \n"&lt;/span&gt;;&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum25"&gt;  25:&lt;/span&gt;                 errMsg += &lt;span style="color: #006080"&gt;"Position: "&lt;/span&gt; + args.charPosition + &lt;span style="color: #006080"&gt;"     \n"&lt;/span&gt;;&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum26"&gt;  26:&lt;/span&gt;             }&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum27"&gt;  27:&lt;/span&gt;             &lt;span style="color: #0000ff"&gt;else&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (errorType == &lt;span style="color: #006080"&gt;"RuntimeError"&lt;/span&gt;) {           &lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum28"&gt;  28:&lt;/span&gt;                 &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (args.lineNumber != 0) {&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum29"&gt;  29:&lt;/span&gt;                     errMsg += &lt;span style="color: #006080"&gt;"Line: "&lt;/span&gt; + args.lineNumber + &lt;span style="color: #006080"&gt;"     \n"&lt;/span&gt;;&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum30"&gt;  30:&lt;/span&gt;                     errMsg += &lt;span style="color: #006080"&gt;"Position: "&lt;/span&gt; +  args.charPosition + &lt;span style="color: #006080"&gt;"     \n"&lt;/span&gt;;&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum31"&gt;  31:&lt;/span&gt;                 }&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum32"&gt;  32:&lt;/span&gt;                 errMsg += &lt;span style="color: #006080"&gt;"MethodName: "&lt;/span&gt; + args.methodName + &lt;span style="color: #006080"&gt;"     \n"&lt;/span&gt;;&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum33"&gt;  33:&lt;/span&gt;             }&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum34"&gt;  34:&lt;/span&gt;&amp;nbsp; &lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum35"&gt;  35:&lt;/span&gt;             &lt;span style="color: #0000ff"&gt;throw&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Error(errMsg);&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum36"&gt;  36:&lt;/span&gt;         }&lt;!--CRLF--&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;script&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum22"&gt;  22:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;head&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum23"&gt;  23:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;body&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum24"&gt;  24:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;form&lt;/span&gt; &lt;span style="color: #ff0000"&gt;id&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="form1"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;runat&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="server"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;style&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="height:100%"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum25"&gt;  25:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;div&lt;/span&gt; &lt;span style="color: #ff0000"&gt;id&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="silverlightControlHost"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum26"&gt;  26:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;object&lt;/span&gt; &lt;span style="color: #ff0000"&gt;data&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="data:application/x-silverlight-2,"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="application/x-silverlight-2"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;width&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="100%"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;height&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="100%"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum27"&gt;  27:&lt;/span&gt;           &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;param&lt;/span&gt; &lt;span style="color: #ff0000"&gt;name&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="source"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;value&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="ClientBin/SilverlightApplicationInASPNETAJAX.xap"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum28"&gt;  28:&lt;/span&gt;           &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;param&lt;/span&gt; &lt;span style="color: #ff0000"&gt;name&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="onError"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;value&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="onSilverlightError"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum29"&gt;  29:&lt;/span&gt;           &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;param&lt;/span&gt; &lt;span style="color: #ff0000"&gt;name&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="background"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;value&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="white"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum30"&gt;  30:&lt;/span&gt;           &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;param&lt;/span&gt; &lt;span style="color: #ff0000"&gt;name&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="minRuntimeVersion"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;value&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="3.0.40818.0"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum31"&gt;  31:&lt;/span&gt;           &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;param&lt;/span&gt; &lt;span style="color: #ff0000"&gt;name&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="autoUpgrade"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;value&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="true"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum32"&gt;  32:&lt;/span&gt;           &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;a&lt;/span&gt; &lt;span style="color: #ff0000"&gt;href&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="http://go.microsoft.com/fwlink/?LinkID=149156&amp;amp;v=3.0.40818.0"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;style&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="text-decoration:none"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum33"&gt;  33:&lt;/span&gt;                &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;img&lt;/span&gt; &lt;span style="color: #ff0000"&gt;src&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="http://go.microsoft.com/fwlink/?LinkId=161376"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;alt&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Get Microsoft Silverlight"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;style&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="border-style:none"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum34"&gt;  34:&lt;/span&gt;           &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;a&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum35"&gt;  35:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;object&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;iframe&lt;/span&gt; &lt;span style="color: #ff0000"&gt;id&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="_sl_historyFrame"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;style&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="visibility:hidden;height:0px;width:0px;border:0px"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;iframe&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;div&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum36"&gt;  36:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;form&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum37"&gt;  37:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;body&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum38"&gt;  38:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;html&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;!--CRLF--&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;此案例的显示结果如下，虽然包含的内容不多，但是它明确说明了如何使用asp:Silverlight控件。&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/Silverlight_EF6D/image_22.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/Silverlight_EF6D/image_thumb_3.png" width="644" height="199" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;&lt;strong&gt;Figure 3-8 使用asp:Silverlight控件在ASP.NET AJAX页面中显示简单的Silverlight内容&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;asp:MediaPlayer 控件&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;使用asp:mediaPlayer控件，ASP.NET AJAX应用程序中可以很容易的包含音频、视频和媒体内容。asp:MediaPlayer控件控件包含在ASP.NET扩展包中。asp:MediaPlayer控件目的就是集成Silverlight的音频和视频功能。使用asp:MediaPlayer控件的好处是可以集成Silverlight音频和视频，而不需要开发人员具有XAML或JavaScript的知识。asp:MediaPlayer控件允许快速集成Silverlight到ASP.NET或ASP.NET AJAX应用程序，使开发人员可以用更多的精力去开发新的功能和技术。&lt;/p&gt;&lt;p&gt;asp:MediaPlayer控件现在支持Windows 视频（WMV）、Windows Media Audio（WMA）、以及MP3格式的媒体。asp:MediaPlayer控件可以抛出JavaScript的事件。另外，asp:MediaPlayer 控件可以包含显示并导航不同的媒体文件，以及自定义的导航界面。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;创建Silverlight应用程序&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;虽然现有的应用程序可以集成Silverlight内容和媒体，大多数情况下，详尽的Silverlight应用程序应该是以新Silverlight应用程序的方式创建的。Silverlight 应用程序可以使用Visual&amp;nbsp; Studio 2010或Expression Blend；然而，Visual Studio 2010可以在创建虚拟的项目时提供更多选择。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Silverlight 项目&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;创建Silverlight应用程序的第一步是创建一个新的Silverlight项目。下图显示了Visual Studio 2010中的新建Silverlight项目对话框。&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/Silverlight_EF6D/image_20.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/Silverlight_EF6D/image_thumb.png" width="644" height="398" /&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Figure 3-9 Visual Studio 2010中的新建项目对话框中的新建Silverlight界面&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;下图显示了Expression Blend中的新建项目对话框&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/Silverlight_EF6D/image_24.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/Silverlight_EF6D/image_thumb_9.png" width="599" height="484" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;&lt;strong&gt;Figure 3-10 Expression Blend中的新建项目对话框中的新建Silverlight项目界面&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;当使用Visual Studio 2010新建项目对话框时，另一个对话框会提示你需要配置另外一个项目信息，而这个提示在Expression Blend中是没有的。下面是这个提示对话框的界面：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/Silverlight_EF6D/image_26.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/Silverlight_EF6D/image_thumb_10.png" width="600" height="484" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;&lt;strong&gt;Figure 3-11 Visual Studio 2010中的新建Silverlight应用程序对话框&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;下面是这个对话框中选项的解释：&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&amp;#9679; &lt;strong&gt;在一个新的网站中宿主Silverlight应用程序&lt;/strong&gt; 这是最常用的选项。它将在Silverlight应用程序之外，创建一个ASP.NET AJAX的Web项目。ASP.NET AJAX的Web项目创建后会作为Silveright应用程序的测试工具。Silverlight内容宿主在一个HTML或ASP.NET页面中。这个选项指示Visual Studio创建一个Silverlight应用程序的测试，而且开发人员还可以修改这个测试页面。&lt;/li&gt;&lt;li&gt;注意：测试工具是一个用来测试另一个应用程序部分功能的项目或文件。ASP.NET AJAX的Web项目创建了一个新的Silverlight项目，这个项目就包含了用来显示和测试你的Silverlight内容的文件。因此，新的Web应用程序就作为Silverlight应用程序的测试工具。&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;添加Silverlight应用程序对话框中的其他选项，取决于在第一个对话框中的选择。项目类型下拉列表中提供了可供选择的创建一个Web站点或一个Web应用程序。最后，在名称文本框中可以修改新网站的名字或使用默认名字。&lt;/p&gt;&lt;p&gt;当此项被选中后，解决方案浏览器中会出现两个项目。如下图所示； &lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/Silverlight_EF6D/image_28.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/Silverlight_EF6D/image_thumb_11.png" width="472" height="484" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;&lt;strong&gt;Figure 3-12 Visual Studio 2010 解决方案浏览器中的一个新建的Silverlight 应用程序和一个 web 应用程序测试工具项目（上面一个是Silverlight应用程序；下面一个是Web测试工具项目）&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;上图中第一个项目是Silverlight测试工具Web项目，第二个项目是Silverlight应用程序。在Silverlight应用程序中，我们这次关心的文件时MainPage.xaml文件和相关代码后置文件，MainPage.xaml.cs。MainPage.xaml文件默认使用Visual Studio 2010 编辑。与Silverlight 2不同的是，使用Visual Studio 2010创建的Silverlight 3应用程序，必须通过XAML直接编辑和创建。当然也可以使用Expression Blend来创建和编辑Silverlight应用程序。Visual Studio 2010创建的Silverlight应用程序可以使用Expression Blend轻松打开。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;动手实验室：&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;使用Expression Blend打开新的Silverlight XAML文件&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;虽然Silverlight的XAML文件可以使用编程的方式进行设计，还可以使用集成在Visual Studio中的设计器进行设计，但是最方便的XAML设计工具，仍然是Expression Blend。&lt;/p&gt;&lt;ul&gt;&lt;li&gt;1. 在Visual Studio 2010中打开Silverlight 项目，在解决方案浏览器中右键单击Silverlight项目中的MainPage.xaml文件。&lt;br /&gt;2. 在弹出的菜单中，选择在Expression Blend中打开。此时会显示一个安全提示对话框。&lt;br /&gt;3. MainPage.xaml 文件是我们主动从Visual Studio 2010中打开的，因此我们在安全提示对话框中选择是。MainPage.xaml就会在Expression Blend中打开。效果如下图所示.&lt;/li&gt;&lt;li&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/Silverlight_EF6D/image_30.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/Silverlight_EF6D/image_thumb_12.png" width="644" height="372" /&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Figure 3-13 在Expression Blend中显示的Silverlight XAML &lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;设计Silverlight XAML&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;这里我们会创建一个与大多数语言相类似的简单的客户响应应用程序。创建的步骤如下所示：&lt;/p&gt;&lt;ul&gt;&lt;li&gt;1. 使用Expression Blend打开MainPage.xaml文件后，从互动选项卡中打开对象与时间线面板.，选择LayoutRoot节点。&lt;br /&gt;2. 使用属性选项卡标签中的画笔面板根据你自己的喜好来配置背景。例如，你可以使用渐变背景来填充.&lt;br /&gt;3. 从Blend左侧的垂直工具箱中, 拖拽一个 TextBox 控件到 Silverlight 设计界面上.&lt;br /&gt;4. 定位TextBox 控件到设计界面的顶部.&lt;br /&gt;5. 在属性选项卡顶部的名称属性中输入控件名称，如txtName，为TextBox控件指定名称.&lt;br /&gt;6. 选中这个新拖拽的TextBox控件，在属性选项卡中，删除Text属性中的字符串&amp;#8220;TextBox&amp;#8221;.&lt;br /&gt;7. 从工具箱中，拖拽一个Button控件到Silverlight设计界面.&lt;br /&gt;8. 将按钮放置到TextBox控件的右侧，并为Button控件分配名称，如btnDisplayname，在属性选项卡顶部的名称属性文本框中输入即可.&lt;br /&gt;9. 选中这个新拖拽的Button控件，在属性选项卡中将内容属性中的字符串&amp;#8220;Button&amp;#8221;修改为&amp;#8220;Display Name&amp;#8221;.&lt;br /&gt;10. 从工具箱中拖拽一个TextBlock控件到Silverlight设计界面.&lt;br /&gt;11. 将TextBlock控件放置在TextBox控件和Button控件的下方，并为TextBlock控件分配名称，如tbName.&lt;br /&gt;12. 选中这个TextBlock控件，在属性选项卡中删除Text属性文本框中的字符串&amp;#8220;TextBlock&amp;#8221;。完整的XAML设计效果如下图所示.&lt;/li&gt;&lt;li&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/Silverlight_EF6D/image_32.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/Silverlight_EF6D/image_thumb_13.png" width="644" height="373" /&gt;&lt;/a&gt;&amp;nbsp;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Figure 3-14 在Expression Blend中，XAML设计完成后的效果&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;编写事件处理程序&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;为了使Button控件执行活动，必须了解何时活动会触发。每个控件都包含一系列与控件一同初始化的活动。在常见用户界面事件中，单击事件是最常用的。一旦触发事件，则系统会转向代码中，引用事件处理程序，并执行事件响应。&lt;/p&gt;&lt;p&gt;事件处理程序可以通过多种方式绑定到Silverlight控件：&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&amp;#9679; 如果使用Visual Studio 2010，你可以直接在代码后置文件中创建事件处理程序，并将事件处理程序绑定到已有的控件事件上。另外，当你试图绑定一个事件代码到事件处理器上时，事件代码不存在，那么事件处理器可以动态创建事件代码.&lt;br /&gt;&amp;#9679; 如果使用Expression Blend, 你可以选择要创建事件处理的控件，然后在属性选项卡的事件面板中，双击期望的事件处理程序. Expression Blend就会为选定的控件事件创建事件处理程序代码.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;下面显示了事件处理的代码：&lt;/p&gt;&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;&lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #606060" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System;&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum2"&gt;   2:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum3"&gt;   3:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Linq;&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum4"&gt;   4:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Net;&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum5"&gt;   5:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Windows;&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum6"&gt;   6:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Windows.Controls;&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum7"&gt;   7:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Windows.Documents;&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum8"&gt;   8:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Windows.Input;&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum9"&gt;   9:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Windows.Media;&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum10"&gt;  10:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Windows.Media.Animation;&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum11"&gt;  11:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Windows.Shapes;&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum12"&gt;  12:&lt;/span&gt;&amp;nbsp; &lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum13"&gt;  13:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;namespace&lt;/span&gt; MyFirstSilverlightApplication&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum14"&gt;  14:&lt;/span&gt; {&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum15"&gt;  15:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;partial&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; MainPage : UserControl&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum16"&gt;  16:&lt;/span&gt;     {&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum17"&gt;  17:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; MainPage()&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum18"&gt;  18:&lt;/span&gt;         {&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum19"&gt;  19:&lt;/span&gt;             InitializeComponent();&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum20"&gt;  20:&lt;/span&gt;         }&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum21"&gt;  21:&lt;/span&gt;&amp;nbsp; &lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum22"&gt;  22:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; btnDisplayName_Click(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender, System.Windows.RoutedEventArgs e)&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum23"&gt;  23:&lt;/span&gt;         {&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum24"&gt;  24:&lt;/span&gt;             &lt;span style="color: #008000"&gt;// TODO: Add event handler implementation here.&lt;/span&gt;&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum25"&gt;  25:&lt;/span&gt;             tbName.Text = txtName.Text;&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum26"&gt;  26:&lt;/span&gt;         }&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum27"&gt;  27:&lt;/span&gt;     }&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum28"&gt;  28:&lt;/span&gt; }&lt;!--CRLF--&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;运行效果如下图所示：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/Silverlight_EF6D/image_36.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/Silverlight_EF6D/image_thumb_15.png" width="644" height="264" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;&lt;strong&gt;Figure 3-15 示例程序的显示效果&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Silverlight项目的结构&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;当你使用Visual Studio 创建一个新的Silverlight项目时，你会选择在一个新的Web网站中宿主Silverlight应用程序，然后就会创建两个项目。一个项目包含真正的Silverlight应用程序，另一个项目作为测试Silverlight应用程序的服务器项目。当你使用Expression Blend创建一个项目时，这个测试站点会自动创建，但是它远没有使用Visual Studio 2010创建的测试Web应用程序强大。&lt;/p&gt;&lt;p&gt;一个Silverlight应用程序包含很多Silverlight文件。默认情况下，每个Silverlight的XAML文件都会紧跟一个类文件作为代码后置文件。微软使用与ASP.NET相同的基础结构来设计Silverlight，而且还融入了很多微软.NET开发技术，如WPF。Silverlight控件是由一个包含XAML标签的文件和一个单独包含代码或隐藏代码的类文件组成（通常使用的是C#或VB）。无论用哪个工具创建Silverlight项目，当Silverlight应用程序生成调试时，代码后置文件会被编译进一个程序集（.dll文件），而且所有XAML文件和程序集文件被压缩到一个.xap扩展名的文件中（发音zap）。XAP文件会被部署到宿主的Web服务器上。图3-12已经显示了这种架构特点。&lt;/p&gt;&lt;p&gt;注意，在测试项目中生成了三个Web页面。Default.aspx页面在测试项目中内有用到。然而，两个与Silverlight同名的ASP.NET页面和HTML页面确用到了。HTML页面使用&amp;lt;object&amp;gt;元素包含Silverlight控件，而ASP.NET页面使用&amp;lt;asp:Silverlight&amp;gt;元素包含Silverlight控件。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;创建一个简单的Silverlight动画&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;使用Silverlight创建动画是一个简单的过程，但是它取决于你心里的动画创意。Silverlight动画可以使用Visual Studio 2010的编码或XAML设计来完成。然而，创建Silverlight动画的首选工具是Expression Blend。作为入门案例的一个标准的，简单的动画就是旋转的圆圈（就像在Windows 7中需要长时间等待时，出现的效果）。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;动手实验室：创建一个简单的Silverlight动画&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;使用Expression Blend创建Silverlight动画很容易，步骤如下：&lt;/p&gt;&lt;ul&gt;&lt;li&gt;1. 启动 Visual Studio 2010. 选择 文件 | 新建 | 项目 打开新建项目对话框.&lt;br /&gt;2. 在新建项目对话框中左侧的项目模板面板中，选定的.NET Framework编程语言下选择Silverlight节点.&lt;br /&gt;3. 在新建项目对话框右侧的模板面板中选择Silverlight应用程序.&lt;br /&gt;4. 为新项目分配名称，如SilverlightApplicationSpinningCircle，选定一个位置来创建新的项目，然后单击确定按钮.&lt;br /&gt;5. 当出现新建Silverlight应用程序提示时，单击确定按钮以接受默认值.&lt;br /&gt;6. 在解决方案浏览器中右键单击Silverlight项目中的MainPage.xaml文件.&lt;br /&gt;7. 在弹出的菜单中选择使用Expression Blend打开。MainPage.xaml文件会显示在Expression Blend中.&lt;br /&gt;8. 从Blend左侧的工具箱中，拖拽一个椭圆，放置在Silverlight设计界面中.&lt;br /&gt;9. 选中这个椭圆，使用属性选项卡中的画笔工具，进行透明填充.&lt;br /&gt;10. 从属性选项卡中，设置StrokeThickness值为20或更大，并采用线性梯度过度。XAML设计效果如下所示：&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/Silverlight_EF6D/image_34.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/Silverlight_EF6D/image_thumb_14.png" width="644" height="371" /&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Figure 3-16 在Expression Blend中对椭圆的设置&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;注意：在Expression Blend中设置椭圆大小时, 为了保持一个正圆, 可以按住Shift键，再调整.&lt;br /&gt;11. 在对象和时间线面板上，单击添加按钮来创建一个新的故事情节。此时创建故事情节资源对话框会出现，如下图所示：&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/Silverlight_EF6D/image_38.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/Silverlight_EF6D/image_thumb_16.png" width="644" height="254" /&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Figure 3-17 使用Expression Blend创建新的故事情节&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;12. 为故事情节制定名称为sbSpin，然后单击确定. &lt;br /&gt;13. 在时间轴上选择一个点，以某种方式修改椭圆。这个例子中，选择时间轴上2秒的点，然后使用鼠标抓住椭圆的一角，并旋转数次.&lt;br /&gt;14. 你可以通过点击时间轴面板上的播放按钮来测试动画效果.&lt;br /&gt;15. 如果这个动画应该制定一个名称或应该永远循环，在Expression Blend中选择时间表，在属性面板中为故事情节指定一个名称或设置RepeatBehavior为&amp;#8220;永远&amp;#8221;。&lt;br /&gt;16. 保存页面效果、关闭Expression Blend，然后返回Visual Studio 2010. &lt;br /&gt;注意：为了让动画开始，你必须调用故事情节的Begin方法。为了调用故事情节的Begin方法，你需要为故事情节指定一个名称。假如故事情节已经在Expression Blend中指定了名称，Begin方法就可以从Silverlight的代码后置文件中调用。然而，调用Begin方法，还必须触发一个XAML文件元素的时间处理程序。如果需要动画从启动加载XAML文件时立刻开始就执行，那么需要在Loaded事件中调用.&lt;br /&gt;17. 要轻松创建一个新的事件处理程序，并将它绑定到XAML Loaded事件上，可以在Visual Studio 中打开XAML文件并定位到顶端的&amp;lt;UserControl&amp;gt;文档元素定义的末尾. 在右括号内按空格键来显示智能成员提示选择器并选中Loaded.按等号键以定义一个新的事件处理程序。&lt;br /&gt;18. 用鼠标单击 Silverlight XAML 设计界面 然后选择查看代码.&lt;br /&gt;19. 找到新创建的事件处理程序，然后添加对故事情节的Begin方法的调用，如下面代码所示:&lt;/li&gt;&lt;li&gt;&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;&lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #606060" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; UserControl_Loaded(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender, RoutedEventArgs e){&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum2"&gt;   2:&lt;/span&gt;     sbSpin.Begin();&lt;!--CRLF--&gt;&lt;span style="color: #606060" id="lnum3"&gt;   3:&lt;/span&gt; }&lt;!--CRLF--&gt;&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;运行结果如下图所示：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/Silverlight_EF6D/image_40.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/Silverlight_EF6D/image_thumb_17.png" width="458" height="484" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;&lt;strong&gt;Figure 3-26 一个简单的 Silverlight 动画&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;结论&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;对于熟悉.NET的开发人员来说，创建Silverlight应用程序非常容易，但是开发ASP.NET应用程序与开发Silverlight应用程序有着显著的不同。由于ASP.NET已经被广泛使用而且已被证明是稳定的和成功的，所以微软为了让开发人员更容易更快速的创建Silverlight应用程序，采用了与设计ASP.NET相同的设计架构。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/Phoenix-Rock/aggbug/1793196.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/Phoenix-Rock/archive/2010/08/05/Silverlight_2.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/Phoenix-Rock/archive/2010/08/05/Silverlight.html</id><title type="text">Silverlight 介绍(转)</title><summary type="text">Silverlight 介绍 </summary><published>2010-08-05T06:35:00Z</published><updated>2010-08-05T06:35:00Z</updated><author><name>天马行空（笨笨）</name><uri>http://www.cnblogs.com/Phoenix-Rock/</uri></author><link rel="alternate" href="http://www.cnblogs.com/Phoenix-Rock/archive/2010/08/05/Silverlight.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/Phoenix-Rock/archive/2010/08/05/Silverlight.html"/><content type="html">&lt;div class="postTitle"&gt;Silverlight是一个构建丰富客户体验、基于浏览器的应用程序，并使其能够运行在多种操作系统之上的开发框架。Silverlight通过浏览器插件发挥他魔幻的效果。当你访问一个带有一些Silverlight内容的网页时，浏览器的插件就会运行这些代码，并将这些效果呈现在一个特定的区域内。重要的是，Silverlight插件提供了比传统的交互方法，如HTML和JavaScript，更丰富的运行环境。合理而巧妙的使用Silverlight技术，你可以创建包含互操作图形、各种动画效果以及音频文件的Silverlight页面。&lt;/div&gt;&lt;p&gt;如果这些听起来有些熟悉，那是因为同样的技巧已经存在。许多其他的技术也在使用浏览器插件来扩展浏览器的功能范围，包括Java，ActiveX等，以及（最成功）Adobe Flash。虽然这些技术都正在使用过程中，但是他们都没有成为独立的、整合的丰富用户体验的开发平台。他们也遇到了很多问题，如头疼的安装、简陋的开发工具以及无法满足所有浏览器和操作系统。而能够解决这些问题的技术只有Flash，所以它拥有优秀的跨平台支持和广泛的应用。然而，最近Flash从一个多媒体播放器演变为了一系列动态程序设计工具。但是它依然无法提供像现代编程环境.NET这样的广泛功能。&lt;/p&gt;&lt;p&gt;这就正好是Silverlight适合的切入点。Silverlight的目的是结合Flash提供的现有的能力和跨平台支持，再加上一流的集成基本理论的程序设计平台.NET。目前，Flash依然因为它的普及和成熟得到广泛的应用。然而，Silverlight具有很多Flash满足不了的架构和功能&amp;#8212;&amp;#8212;最重要的是，事实上它基于一个规模较小的.NET通用语言运行时环境，而且允许开发者使用纯C#编写客户端代码。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;理解Silverlight&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Silverlight使用了一个熟悉的技术来超越标准网页的功能：一个轻量级的浏览器插件。插件模式的优势是用户只需要安装一个组件，就可以看到由不同人和公司开发出来的内容。安装这个插件要求很少的下载量，并强制用户在一个安全的对话框中确认操作。它只需要很短的时间。但是一旦安装该插件，浏览器可以无缝的处理任何Silverlight内容，而不会再有进一步的提示。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;：Silverlight是为了克服普通的HTML限制，允许开发人员创建更多的图形和交互式应用程序。但是，Silverlight的开发人员目前无法摆脱浏览器的安全沙箱。大多数情况下，Silverlight应用程序被限制以访问普通网页同样的方式执行。例如，一个Silverlight应用程序允许创建和访问文件，但是这些文件却被存储在一个特殊包围的分割区域。理论上说，分割的存储区域如普通网页中的Cookies。文件被网站和当前用户分割存储，而且大小有限制。&lt;/p&gt;&lt;p&gt;下图显示了两个包含Silverlight内容的页面。上面一张图中你看到没有安装Silverlight插件的效果。此时，你可以点击&amp;#8220;获取微软Silverlight &amp;#8221;图片来导航到微软的网站，在那里你可以按照提示安装该插件，接下来就可以返回原页面。下面一张图你会看到安装Silverlight插件之后的效果。&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/Silverlight2_F27C/image_2.png"&gt;&lt;img style="border-right-width: 0px; width: 466px; display: inline; border-top-width: 0px; border-bottom-width: 0px; height: 170px; border-left-width: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/Silverlight2_F27C/image_thumb.png" width="466" height="170" /&gt;&lt;/a&gt; &lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/Silverlight2_F27C/image_4.png"&gt;&lt;img style="border-right-width: 0px; width: 466px; display: inline; border-top-width: 0px; border-bottom-width: 0px; height: 425px; border-left-width: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/Silverlight2_F27C/image_thumb_1.png" width="466" height="425" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;&lt;strong&gt;Silverlight VS Flash&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;大多数成功的浏览器都安装有Adobe Flash插件。Flash已经具有十余年的发展历程。它开始时是作为一种添加动画图形的简单工具，后来逐渐演变为一个开发交互式内容的平台。&lt;/p&gt;&lt;p&gt;.NET开发人员使用Flash内容来创建网站是完全合理的。但是，这样做就需要一个独立的设计工具和一种完全不同的编程语言（ActionScript）以及编程环境（Flex）。此外，没有直接的方法能使用.NET服务端代码集成Flash内容。例如，创建调用.NET组件的Flash应用程序是非常尴尬的做法。使用服务端代码来呈现Flash内容（如在一个自定义的ASP.NET控件中弹出一个Flash内容区）就更困难的多。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;：有一些第三方的解决方案可以帮助我们打破ASP.NET和Flash之间存在的屏障。其中一个例子是引入SWFSource.NET（&lt;a href="http://www.activehead.com/SWFSource.aspx"&gt;&lt;font color="#729773"&gt;http://www.activehead.com/SWFSource.aspx&lt;/font&gt;&lt;/a&gt;），它提供了一系列.NET类以允许你动态生成Flash（.swf）文件。然而，这些工具都作用在较低层。他们远远不能全面发展成为一个平台。&lt;/p&gt;&lt;p&gt;Silverlight的目的是给.NET开发人员提供一套更好的创建丰富Web内容的选择。Silverlight提供一个很像Flash特点的浏览器插件，但是它根本上是为.NET设计的。Silverlight本身就支持C#语言以及.NET所涵盖的范围。因此，开发人员可以编写为Silverlight编写客户端代码，就像他们编写服务端代码时一样（如C#和VB），而且可以使用很多抽象技巧（包括流、控件、集合、泛型以及LINQ）。&lt;/p&gt;&lt;p&gt;Silverlight插件有一个令人印象深刻的功能，其中一些共享功能就像Flash一样普通，然而一些全新的功能是革命性的。这里列举一些重点：&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;2-D绘图&lt;/strong&gt;。Silverlight提供丰富的2D绘图模式。最重要的是，你所画的内容是以图形和路径的形式定义的，所以你可以在客户端操作这些内容。你甚至可以响应事件（像鼠标在一个图形上点击），这样就很容易添加一个可交互图形到任何地方。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;控件&lt;/strong&gt;。开发人员不想从最基础的重新做起，所以Silverlight保留了很多传统而集成的功能，包括按钮，文本框，列表和表格。最重要的是，如果你想要他们的功能，而不需要他们外观，那么这些基本组成模块儿可以重新自定义样式。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;动画&lt;/strong&gt;。Silverlight有一个机遇时间的动画模式，可以让你定义该发生什么效果以及这个效果持续多长时间。Silverlight插件会处理微笑的细节，比如插值计算中间值和帧速率。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;媒体&lt;/strong&gt;。Silverlight提供了Windows Media Audio（WMA）、Windows Media Video（WMV7-9），MP3音频和VC-1（支持高清晰度视频）的播放组件。你还没有安装Windows Media Player ActiveX控件和浏览器插件，而你就可以创建任何你想要的前端效果，你甚至可以以全屏模式显示视频。微软还提供了免费的组件宿主服务（在&lt;a href="http://silverlight.live.com/"&gt;&lt;font color="#729773"&gt;http://silverlight.live.com&lt;/font&gt;&lt;/a&gt;），让你的控件可以存储媒体文件。目前，它提供大概10G空间。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;通用语言运行时&lt;/strong&gt;。最令人印象深刻的是，Silverlight包括一个简化版的CLR。它具有一系列核心类，一个垃圾回收器，一个即时编译器，支持泛型、线程等等。在许多情况下，开发人员可以针对整个.NET CLR编写代码，并且只需要少量的变化就可以在Silverlight应用程序中使用它。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;网络&lt;/strong&gt;。Silverlight应用程序可以调用传统样式的ASP.NET Web服务（.asmx）或WCF（Windows Communication Foundation）Web服务。他们还可以通过HTTP发送自定义创建的XML请求，甚至直接打开socket进行快速的双向通信。这就给了开发人员一个强大的方式使用安全的服务端代码规则来组建丰富的客户端体验代码。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;数据绑定&lt;/strong&gt;。虽然Silverlight的功能不比WPF强大多少，但是，Silverlight数据绑定提供了一个方便的方法，使用少量的代码就可以展示大量的数据。你可以从XML或一个内存对象中提取数据，使你能够调用Web服务，接收一个对象集合，并显示在Web网页中&amp;#8212;&amp;#8212;往往只需要两行代码即可。&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;当然，同样要注意Silverlight不包括什么。Silverlight是一项迅速发展的新的技术。它对于那些使用基于.NET中包含丰富预编译方法的开发库的开发人员来说是一块儿绊脚石。其中突出的差距包括缺乏数据库支持（没有ADO.NET），缺乏3D绘图支持，没有打印，没有指令模型，以及并不太多的像树形控件、菜单这样的丰富客户体验的控件（虽然许多开发者以及提供商都分别构建了各自的类似控件）。所有这些特点都可以在基于Windows的WPF应用程序中找到。当然这些控件也许有一天肯定也会迁移到Silverlight的范围内。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Silverlight 1和2&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Silverlight存在三个版本，这里先简单介绍1和2两个版本：&lt;/p&gt;&lt;ul&gt;&lt;li&gt;第一个版本，Silverlight 1，是一个较简单的技术。它包括2-D绘图功能和媒体播放功能。然而，它不包含CLR引擎以及对.NET语言的支持，因此任何编写的代码必须使用javaScript。&lt;/li&gt;&lt;li&gt;第二个版本，Silverlight 2，增加了.NET引擎，并已经经过很多开发人员的试用。它包括CLR，一个.NET框架类库的子集，以及一个基于WPF的用户界面模型。&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;许多开发人员认为Silverlight 2 才是真正的第一个版本的Silverlight平台。&lt;/p&gt;&lt;p&gt;注意，现在Silverlight只是电脑应用中的一小部分。然而，微软相信如果Silverlight做出引人注目的内容，那么用户将会下载Silverlight插件。有许多因素支持这一观点。Flash已经在短时间内大幅成长，而且微软已经有很多其他大小不等的基于Web的应用程序在广泛使用，并获得了成功的经验。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Silverlight 与 WPF&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Silverlight有趣的地方是它借用了WPF的模型来实现丰富的客户端用户体验。&lt;/p&gt;&lt;p&gt;WPF是下一代Windows应用程序创建技术。它是.NET 3.0中一项成功的Windows窗体技术。WPF值得关注的不仅仅是简化了一系列功能强大的高端的开发技巧，而且它还通过DirectX管道渲染所有东西来提高性能。&lt;/p&gt;&lt;p&gt;Silverlight显然不能复制WPF的特点，因为许多特点都深度依赖于操作系统的功能，包括Windows 特定的显示程序和DirectX技术。然而，Silverlight并不是为客户端技术开发一套全新的完整的控件和类库，而是使用一套WPF模型的子集。如果你有使用WPF的经验，你会惊讶的发现Silverlight其实是WPF技术亲密的兄弟。明显的特点如下：&lt;/p&gt;&lt;ul&gt;&lt;li&gt;要定义一个Silverlight用户界面（一个Silverlight内容区域内的一系列元素集合），你可以使用XAML标记，就像你使用WPF一样。你甚至可以试用相同的数据绑定语法来定位数据的显示。&lt;/li&gt;&lt;li&gt;Silverlight借用了很多与WPF中相同的基础控件，相同的样式系统（为了规范和格式重用），以及相似的模板机制（用来改变标准控件的外观）。&lt;/li&gt;&lt;li&gt;为了在Silverligt中绘制2-D图形，你可以使用形状、路径、变形、几何形状以及刷。所有这些都与WPF相一致。&lt;/li&gt;&lt;li&gt;Silverlight提供一种基于故事板的声明形式的动画模式，这也和WPF中的动画系统相一致。&lt;/li&gt;&lt;li&gt;要显示或播放视频音频文件，使用MediaElement类，就像你在WPF中的一样。&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;注意：WPF没有完全切断易于部署的Web方式。WPF中允许开发人员创建基于浏览器宿主的称为XBAPs（XAML Browser Applications）应用程序。这些应用程序可以无缝下载，缓存在本地，以及直接在浏览器中运行，而没有任何安全提示。然而，尽管XBAPs运行在IE和Firefox中，他们仍然只是Windows平台的技术，而不想Silverlight。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Silverlight的局限&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Silverlight可以很好的媲美任何基于浏览器的技术，它具有丰富，完整地功能模型和一些明显的创新。然而，Silverlight不能提供像WPF这样专著于客户端技术的所有丰富客户体验。WPF的设计目的是为Windows平台和明确的DirectX库。&lt;/p&gt;&lt;p&gt;以下是WPF中的一些你现在还无法实现的功能：&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;3-D图形&lt;/strong&gt;。你可以使用Silverlight提供的2-D绘图方法来绘制3-D图形。然而，这就留给你大量的自定义代码要写，以及大量的风险。真正的3-D绘图的支持，就像WPF中提供的，需要像旋转、灯光、阻塞以及单击测试。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;硬件加速&lt;/strong&gt;。Silverlight将永远达不到WPF的速度，因为它是为广泛的兼容性而设计的，而不是本地硬件。但是，它的表现仍然令人印象深刻，它对其他浏览器技术，如Flash，是严重的挑战。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;文档&lt;/strong&gt;。WPF有一个显示大量文本内容的流模型，它使用智能的行识别和理解算法。而Silverlight没有。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;打印&lt;/strong&gt;。Silverlight不提供任何方式让您使用客户端的打印机。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;命令&lt;/strong&gt;。WPF使用一个命令模型，允许你定义更高级的任务来激发不同的用户界面控件。Silverlight不包括这种模式。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;触发器&lt;/strong&gt;。Silverlight控件模板与WPF中的有很大不同，因为他们不支持处触发器。触发器是一个将事件声明影射为动画和状态改变的工具。针对这种情况的解决方案是所谓的视觉状态管理器。在后面中我们会详细介绍。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;样式&lt;/strong&gt;。样式是一种可在多个元素上重复使用的格式。Silverlight提供样式，但是有一定限制。值得注意的是，它不允许你在应用程序运行之后再更改样式（这限制了一些潜在的更换皮肤的设计），而且它不包含自动应用某些元素的样式的机制。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;自定义路由事件&lt;/strong&gt;。Silverlight支持路由事件的概念&amp;#8212;&amp;#8212;即事件发生在一个元素中，然后遍历元素的层次结构，可以让你有机会来处理这种包含关系的元素事件。但是，Silverlight有很多限制，包括防止使用自己定义的控件的路由事件。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;离线模式&lt;/strong&gt;。Silverlight的应用程序下载到客户端并且在浏览器中执行。虽然这种模式使在客户端硬件驱动上缓存应用程序成为可能，然而在浏览器之外，就不包括这种功能。&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;Silverlight设计工具&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;虽然在技术上，你手动创建一个Silverlight应用程序文件是有可能的，但是专业的开发仍远仍然会使用专业的开发工具。如果你是一个图形设计人员，那么可以使用Microsoft Expression Bland 3。这个工具为设计丰富的视觉效果的用户界面提供完整的功能。如果你是一个开发人员，你很可能使用Visual Studio 2008 或Visual Studio 2010。因为他们之中包含了良好的编码、测试和调试工具。&lt;/p&gt;&lt;p&gt;因为这两个工具对于Silverlight应用程序模型来说是平等的，你可以更容易创建一个工作流来整合他们。例如，开发人员可以使用Visual Studio创建一个基础用户界面，然后交给一个精锐的美工设计团队。美工团队可以在Expression Blend中使用自定义图形来美化它。当美化结束后，设计人员会将这个项目交还给开发人员。然后，开发人员会继续在此基础上使用Vsual Studio编写和改进它的代码。&lt;/p&gt;&lt;p&gt;许多开发人员更进一步。他们在计算机上安装两个应用程序，同时运行他们，然后再他们之间切换。他们利用Visual Studio进行核心程序开发，如编码和调试。然后再切换到Expression Blend来强化他们的用户界面&amp;#8212;&amp;#8212;例如，为了编辑控件模板，挑选颜色，定义动画以及绘制简单的艺术图形。（这样反复变化的工作流程中，一旦你保存其中一个的修改，另一个程序中就会出现提示。当你再切换回来时，程序就会提醒您迅速刷新以加载新的版本。唯一的技巧是你要记住在切换之前保存。）即使你使用这种方法，那么Visual Studio仍然是你进行项目开发的起点和核心开发重要工具。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Visual Studio VS. Expression Blend&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;现在我们可以了解Visual Studio 2008、Visual Studio 2010以及Expression Blend的关系：&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Visual Studio 2008&lt;/strong&gt;：它拥有你要开发Silverlight应用程序必须的一切，但是没有提供图形化设计的功能。你不仅需要手动编写所有标记（其实并不像听起来这么糟糕），你还无法获得Silverlight页面的设计时预览（这才是更烦人的）。因此，如果你想看到你的用户界面的效果，你将被迫编译你的应用程序并在浏览器中启动它。过去，Visual Studio 2008 已经具有一个为Silverlight 2 提供页面预览的设计器，但是这个功能已经被移除。因为它有慢又笨重。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Visual Studio 2010&lt;/strong&gt;：具有与Visual Studio 2008相同的编码支持，但增加了一个可视化设计器。使用这个设计器，你可以拖拽你的用户界面（并非总是好的做法），而且你可以实时预览页面的效果（这个总是非常有用）。唯一的缺点是Visual Studio 2010还是测试版。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Expression Blend 3&lt;/strong&gt;：它提供了用于支持创建Silverlight的丰富用户界面的工具。在这个方面，这个工具超过Visual Studio 2010。对于某种类型的繁重的页面工作（例如，创建一个不错的渐变填充），这个工具是一个巨大的帮助。Expression Blend还支持一个有趣的应用程序原型工具，叫做SketchFlow，并包含一个成熟的像在Visual&amp;nbsp; Studio中的代码编辑器。然而，它缺乏像调试、代码重构以及项目源代码管理等先进的重要的开发工具。&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;理解Silverlight网站&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;你在Visual Studio 或Expression Blend中可以创建两种网站：&lt;/p&gt;&lt;ul&gt;&lt;li&gt;一个包含普通HTML页面的网站：这种情况下，你的Silverlight应用程序的入口点是一个普通的HTML文件。这个HTML文件中包含一个Silverlight内容区域。&lt;/li&gt;&lt;li&gt;ASP.NET 网站：这种情况下，Visual Studio会创建两个项目，一个包含Silverlight应用程序文件，而另一个会宿主一个服务端的ASP.NET网站。这个ASP.NET网站将和你的Silverlight文件一起部署。你的Silverlight应用程序的入口点可以是一个普通的HTML文件，也可以是一个包含服务器端生成内容的ASP.NET网页。&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;那么，那种方法最好呢？无论你选择那种方式，你的Silverlight应用程序都将以相同的方式运行&amp;#8212;&amp;#8212;客户端浏览器接收到的都是包含一个Silverlight内容区域的HTML 文档以及将要运行在客户端本地机器上的Silverlight代码。然而，ASP.NET网站应用程序会更容易的混合ASP.NET和Silverlight内容。在如下情况下，ASP.NET网站往往是更好的方法：&lt;/p&gt;&lt;ul&gt;&lt;li&gt;你希望创建的网站包含ASP.NET网页和Silverlight内容。&lt;/li&gt;&lt;li&gt;你希望创建一个Silverlight应用程序来调用一个Web服务，而且你希望同时设计这个Web服务（并将其部署到相同的Web服务器）。&lt;/li&gt;&lt;li&gt;你希望使用专门的ASP.NETWeb控件间接生成Silverlight内容。&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;另一方面，如果你不需要写任何服务器代码，几乎没有必要创建一个全功能的ASP.NET网站。这里我给出的案例中，大部分都是使用基本HTML网站的Silverlight应用程序。只有案例中需要ASP.NET服务器端代码时才会使用ASP.NET网站。&lt;/p&gt;&lt;p&gt;======================================================================================&lt;/p&gt;&lt;p&gt;&lt;strong&gt;添加Silverlight内容到现有网站中&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;考虑到Silverlight的开发模式，需要记住一个关键的问题。在许多情况下，你需要在现有网站内容中加入Silverlight。这些网站可能包含普通HTML、CSS或JavaScript元素。例如，你可能会添加一个Silverlight内容区域来展示广告或者增强网站某一部分的用户体验（如参与一个游戏、完成一项调查、与产品互动、虚拟现实参观）。你可以使用经过Silverlight增强的网页来表现内容，使现有的网站内容更加吸引人，或为那些拥有Silverlight插件的用户提供增值服务功能。&lt;/p&gt;&lt;p&gt;=======================================================================================&lt;/p&gt;&lt;p&gt;当然，还有可能创建一个只包含Silverlight的网站，但这是一个比较大胆的手法。关键的不足是Silverlight仍然较新，并不像如Flash这样的其他Web技术被广泛的安装，而且不支持那些仍然运行Windows ME或Windows 2000操作系统的传统客户端。因此，Silverlight不可能与普通的HTML达到相同的应用范围。许多企业采用Silverlight是为了使用最前沿的技术，让他们自己从其他在线的竞争对手中脱颖而出。但是他们仍然没有放弃传统的网站。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;创建一个单独的Silverlight项目&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;开始使用Silverlight技术的最简单的方法就是创建一个普通HTML的网页，而且不加载任何服务器端代码。方法如下：&lt;/p&gt;&lt;ol&gt;&lt;li&gt;在Visual Studio中选择文件-&amp;gt;新建-&amp;gt;项目,然后选择项目类型为Visual C#的组，并选择Silverlight应用程序模板。像往常一样，你必须选择一个项目名称和你的本地路径，然后点击确定。&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/Silverlight2_F27C/image_6.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/Silverlight2_F27C/image_thumb_2.png" width="685" height="366" /&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;此时，Visual Studio将提示你选择是否要创建一个完整地ASP.NET网站，来运行服务端代码和你的Silverlight代码。在Visual Studio 2008中，取消选中&amp;#8220;在一个新的网站中宿主Silverlight应用程序&amp;#8221;选项，可以让事情变的简单。在Visual Studio 2010中，你可以选择&amp;#8220;自动生成一个测试页&amp;#8221;选项来完成相同功能。&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/Silverlight2_F27C/image_10.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/Silverlight2_F27C/image_thumb_4.png" width="441" height="256" /&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;如果你使用Visual Studio 2010，及还有其他的选择。你可以选择创建一个Silverlight2或Silverlight3的应用程序。在Visual Studio 2008中，你没有此选项。所以，如果您已安装了Silverlight3工具，您将无法创建Silverlight2应用程序。&lt;/li&gt;&lt;li&gt;点击OK继续，就可以创建项目了。&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;每一个Silverlight项目开始于一小部分基本的文件。如下图所示。所有以.xaml扩展名结尾的文件，都是使用一种灵活的叫做XAML的标准标记语言。我们将在下一部分中讨论XAML。所有.cs扩展名结尾的文件都是应用程序执行的C#源代码文件。&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/Silverlight2_F27C/image_12.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/Silverlight2_F27C/image_thumb_5.png" width="248" height="168" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;下面是这些文件的介绍：&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;App.xaml和App.xaml.cs&lt;/strong&gt;：这些文件用来配置你的Silverlight应用程序。他们允许你定义可以在所有页面中使用的资源，而且他们允许你对应用程序事件做出反应，如启动、关闭和错误判断。在新生成的项目中，定义在App.xaml.cs文件中的启动代码指定应用程序开始时显示MainPage.xaml页面。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;MainPage.xaml&lt;/strong&gt;：此文件定义了在你的第一个页面中显示的用户界面（控件、图片和文本的集合）。从技术上讲，Silverlight页使用的控件派生自UserControl类。一个Silverlight应用程序可以包含任意你所需要的数量的网页。想要添加更多页面，只要选择添加新项，再选择Silverlight用户控件模板，并给定一个文件名，然后单击添加。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;MainPage.xaml.cs：&lt;/strong&gt;此文件包含支持你的第一个页面的代码，还包含响应用户操作的事件处理程序。&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;除了这四个重要文件外，有几个因素，隐藏在你的周围。在解决方案浏览器的属性节点下，你会看到名为AppManifest.xml的文件。这个文件中列出了应用程序要使用的引用列表。你还会看到名为AssemblyInfo.cs。这个文件包含一些在编译时嵌入到你的Silverlight程序集的项目信息（如名字、版本和版权）。这些文件都不应手动编辑，而是当你添加引用或设置项目属性时，由Visual Studio修改它们。&lt;/p&gt;&lt;p&gt;最后，你的Silverlight应用程序门户是自动生成的，但是却隐藏在名为TestPage.html的HTML文件中。要查看此文件，请确保你已经编译了你的应用程序至少一次。然后，在解决方案资源管理器的顶端点击&amp;#8220;察看所有文件&amp;#8221;按钮，并展开Bin\Debug文件夹（这里是你应用程序编译后的目录）。TestPage.html文件包含一个&amp;lt;object&amp;gt;元素来创建一个Silverlight内容区域。在后面还会详细介绍。&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/Silverlight2_F27C/image_14.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/Silverlight2_F27C/image_thumb_6.png" width="260" height="301" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;&lt;strong&gt;创建一个简单的Silverlight页面&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;正如你已经了解到的，每一个Silverlight页面的一部分包含定义视觉外观的标记（XAML文件），另一部分包含事件处理内容的源代码。要自定义你的第一个Silverlight应用程序，你只需打开MainPage.xaml文件，就可以开始添加标记。&lt;/p&gt;&lt;p&gt;在Visual Studio 2008中，没有任何Silverlight的设计界面，所以你需要手动编写所有标记。虽然第一次看起来这是项艰巨的任务，在后面的内容中我们将深入理解XAML语言的要点。工具箱也只能为你提供一些有限的标签帮助。要插入一个元素，将光标移动到XAML文件的适当位置，然后双击工具箱中的元素。如果你所添加的元素不是Silverlight核心元素的一部分时，这项技术就会非常有用。因为Visual Studio将会添加程序集引用以及自动添加命名空间影射。&lt;/p&gt;&lt;p&gt;---------------------------------------------------------------------------------------------------------------&lt;/p&gt;&lt;ul&gt;&lt;li&gt;注意：在Silverlight的术语中，每个符合标准的图形部件（显示在一个窗口中而且由一个.NET类表示的）都叫做元素。传统控件往往用来接收焦点并允许用户交互。例如，TextBox是控件，但是TextBlock不是。&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;---------------------------------------------------------------------------------------------------------------&lt;/p&gt;&lt;p&gt;Visual Studio 2010提供一个更好的设计体验。他给你两种方法来查看每个XAML文件的视觉预览效果（如设计界面）或底层标记（如XAML视图）。默认情况下，Visual Studio中两个部分都会显示，而且其中一个会叠加在另一个之上。&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/Silverlight2_F27C/image_16.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/Silverlight2_F27C/image_thumb_7.png" width="749" height="437" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;在Visual Studio中，您可以在工具箱中选择控件并将它拖拽到你的设计页面中，就可以开始设计你的XAML页面。然而，这种便利不会对你学习XAML提供任何的便利 。为了将你的元素放置到正确的布局容器中，并且可以修改属性，激活事件处理以及使用Silverlight功能，如动画、样式、模板和数据绑定，你需要手动编辑XAML标签。实际上，大多数情况下，你会发现当你拖拽时，Visual Studio在页面中生成的标签不一定是你确实需要的。&lt;/p&gt;&lt;p&gt;为了在任何版本的Visual Studio中都可以顺利开始，你可以尝试创建如下面这样的页面。其中定义了一个按钮和一个文本块儿。粗体的部分已经在你创建项目时，由Visual Studio自动生成并加入到了基本页面模板中。&lt;/p&gt;&lt;strong&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;UserControl&lt;/span&gt; &lt;span style="color: #ff0000"&gt;x&lt;/span&gt;:&lt;span style="color: #ff0000"&gt;Class&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"MyFirstSilverlightApplication.MainPage"&lt;/span&gt;&lt;br/&gt;    &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"http://schemas.microsoft.com/winfx/2006/xaml/presentation"&lt;/span&gt; &lt;br/&gt;    &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;:&lt;span style="color: #ff0000"&gt;x&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"http://schemas.microsoft.com/winfx/2006/xaml"&lt;/span&gt;&lt;br/&gt;    &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;:&lt;span style="color: #ff0000"&gt;d&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"http://schemas.microsoft.com/expression/blend/2008"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;:&lt;span style="color: #ff0000"&gt;mc&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"http://schemas.openxmlformats.org/markup-compatibility/2006"&lt;/span&gt; &lt;br/&gt;    &lt;span style="color: #ff0000"&gt;mc&lt;/span&gt;:&lt;span style="color: #ff0000"&gt;Ignorable&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"d"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;d&lt;/span&gt;:&lt;span style="color: #ff0000"&gt;DesignWidth&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"640"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;d&lt;/span&gt;:&lt;span style="color: #ff0000"&gt;DesignHeight&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"480"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;  &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Grid&lt;/span&gt; &lt;span style="color: #ff0000"&gt;x&lt;/span&gt;:&lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"LayoutRoot"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;&lt;/strong&gt;    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;StackPanel&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;        &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;TextBlock&lt;/span&gt; &lt;span style="color: #ff0000"&gt;x&lt;/span&gt;:&lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"lblMessage"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Text&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Hello World!"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Margin&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"5"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;TextBlock&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;        &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Button&lt;/span&gt; &lt;span style="color: #ff0000"&gt;x&lt;/span&gt;:&lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"cmdClickMe"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Content&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Click Me!"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Margin&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"5"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Button&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;    &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;StackPanel&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;&lt;strong&gt;  &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Grid&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;UserControl&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/strong&gt;&lt;p&gt;&lt;span style="color: #0000ff"&gt;&lt;font color="#000000"&gt;这将创建一网页。其中两个元素叠放在一起。顶端是一个包含简单消息的文本区域。下面是一个按钮。&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;添加事件处理代码&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;font color="#000000"&gt;你可以使用属性向页面的元素中添加事件处理代码，这个方法在WPF、ASP.NET和JavaScript中都是一样的。例如，按钮元素可以抛出一个单击事件叫Click，这个事件在按钮被鼠标或键盘点击时触发。为了响应这个事件，你可以添加Click属性到按钮元素中，并且设置它在代码中的方法名：&lt;/font&gt;&lt;/p&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Button&lt;/span&gt; &lt;span style="color: #ff0000"&gt;x&lt;/span&gt;:&lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"cmdClickMe"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Content&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Click Me!"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Margin&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"5"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Click&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"cmdClickMe_Click"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Button&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;p&gt;&lt;span style="color: #0000ff"&gt;&lt;font color="#000000"&gt;---------------------------------------------------------------------------------------------------------------&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #0000ff"&gt;&lt;font color="#000000"&gt;提示：尽管这并不是必须的，但是通常事件响应方法命名格式为&amp;#8220;元素名_事件名&amp;#8221;。&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #0000ff"&gt;&lt;font color="#000000"&gt;---------------------------------------------------------------------------------------------------------------&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #0000ff"&gt;&lt;font color="#000000"&gt;这个案例假定你已经创建了一个名为cmdClickMe_Click的事件处理方法。下面是这个方法在MainPage.xaml.cs文件中的样子：&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; cmdClickMe_Click(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender, RoutedEventArgs e)&lt;br/&gt;{&lt;br/&gt;    lblMessage.Text = "&lt;span style="color: #8b0000"&gt;Good bye, Chinasofti.&lt;/span&gt;";&lt;br/&gt;}&lt;p&gt;&lt;font color="#000000"&gt;在Visual Studio 2010中，你可以在设计界面中，添加一个通过双击某个元素响应的事件处理程序，或在属性窗口中单击事件按钮，然后再双击相应的事件。&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font color="#000000"&gt;Visual Studio 2008没有这样的便利。但是，一旦你增加了事件处理程序，你可以使用智能感知迅速将方法分配给正确的事件。首先键入属性名称，然后键入等号就可以。此时，Visual Studio将会弹出一个菜单，列出所有在你的代码类中，那些语法上没有错误的方法来支持这个事件。如下图，只需选择下拉列表中的事件响应方法。&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/Silverlight2_F27C/image_8.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/Silverlight2_F27C/image_thumb_3.png" width="536" height="86" /&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;font color="#000000"&gt;可以使用Visual Studio（任一版本），通过添加一个事件属性并选择&amp;#8220;新建事件处理程序&amp;#8221;来实现一步创建和分配实践处理程序。&lt;/font&gt;&lt;/p&gt;&lt;p&gt;---------------------------------------------------------------------------------------------------------------&lt;/p&gt;&lt;p&gt;&lt;font color="#000000"&gt;提示：要想快速从你的XAML标签跳转到事件处理程序，只要在相应的事件属性上点击右键，选择&amp;#8220;跳转到事件处理程序&amp;#8221;即可。&lt;/font&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/Silverlight2_F27C/image_18.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/Silverlight2_F27C/image_thumb_8.png" width="566" height="167" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;&lt;font color="#000000"&gt;你也可以使用代码来连接事件。代码是写在叶面的构造函数中，在InitializeComponent()方法调用之后，即初始化所有控件之后。下面的代码相当于前面例子中的XAML标记：&lt;/font&gt;&lt;/p&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; MainPage()&lt;br/&gt;{&lt;br/&gt;    InitializeComponent();&lt;br/&gt;    cmdClickMe.Click +=&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; RoutedEventHandler(cmdClickMe_Click);&lt;br/&gt;}&lt;p&gt;&lt;font color="#000000"&gt;如果你需要在你的窗口生成时，动态创建一个控件并附加一个事件，该方法就非常有用。相比之下你在XAML中挂接的事件，当窗体对象初始化时，会被首先附加到元素上。该方法也可保持你的XAML更简洁、更简单。这样简洁的代码在你打算与非程序员，如美工人员，共享时，就非常的完美。其缺点是明显增加的代码量，会使你的代码文件显得凌乱。&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font color="#000000"&gt;如果你想分离事件处理程序，代码是你唯一的选择。您可以使用-=运算符，如下所示：&lt;/font&gt;&lt;/p&gt;&lt;p&gt;cmdClickMe.Click -= cmdClickMe_Click;&lt;/p&gt;&lt;p&gt;&lt;font color="#000000"&gt;将同样的事件处理程序连接到相同的控件多次，在技术上是可行的，但是这样总会有一个事件的代码会出错。（这种情况下，事件处理程序将会触发多次。）如果你试图删除一个重复连接的实践处理程序，那么事件将仍会触发另一个保留的事件处理程序。&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font color="#000000"&gt;---------------------------------------------------------------------------------------------------------------&lt;/font&gt;&lt;/p&gt;&lt;h3 align="center"&gt;Silverlight的类库&lt;/strong&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;font color="#000000"&gt;要编写实际的代码，你需要知道相当多的你要使用的类。这就意味着对一个核心类库的透彻了解，关系到顺利的使用Silverlight。&lt;/font&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;font color="#000000"&gt;Silverlight版本的.NET框架是经过两个层次简化的。首先，它不提供像你在完整.NET框架中看到的那么多类型。其次，它包含的类中通常不提供全套的构造函数、方法、属性和实践。相反，Silverlight只保留最重要最实际的成员类。这些留下的类足够创建惊人的引人注目的代码。&lt;/font&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;font color="#000000"&gt;你会发现，Silverlight中的许多类都有公共接口，与他们在全功能的.NET框架中时相对应。然而，这些类的实际机制完全不同。所有的Silverlight类已经从头到尾被改写，为了尽可能的精简和最大化的保留功能。&lt;/font&gt;&lt;/p&gt;&lt;p align="left"&gt;---------------------------------------------------------------------------------------------------------------&lt;/p&gt;&lt;p&gt;&lt;strong&gt;测试Silverlight应用程序&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;你现在可以开始测试你的Silverlight项目了。当你运行Silverlight应用程序时，Visual Studio启动默认Web浏览器并导航到隐藏的浏览器测试页&amp;#8212;&amp;#8212;TestPage.html。测试页创建一个新的Silverlight控件，并使用MainPage.xaml中的标签初始化它。&lt;/p&gt;&lt;p&gt;---------------------------------------------------------------------------------------------------------------&lt;/p&gt;&lt;p&gt;注意：Visual Studio将TestPage.html设置为项目的初始页。因此，当您启动项目时，此网页将被装载在浏览器中。您可以通过在解决方案资源管理器中，右键选择不同HTML文件，并设置它为启始页，来更换起始页。&lt;/p&gt;&lt;p&gt;---------------------------------------------------------------------------------------------------------------&lt;/p&gt;&lt;p&gt;下图就显示了前面的例子运行的效果。当你单击按钮，事件处理代码将运行，而且文本会被改变。虽然是像ASP.NET一样在服务端编程的框架，但是这个过程完全在客户端发生，因此不需要联系服务器或者回发页面。所有Silverlight代码通过嵌入在Silverlight插件中的精简版本的.NET在客户端执行。&lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/Silverlight2_F27C/image_20.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/Silverlight2_F27C/image_thumb_9.png" width="646" height="188" /&gt;&lt;/a&gt; &lt;a href="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/Silverlight2_F27C/image_22.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/zhangdong/WindowsLiveWriter/Silverlight2_F27C/image_thumb_10.png" width="642" height="176" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;如果你用一个普通网站（没有服务端ASP.NET内容）来宿主Silverlight内容，Visual Studio将不会在测试过程中使用集成的网络服务器。相反，它只是打开HTML测试页，直接从文件系统浏览。（你可以从上面图片中浏览器地址栏中看到效果）&lt;/p&gt;&lt;p&gt;在某种情况下，此行为可能导致你的测试环境和部署环境之间的差异。而部署环境大多数情况下使用的是基于HTTP的全功能的网络服务器。最明显的区别是从安全角度考虑的&amp;#8212;&amp;#8212;换句话说，你可以配置你的Web浏览器，允许本地网页来执行那些远程Web内容不能执行的操作。实际上，这问题并不经常发生。因为Silverlight总是在执行一个精简的安全机制，而不限制那些可信的本地功能。这会简化Silverlight开发模式，并且确定功能不会再一种特定的环境下可以执行，而放到其他环境后就无法执行。然而，当基于实际产品标准测试一个Silverlight应用程序时，创建一个ASP.NET测试网站还是比较好的做法。或者，甚至更好的做法是将你的Silverlight应用程序部署到测试Web服务器上。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/Phoenix-Rock/aggbug/1793190.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/Phoenix-Rock/archive/2010/08/05/Silverlight.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/Phoenix-Rock/archive/2009/08/13/1545375.html</id><title type="text">使用MAP文件快速定位程序崩溃代码行(转)</title><summary type="text">使用MAP文件快速定位程序崩溃代码行(转)</summary><published>2009-08-13T07:54:00Z</published><updated>2009-08-13T07:54:00Z</updated><author><name>天马行空（笨笨）</name><uri>http://www.cnblogs.com/Phoenix-Rock/</uri></author><link rel="alternate" href="http://www.cnblogs.com/Phoenix-Rock/archive/2009/08/13/1545375.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/Phoenix-Rock/archive/2009/08/13/1545375.html"/><content type="text">使用MAP文件快速定位程序崩溃代码行(转)</content></entry><entry><id>http://www.cnblogs.com/Phoenix-Rock/archive/2009/07/29/1533712.html</id><title type="text">Pocket PC 模拟器上网设置</title><summary type="text">Pocket PC 模拟器上网设置</summary><published>2009-07-29T01:29:00Z</published><updated>2009-07-29T01:29:00Z</updated><author><name>天马行空（笨笨）</name><uri>http://www.cnblogs.com/Phoenix-Rock/</uri></author><link rel="alternate" href="http://www.cnblogs.com/Phoenix-Rock/archive/2009/07/29/1533712.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/Phoenix-Rock/archive/2009/07/29/1533712.html"/><content type="text">Pocket PC 模拟器上网设置</content></entry><entry><id>http://www.cnblogs.com/Phoenix-Rock/archive/2009/07/09/1519895.html</id><title type="text">解决继承窗体或用户控件时“visual继承当前被禁用，因为基类引用设备特定的组件或包含 p/invoke”问题(转)</title><summary type="text">解决继承窗体或用户控件时“visual继承当前被禁用，因为基类引用设备特定的组件或包含 p/invoke”问题</summary><published>2009-07-09T06:56:00Z</published><updated>2009-07-09T06:56:00Z</updated><author><name>天马行空（笨笨）</name><uri>http://www.cnblogs.com/Phoenix-Rock/</uri></author><link rel="alternate" href="http://www.cnblogs.com/Phoenix-Rock/archive/2009/07/09/1519895.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/Phoenix-Rock/archive/2009/07/09/1519895.html"/><content type="text">解决继承窗体或用户控件时“visual继承当前被禁用，因为基类引用设备特定的组件或包含 p/invoke”问题</content></entry><entry><id>http://www.cnblogs.com/Phoenix-Rock/archive/2009/02/16/1391633.html</id><title type="text">操作MSN(IM)相关的资源</title><summary type="text">操作MSN(IM)相关的资源</summary><published>2009-02-16T07:33:00Z</published><updated>2009-02-16T07:33:00Z</updated><author><name>天马行空（笨笨）</name><uri>http://www.cnblogs.com/Phoenix-Rock/</uri></author><link rel="alternate" href="http://www.cnblogs.com/Phoenix-Rock/archive/2009/02/16/1391633.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/Phoenix-Rock/archive/2009/02/16/1391633.html"/><content type="text">操作MSN(IM)相关的资源</content></entry><entry><id>http://www.cnblogs.com/Phoenix-Rock/archive/2009/02/12/1389131.html</id><title type="text">我坚信：中国经济将很快进入一个黑色大萧条时期</title><summary type="text">我坚信：中国经济将很快进入一个黑色大萧条时期</summary><published>2009-02-12T07:21:00Z</published><updated>2009-02-12T07:21:00Z</updated><author><name>天马行空（笨笨）</name><uri>http://www.cnblogs.com/Phoenix-Rock/</uri></author><link rel="alternate" href="http://www.cnblogs.com/Phoenix-Rock/archive/2009/02/12/1389131.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/Phoenix-Rock/archive/2009/02/12/1389131.html"/><content type="text">我坚信：中国经济将很快进入一个黑色大萧条时期</content></entry><entry><id>http://www.cnblogs.com/Phoenix-Rock/archive/2008/11/20/1337341.html</id><title type="text">压缩SQLServer数据库日志的一个存储过程 </title><summary type="text">压缩SQLServer数据库日志的一个存储过程 </summary><published>2008-11-20T02:20:00Z</published><updated>2008-11-20T02:20:00Z</updated><author><name>天马行空（笨笨）</name><uri>http://www.cnblogs.com/Phoenix-Rock/</uri></author><link rel="alternate" href="http://www.cnblogs.com/Phoenix-Rock/archive/2008/11/20/1337341.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/Phoenix-Rock/archive/2008/11/20/1337341.html"/><content type="text">压缩SQLServer数据库日志的一个存储过程 </content></entry></feed>
