<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
  <channel>
    <title>翻译引进 - 老赵点滴 - 追求编程之美</title>
    <link>http://blog.zhaojie.me/translation/</link>
    <description>先做人，再做技术人员，最后做程序员。打造国内最好的.NET技术博客。</description>
    <language>zh-cn</language>
    <managingEditor>jeffz@live.com (老赵)</managingEditor>
    <webMaster>jeffz@live.com (老赵)</webMaster>
    <pubDate>Wed, 15 Nov 2006 10:23:00 GMT</pubDate>
    <lastBuildDate>Wed, 17 Nov 2010 12:56:01 GMT</lastBuildDate>
    <ttl>60</ttl>
    <item>
      <author>jeffz@live.com (老赵)</author>
      <category domain="http://blog.zhaojie.me/cutting-edge/">技术尝鲜</category>
      <category domain="http://blog.zhaojie.me/speech/">培训演讲</category>
      <category domain="http://blog.zhaojie.me/translation/">翻译引进</category>
      <title>PDC 2010：C#与Visual Basic的未来（下）</title>
      <link>http://blog.zhaojie.me/2010/11/pdc2010-the-future-of-csharp-and-vb-by-anders-hejlsberg-3.html</link>
      <guid>http://blog.zhaojie.me/2010/11/pdc2010-the-future-of-csharp-and-vb-by-anders-hejlsberg-3.html</guid>
      <description>&lt;p&gt;前几天在PDC 2010会议上Anders Hejlsberg发表了一场名为“The Future of C# and Visual Basic”的演说，谈论了未来C#和VB中最为重要的两个特性：“异步（Async）”及“编译器即服务（Compiler as a Service）”。我现在对这场演讲进行总结，但不会像上次《&lt;a href="http://blog.zhaojie.me/2010/04/trends-and-future-directions-in-programming-languages-by-anders-1-history-and-trends.html"&gt;编程语言的发展趋势及未来方向&lt;/a&gt;》那样逐句翻译，而是以Anders的角度使用一种简捷合适的方式表述其完整内容。上一篇Anders对async和await的的实现及效果作更进一步的解释，本篇则是对“编译器即服务”做了些最表面的尝试。&lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/36.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/36-s.png" /&gt;&lt;/a&gt; 

&lt;p&gt;你们某些人可能参加了PDC 2008，那时我谈到了“编译器即服务（Compier as a Service）”，也作了点演示。现在我来演示一点这方面的进展。 &lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/37-1.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/37-1-s.png" /&gt;&lt;/a&gt; 

&lt;p&gt;编译器即服务的关键，在于目前的编译器是个黑盒，输入源文件，输出.NET程序集。至于它是如何工作的，你不能参与进去。 &lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/37-2.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/37-2-s.png" /&gt;&lt;/a&gt; 

&lt;p&gt;为了打造更灵活工作过程，我们把编译器展开，把其中的信息展示出来并加以利用，这样就能做到实现元编程、REPL，把C#和VB作为内嵌的DSL，或是根据语言对象模型实现重构，代码生成器等语义相关的工作。 &lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/38.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/38-s.png" /&gt;&lt;/a&gt; 

&lt;p&gt;我最后的示例便是些这方面的展示。（译注：这个示例展示的代码非常复杂，但并不重要，它的主要目的便是根据编译器提供的语言对象模型，判断其中的if/else逻辑，并在Visual Studio中显示出轮廓（就像方法的折叠功能一样）。有趣的是，这个演示失败了……） &lt;/p&gt;

&lt;p&gt;这里的语言对象模型，就是C#和VB编译器内部所使用的，包含了完整的语义，可用于理解代码的工作目的。有了这些数据，我们就能作一些非常有趣的事情了。例如，我们有两个语言，它们的语法非常接近，不是吗？那么我们理解了其中一个语言，把它转化成另外一个应该也不太困难。 &lt;/p&gt;

&lt;p&gt;这里还有一个简单的C#到VB的代码转换器（译注：又一个演示），你可以把C#代码复制到剪贴板里，然后粘贴成VB代码。在实现时，只不过遍历了C#语法树，生成另一个对象模型。当然，这个程序也不是太简单，实际上还是要有几千行代码的，这里只是个最简单的实现。那么我这里来试着把那段没法工作的代码，粘贴到VB文件中……砰，这就出现了功能一致的VB代码（掌声）。这就是利用这种技术可以做到的事情。我们也已经发布了CTP版本的编译器，也包含了这些示例。 &lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/39.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/39-s.png" /&gt;&lt;/a&gt; 

&lt;p&gt;我答应过，这里是Visual Studio Async CTP的下载地址，它基于Visual Studio 2010安装。其中包含了所有我演示过的示例，有C#也有VB。此外还有一些相关的讲座，例如LINQ，我也会参加下午的语言话题讨论。接下来还有点时间，可以回答一两个问题。 &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;提问：&lt;/strong&gt;除了这里您提到的这些，C#和VB还会包含其他功能吗？ &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Anders：&lt;/strong&gt;呃，现在说起C#和VB最终是什么样的为时尚早，不过的确还有些其他的功能。 &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;提问：&lt;/strong&gt;我想知道您对于数据并发和数据共享的看法。 &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Anders：&lt;/strong&gt;并发有许多令人头痛的地方，你说的就是其中之一。我们在内部有些研究是关于不可变性，状态隔离，纯函数式编程，还有其他一些编译器方面的工作。现在还没有准备好公开，不过我们正在取得些不错的进展。我相信接下来的几十年间并发会一直是个课题，这里的异步功能是其中的一小步，我肯定还会有更多进展。 &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;提问：&lt;/strong&gt;从反射的视角来说，异步方法和普通方法有什么区别？ &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Anders：&lt;/strong&gt;对于反射来说，异步方法就是普通的方法，调用方法也一样。不过它会在第一个await的地方返回，等异步任务完成之后，它再继续执行下去。所以它其实和普通方法没有任何区别，但如果你要知道它什么时候结束，那么就必须去关注它返回的Task对象了。你还看到我写过一些void方法，可能你根本不会在乎它什么时候结束，不过原理上它还是一样的。 &lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/40.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/40-s.png" /&gt;&lt;/a&gt; 

&lt;p&gt;就到这里，非常感谢各位参与。&lt;/p&gt;

&lt;h1&gt;相关文章&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://blog.zhaojie.me/2010/10/pdc2010-the-future-of-csharp-and-vb-by-anders-hejlsberg-1.html"&gt;PDC 2010：C#与Visual Basic的未来（上）&lt;/a&gt;&lt;/li&gt;

  &lt;li&gt;&lt;a href="http://blog.zhaojie.me/2010/10/pdc2010-the-future-of-csharp-and-vb-by-anders-hejlsberg-2.html"&gt;PDC 2010：C#与Visual Basic的未来（中）&lt;/a&gt;&lt;/li&gt;

  &lt;li&gt;PDC 2010：C#与Visual Basic的未来（下） &lt;/li&gt;
&lt;/ul&gt;</description>
      <comments>http://blog.zhaojie.me/2010/11/pdc2010-the-future-of-csharp-and-vb-by-anders-hejlsberg-3.html#comments</comments>
      <pubDate>Mon, 15 Nov 2010 09:47:47 GMT</pubDate>
      <lastBuildDate>Wed, 17 Nov 2010 12:56:01 GMT</lastBuildDate>
    </item>
    <item>
      <author>jeffz@live.com (老赵)</author>
      <category domain="http://blog.zhaojie.me/cutting-edge/">技术尝鲜</category>
      <category domain="http://blog.zhaojie.me/speech/">培训演讲</category>
      <category domain="http://blog.zhaojie.me/translation/">翻译引进</category>
      <title>PDC 2010：C#与Visual Basic的未来（中）</title>
      <link>http://blog.zhaojie.me/2010/10/pdc2010-the-future-of-csharp-and-vb-by-anders-hejlsberg-2.html</link>
      <guid>http://blog.zhaojie.me/2010/10/pdc2010-the-future-of-csharp-and-vb-by-anders-hejlsberg-2.html</guid>
      <description>&lt;p&gt;前几天在PDC 2010会议上Anders Hejlsberg发表了一场名为“The Future of C# and Visual Basic”的演说，谈论了未来C#和VB中最为重要的两个特性：“异步（Async）”及“编译器即服务（Compiler as a Service）”。我现在对这场演讲进行总结，但不会像上次《&lt;a href="http://blog.zhaojie.me/2010/04/trends-and-future-directions-in-programming-languages-by-anders-1-history-and-trends.html"&gt;编程语言的发展趋势及未来方向&lt;/a&gt;》那样逐句翻译，而是以Anders的角度使用一种简捷合适的方式表述其完整内容。上一篇Anders讲述了async和await的使用方式，而这篇则是对这两个关键字的实现及效果作更进一步的解释。&lt;/p&gt;

&lt;a href="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/11.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/11-s.png" /&gt;&lt;/a&gt; 

&lt;p&gt;异步方法的目标，是为了让代码与同步方法保持一致。微软要让代码充斥着回调函数，混乱不堪，它们完全不是逻辑上你想做的事情。可能您的代码中包含着一个核心模型，你也已经实现了，只是您现在想把它的执行过程变得异步化。您自己就可以享受到这一点。&lt;/p&gt;

&lt;p&gt;与我们之前做的一些扩展一样，工作分为语言和框架两部分。语言的异步功能基于框架中的Task&amp;lt;T&amp;gt;，我们会围绕着Task&amp;lt;T&amp;gt;扩展框架，将它作为异步模型的核心。事实上，从Begin/End，或是基于事件的异步模型进行扩展往往只需要一两行封装的代码，于是您也可以得到自己的Task&amp;lt;T&amp;gt;模型。&lt;/p&gt;

&lt;p&gt;而在语言方面，我们添加了两个新的关键字。一个是async关键字，用于把方法标记为异步。还有一个是await方法，用于等待异步工作完成，或者说是把控制权交换给调用方继续执行其他工作。这两个功能在C#和VB种均有体现。&lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/12.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/12-s.png" /&gt;&lt;/a&gt; 

&lt;p&gt;那么什么是Task&amp;lt;T&amp;gt;呢？它表现的是一个“后续会继续进行的操作”，这可以是许多东西，Task&amp;lt;T&amp;gt;并不做任何限制，例如是一个异步I/O，后台工作线程等等，甚至可以是UI上的一个按钮，在用户点击之后任务就结束了。&lt;/p&gt;

&lt;p&gt;Task&amp;lt;T&amp;gt;的优势在于，它使用一个对象封装了整个概念，您可以查询其结果或是状态，或是这个任务所引发的异常。您可以用它来构造一个可组合的异步模型，这正式我们目前的异步编程模型所不足的地方。&lt;/p&gt;

&lt;p&gt;此外，它还提供了一个可组合的回调模型，您可以对一个任务指定说，在它结束之后执行另外一段代码，然后还可以对这个新的任务继续进行设定。这便构造出一个完整的逻辑流，框架会自行帮你完成这些工作。事实上await操作符便会自动把您的逻辑改写成这样的代码，它将您从Lambda表达式及回调函数中的逻辑里解放了出来，一切都交给编译器去做了。您可能会有些疑惑，不过其实这些都是编译器所擅长的事情。&lt;/p&gt;

&lt;p&gt;由于我们统一了异步模型，我们就可以在此之上构建组合工具。例如WhenAll，它接受一系列的Task对象，并在全部结束之后返回所有结果。还有WhenAny，则等待第一个完成的任务，返回其结果。我们还有Delay，可以等待一段时间，但不占用任何资源。&lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/13.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/13-s.png" /&gt;&lt;/a&gt; 

&lt;p&gt;沿着这个过程走一遍可能就会清晰一些。这里有个例子，一个异步方法调用另一个异步方法。我们假设这是在UI线程上执行的，消息会一个一个发送至UI线程上。&lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/14.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/14-s.png" /&gt;&lt;/a&gt; 

&lt;p&gt;好，有人调用了DoWorkAsync，于是出现了一些任务。&lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/15-1.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/15-1-s.png" /&gt;&lt;/a&gt; 

&lt;p&gt;DoWorkAsync的第一件事，是调用了ProcessFeedAsync。&lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/15-2.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/15-2-s.png" /&gt;&lt;/a&gt; 

&lt;p&gt;ProcessFeedAsync方法是一个异步方法，所以它做的第一件事是构造一个表示任务的Task对象。&lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/16.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/16-s.png" /&gt;&lt;/a&gt; 

&lt;p&gt;然后它调用了DownloadFeedAsync，这会创建另一个Task对象。然后，我们遇上了await操作符，这意味着ProcessFeedAsync后面的部分，将作为DownloadFeedAsync完成后的回调函数/continuation里的工作。&lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/17.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/17-s.png" /&gt;&lt;/a&gt; 

&lt;p&gt;于是任务返回至DoWorkAsync，我们得到了t1这个对象。&lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/18.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/18-s.png" /&gt;&lt;/a&gt; 

&lt;p&gt;同样的过程会再次出现，是为t2。&lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/19.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/19-s.png" /&gt;&lt;/a&gt; 

&lt;p&gt;然后便调用了Task.WhenAll，这会创建一个新任务，表示前两个任务全部完成。于是这里的await操作符表示接下去的代码会在前两个任务完成后再继续下去。此时控制权便还给了DoWorkAsync的调用者，不会对线程造成负担。&lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/20.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/20-s.png" /&gt;&lt;/a&gt; 

&lt;p&gt;在未来某一时刻t1和t2会执行完，我们假设t2先结束。此时它会说：我完成了，执行回调函数/continuation吧。&lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/21.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/21-s.png" /&gt;&lt;/a&gt; 

&lt;p&gt;于是它会和发起线程的SynchronizationContext交互，给UI线程发一个消息，让后续任务在UI线程上继续执行──您的代码不用关注这些。现在代码运行至SaveDocAsync上了，这是另外一个异步任务。await让代码在这里返回，线程又可以执行目前还未结束的任务了。&lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/23.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/23-s.png" /&gt;&lt;/a&gt; 

&lt;p&gt;于是SaveDocAsync任务完成了，UI线程又获得了一个消息执行后续工作。&lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/24.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/24-s.png" /&gt;&lt;/a&gt; 

&lt;p&gt;此时任务便到达了ProcessFeedAsync的末尾，于是t2任务结束了。&lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/27.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/27-s.png" /&gt;&lt;/a&gt; 

&lt;p&gt;继续等待，上面的过程会再次出现，最终t1也结束了。&lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/29.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/29-s.png" /&gt;&lt;/a&gt; 

&lt;p&gt;当t1和t2完成以后，最后DoWorkAsync任务也终于结束了。可以看到，我们逻辑流程，无论是循环还是异常捕获都是同步的，但是其中的执行过程完全是异步的。&lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/30.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/30-s.png" /&gt;&lt;/a&gt; 

&lt;p&gt;但是这又是如何实现的？我不会在这里说太细，这又是个完整的话题了。这里有一个例子，是一个异步方法，它会调用并await另一个异步方法。&lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/31.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/31-s.png" /&gt;&lt;/a&gt; 

&lt;p&gt;而编译器则最终则生成类似于这样的代码。我只会提几点，首先，这是个状态机，编译器构造的其实就是个状态机，例如迭代器就是个状态机，事实上这里编译器的工作和yield之余迭代器的重写本质上没有太大区别。&lt;/p&gt;

&lt;p&gt;其次就是关于任务的执行和等待，假如在等待时任务已经完成了，那么其实您是在同步地执行后续代码。我们没有必要交还控制，反正已经完成了，我们不妨就直接进行下去了。await有自己的模式，会决定这一任务是同步还是异步地执行。对于同步执行的任务，一切就继续执行下去了，直到某个需要异步执行的地方，便把控制权交还给调用方。&lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/32.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/32-s.png" /&gt;&lt;/a&gt; 

&lt;p&gt;那么我们再来看一下异步之于Web服务的意义。这里有个ASP.NET页面，它会向数据库里获取许多RSS地址，然后下载到本地并解析：&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;private void &lt;/span&gt;ProcessData()
{
    &lt;span style="color: green"&gt;// ...

    &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;urls = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;&amp;gt;();
    &lt;span style="color: blue"&gt;using &lt;/span&gt;(&lt;span style="color: blue"&gt;var &lt;/span&gt;conn = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;SqlConnection&lt;/span&gt;(connectionString))
    {
        conn.Open();
        &lt;span style="color: blue"&gt;var &lt;/span&gt;cmd = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;SqlCommand&lt;/span&gt;(&lt;span style="color: #a31515"&gt;&amp;quot;GetUserFeeds&amp;quot;&lt;/span&gt;, conn);
        cmd.CommandType = &lt;span style="color: #2b91af"&gt;CommandType&lt;/span&gt;.StoredProcedure;
        cmd.Parameters.AddWithValue(&lt;span style="color: #a31515"&gt;&amp;quot;@UserID&amp;quot;&lt;/span&gt;, user);
        &lt;span style="color: blue"&gt;using &lt;/span&gt;(&lt;span style="color: blue"&gt;var &lt;/span&gt;reader = cmd.ExecuteReader())
        {
            &lt;span style="color: blue"&gt;while &lt;/span&gt;(reader.Read()) urls.Add(reader[&lt;span style="color: #a31515"&gt;&amp;quot;FeedURL&amp;quot;&lt;/span&gt;].ToString());
        }
    }

    &lt;span style="color: blue"&gt;var &lt;/span&gt;feeds = (&lt;span style="color: blue"&gt;from &lt;/span&gt;url &lt;span style="color: blue"&gt;in &lt;/span&gt;urls &lt;span style="color: blue"&gt;select &lt;/span&gt;CreateWebClient().DownloadString(url)).ToArray();

    &lt;span style="color: green"&gt;// ...
&lt;/span&gt;}&lt;/pre&gt;

&lt;p&gt;这里用到了DownloadString这个同步下载数据的方法。执行下来大约要花费1秒多的时间。这里我不再演示令人痛苦的异步写法了，你必须在Page_Load和Page_PreRender各写一些逻辑，注册一些异步工作，或者就要启用一些后台线程，但这又会影响后台的线程池，对系统的表现会带来影响。&lt;/p&gt;

&lt;p&gt;现在我来演示一些简单的异步化工作：&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;private &lt;span style="background-color: #ffff00"&gt;async&lt;/span&gt; void &lt;/span&gt;ProcessData()
{
    &lt;span style="color: green"&gt;// ...

    &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;urls = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;&amp;gt;();
    &lt;span style="color: blue"&gt;using &lt;/span&gt;(&lt;span style="color: blue"&gt;var &lt;/span&gt;conn = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;SqlConnection&lt;/span&gt;(connectionString))
    {
        conn.Open();
        &lt;span style="color: blue"&gt;var &lt;/span&gt;cmd = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;SqlCommand&lt;/span&gt;(&lt;span style="color: #a31515"&gt;&amp;quot;GetUserFeeds&amp;quot;&lt;/span&gt;, conn);
        cmd.CommandType = &lt;span style="color: #2b91af"&gt;CommandType&lt;/span&gt;.StoredProcedure;
        cmd.Parameters.AddWithValue(&lt;span style="color: #a31515"&gt;&amp;quot;@UserID&amp;quot;&lt;/span&gt;, user);
        &lt;span style="color: blue"&gt;using &lt;/span&gt;(&lt;span style="color: blue"&gt;var &lt;/span&gt;reader = &lt;span style="background-color: #ffff00"&gt;&lt;span style="color: blue"&gt;await &lt;/span&gt;cmd.ExecuteReaderAsync()&lt;/span&gt;)
        {
            &lt;span style="color: blue"&gt;while &lt;/span&gt;(reader.Read()) urls.Add(reader[&lt;span style="color: #a31515"&gt;&amp;quot;FeedURL&amp;quot;&lt;/span&gt;].ToString());
        }
    }

    &lt;span style="color: blue"&gt;var &lt;/span&gt;feeds = &lt;span style="background-color: #ffff00"&gt;&lt;span style="color: blue"&gt;await &lt;/span&gt;&lt;span style="color: #2b91af"&gt;TaskEx&lt;/span&gt;.WhenAll&lt;/span&gt;(
        &lt;span style="color: blue"&gt;from &lt;/span&gt;url &lt;span style="color: blue"&gt;in &lt;/span&gt;urls &lt;span style="color: blue"&gt;select &lt;/span&gt;CreateWebClient().&lt;span style="background-color: #ffff00"&gt;DownloadStringTaskAsync&lt;/span&gt;(url));

    &lt;span style="color: green"&gt;// ...
&lt;/span&gt;}&lt;/pre&gt;

&lt;p&gt;我们将DownloadString修改为DownloadStringTaskAsync，这样LINQ返回的就是一系列表示下载任务的Task对象，然后使用await及WhenAll等待它们全部完成。数据库查询也可以如此。这就是所有我们要做的事情。如今页面的执行效率有了很明显的提高。使用这个做法，我们可以很轻松地提高Web系统的伸缩能力。如今我们需要调用很多互相独立的服务的情况越来越多了，异步方法对此有很大帮助。&lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/33.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/33-s.png" /&gt;&lt;/a&gt; 

&lt;p&gt;如今的异步场景有许多种，例如在后台执行一个计算任务，这是基于CPU的异步，还有基于网络或I/O的异步任务。这些都能用Task来表示出来，因为Task表示的就是未来会完成的异步任务。此外，有了async和.NET框架，我们则出现了另外一种任务，既基于某些任务组合而成的异步任务。这也就是async方法所体现出的异步任务，它可以让你使用传统的语句来构造异步执行过程。&lt;/p&gt;

&lt;p&gt;例如有这么一个场景：获取链接，根据链接下载Youtube视频，根据下载到的视频创建mashup并组合起来。在执行这些工作的时候，我们也希望UI可以响应用户操作。&lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/34.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/34-s.png" /&gt;&lt;/a&gt; 

&lt;p&gt;而要完成这些工作，代码可能只需要这么简单，完全就像同步代码一样。而这里也体现了多种异步任务：ScrapeYoutubeAsync是网络密集型任务，然后同时下载两个视频并等待它们结束。然后MashupVideosAsync是CPU密集型任务，然后最后则是I/O密集型的的SaveAsync操作。对于异常处理来说，我们可以简捷地使用一个try...catch，就像传统编程那样。&lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/35.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/35-s.png" /&gt;&lt;/a&gt; 

&lt;p&gt;总结一下，一个异步方法可以让代码和同步实现一样简单，并统一了计算、网络及I/O的异步化。这可以用来创建高度伸缩的服务器程序，自然还有响应度高的UI程序。&lt;/p&gt;

&lt;p&gt;在演讲的末尾，我会给出Visual Studio Async CTP的下载链接，我很乐于得到大家的反馈。&lt;/p&gt;

&lt;h1&gt;相关文章 &lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://blog.zhaojie.me/2010/10/pdc2010-the-future-of-csharp-and-vb-by-anders-hejlsberg-1.html"&gt;PDC 2010：C#与Visual Basic的未来（上）&lt;/a&gt;&lt;/li&gt;

  &lt;li&gt;PDC 2010：C#与Visual Basic的未来（中）&lt;/li&gt;

  &lt;li&gt;&lt;a href="http://blog.zhaojie.me/2010/11/pdc2010-the-future-of-csharp-and-vb-by-anders-hejlsberg-3.html"&gt;PDC 2010：C#与Visual Basic的未来（下）&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <comments>http://blog.zhaojie.me/2010/10/pdc2010-the-future-of-csharp-and-vb-by-anders-hejlsberg-2.html#comments</comments>
      <pubDate>Sun, 31 Oct 2010 13:49:48 GMT</pubDate>
      <lastBuildDate>Wed, 17 Nov 2010 12:55:19 GMT</lastBuildDate>
    </item>
    <item>
      <author>jeffz@live.com (老赵)</author>
      <category domain="http://blog.zhaojie.me/cutting-edge/">技术尝鲜</category>
      <category domain="http://blog.zhaojie.me/speech/">培训演讲</category>
      <category domain="http://blog.zhaojie.me/translation/">翻译引进</category>
      <title>PDC 2010：C#与Visual Basic的未来（上）</title>
      <link>http://blog.zhaojie.me/2010/10/pdc2010-the-future-of-csharp-and-vb-by-anders-hejlsberg-1.html</link>
      <guid>http://blog.zhaojie.me/2010/10/pdc2010-the-future-of-csharp-and-vb-by-anders-hejlsberg-1.html</guid>
      <description>&lt;a href="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/01.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/01-s.png" /&gt;&lt;/a&gt; 

&lt;p&gt;PDC不愧为微软最高级的技术人员专业会议，看得我直呼过瘾。前几天在PDC 2010会议上Anders Hejlsberg发表了一场名为“The Future of C# and Visual Basic”的演说，谈论了未来C#和VB中最为重要的两个特性：“异步（Async）”及“编译器即服务（Compiler as a Service）”。我现在对这场演讲进行总结，但不会像上次《&lt;a href="http://blog.zhaojie.me/2010/04/trends-and-future-directions-in-programming-languages-by-anders-1-history-and-trends.html"&gt;编程语言的发展趋势及未来方向&lt;/a&gt;》那样逐句翻译，而是以Anders的角度使用一种简捷合适的方式表述其完整内容。&lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/02.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/02-s.png" /&gt;&lt;/a&gt; 

&lt;p&gt;在2000年的PDC上，我们给大家带来了一个全新的平台“.NET”，以及一个语言“C#”。.NET与C#每次发布时都有一个“主题”，一开始是“托管代码”，接着是“泛型”，然后是“LINQ”，直到最近的“动态性”，这就是C#和VB的演变过程。这两种语言面向的用户比较相近，微软也承诺会同时发展两种语言。因此这个演讲虽然以C#作为主题，但其实也会在VB中得以体现。&lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/03.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/03-s.png" /&gt;&lt;/a&gt; 

&lt;p&gt;作为语言的设计者，要设法将工业界所重视的内容，使用语言表现出来，因此也有了这样的分类。“声明式”代表了一种编程的趋势，尽可能表现出“做什么”而不是“怎么做”，于是有了函数式编程与DSL等等。然后，目前研究的热门之一则是动态语言，如Python，Ruby，JavaScript等等，以及它们是如何影响静态语言的。还有便是“并发”，这里所指的广义的“并发”，包括单机上多核以及云或是数据中心上分布式系统等等，也就是各种“同时处理”的方式。&lt;/p&gt;

&lt;p&gt;我们可以清楚地看到，C# 3.0和VB 9中的函数式编程，LINQ等特性体现了“声明式”，而C# 4.0和VB 10则出现了动态性，但都没有太多关于“并发”的成分在里面──它都体现在框架中了，例如.NET 4包含了任务并行库（Task Parallel Library），但对于语言来说，除了lock似乎就没有什么这方面的支持了。&lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/04.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/04-s.png" /&gt;&lt;/a&gt; 

&lt;p&gt;如今对“并发”的需求已经是毋庸质疑的，很少有一个应用程序或是服务不需要连接外部系统。这种与外部系统，例如互联网进行交互的行为则增加了应用程序的延迟，这可能导致UI在和外部服务交互时长时间失去响应。而对于一个数据中心的服务，您可能就会发现CPU的利用率不高，因为系统都在等待其他服务的回复了。 &lt;/p&gt;

&lt;p&gt;为了解决这个问题，我们往往会使用“异步”的编程方式，它逐渐已经成为“高响应度”，“高伸缩性”的代名词了。此外还有一些API只提供了异步的版本，例如在JavaScript中发起HTTP请求，或是Silverlight的网络交互方面。这种情况以后只会越来越普遍。&lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/05.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/05-s.png" /&gt;&lt;/a&gt; 

&lt;p&gt;于是下一版本的C#和VB就会在这里有所行动，目前会展示一下我们的早期工作，希望可以得到一些反馈。&lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/06.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/06-s.png" /&gt;&lt;/a&gt; 

&lt;p&gt;说到异步化，您可以简单认为“一起运行”。一个同步方法，好比DownloadString，应用程序会执行这个方法，并等待结果返回，但是你不能把工作的执行过程与结果的送达区分开来。而对于异步编程来说，DownloadStringAsync在调用之后便会立即返回，过了一段时间，结果就会传递过来，于是执行过程和结果的送达便完全是可分离的了。而对于如今典型的异步模型来说，结果通过一个回调函数传递过来。 &lt;/p&gt;

&lt;p&gt;异步化可以的得到高度的响应能力，因为在等待任务的结果时我们可以做其他一些事情。而对于服务器来说，异步可以带来很好的伸缩性，因为线程得到释放了，而不需要等待请求返回结果。&lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/07.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/07-s.png" /&gt;&lt;/a&gt; 

&lt;p&gt;通过图示可以更清楚地了解这点。例如有段代码叫做DownloadData，调用以后可以得到一些数据。在执行时，线程会有长时间的终止，它被阻塞了，要等到结果返回之后才能继续处理数据。与此相对的是其异步的版本，我们调用DownloadDataAsync方法之后，它立即将控制权交还给我们，过了一段时间，它会把结果传递给回调函数，让我们继续处理下去。但是在DownloadData和ProcessData之间，我们可以处理其他一些工作。如果这是UI线程，那么就可以用于响应其他用户操作。如果这是个服务器线程，那么在等待结果时这个线程可以用来处理其他请求。&lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/08.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/08-s.png" /&gt;&lt;/a&gt; 

&lt;p&gt;那么，如果我们要执行多个请求，例如要调用两遍，对于同步的版本就会获得双倍的阻塞，即便两个请求是完全独立的。而在异步的情况下，我们可以快速地发出两个请求，这样便形成的并发，即便这里并没有使用额外的线程。于是便可以更快地得到结果，也能保证响应能力。&lt;/p&gt;

&lt;p&gt;有人可能会说，我们可以利用后台线程来得到响应。没错，不过就引入了多线程模型，于是就要处理同步等线程安全问题。而且，在开发带有UI的应用程序时，我们不能在后台线程里操作UI，这样又出现了其他的复杂情况。而在服务器应用中，我们又不希望创建更多的线程，因为这会给线程池带来压力，线程之间会有竞争，就会降低请求的处理能力。&lt;/p&gt;

&lt;p&gt;以上便是对异步编程的概述，您可能会问，既然异步有那么多好处，那么为什么不把所有的应用程序都写作异步的呢？那么现在我们就来看一下异步编程大概是什么样子的。&lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/09.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/09-s.png" /&gt;&lt;/a&gt; 

&lt;p&gt;这里有个简单的应用程序，输入年份，可以下载到那一年的电影。现在这个程序是同步的写法。在搜索的时候UI会失去响应，这样的结果显然无法令人接受，我们要做的更好。我们可以将其改写为异步的形式。 &lt;/p&gt;

&lt;p&gt;同步的写法是这样的：&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;private void &lt;/span&gt;searchButton_Click(&lt;span style="color: blue"&gt;object &lt;/span&gt;sender, &lt;span style="color: #2b91af"&gt;RoutedEventArgs &lt;/span&gt;e)
{
    LoadMovies(&lt;span style="color: #2b91af"&gt;Int32&lt;/span&gt;.Parse(textBox.Text));
}

&lt;span style="color: blue"&gt;void &lt;/span&gt;LoadMovies(&lt;span style="color: blue"&gt;int &lt;/span&gt;year)
{
    resultsPanel.Children.Clear();
    statusText.Text = &lt;span style="color: #a31515"&gt;&amp;quot;&amp;quot;&lt;/span&gt;;
    &lt;span style="color: blue"&gt;var &lt;/span&gt;pageSize = 10;
    &lt;span style="color: blue"&gt;var &lt;/span&gt;imageCount = 0;

    &lt;span style="color: blue"&gt;while &lt;/span&gt;(&lt;span style="color: blue"&gt;true&lt;/span&gt;)
    {
        &lt;span style="color: blue"&gt;var &lt;/span&gt;movies = QueryMovies(year, imageCount, pageSize);
        &lt;span style="color: blue"&gt;if &lt;/span&gt;(movies.Length == 0) &lt;span style="color: blue"&gt;break&lt;/span&gt;;
        DisplayMovies(movies);
        imageCount += movies.Length;
    }

    statusText.Text = &lt;span style="color: #2b91af"&gt;String&lt;/span&gt;.Format(&lt;span style="color: #a31515"&gt;&amp;quot;{0} Titles&amp;quot;&lt;/span&gt;, imageCount);
}

&lt;span style="color: #2b91af"&gt;Movie&lt;/span&gt;[] QueryMovies(&lt;span style="color: blue"&gt;int &lt;/span&gt;year, &lt;span style="color: blue"&gt;int &lt;/span&gt;first, &lt;span style="color: blue"&gt;int &lt;/span&gt;count)
{
    &lt;span style="color: blue"&gt;var &lt;/span&gt;client = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;WebClient&lt;/span&gt;();
    &lt;span style="color: blue"&gt;var &lt;/span&gt;url = &lt;span style="color: #2b91af"&gt;String&lt;/span&gt;.Format(query, year, first, count);
    &lt;span style="color: blue"&gt;var &lt;/span&gt;data = client.DownloadString(&lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Uri&lt;/span&gt;(url));

    &lt;span style="color: blue"&gt;var &lt;/span&gt;movies =
        &lt;span style="color: blue"&gt;from &lt;/span&gt;entry &lt;span style="color: blue"&gt;in &lt;/span&gt;&lt;span style="color: #2b91af"&gt;XDocument&lt;/span&gt;.Parse(data).Desendanies(xs + &lt;span style="color: #a31515"&gt;&amp;quot;entry&amp;quot;&lt;/span&gt;)
        &lt;span style="color: blue"&gt;let &lt;/span&gt;properties = entry.Element(xm + &lt;span style="color: #a31515"&gt;&amp;quot;properties&amp;quot;&lt;/span&gt;)
        &lt;span style="color: blue"&gt;select new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Movie
        &lt;/span&gt;{
            &lt;span style="color: green"&gt;/* ... */
        &lt;/span&gt;};

    &lt;span style="color: blue"&gt;return &lt;/span&gt;movies.ToArray();
}&lt;/pre&gt;

&lt;p&gt;在点击按钮以后会调用LoadMovies方法，它会在一个循环中不断使用QueryMovies方法进行查询，在QueryMovies方法中我们使用WebClient下载一个XML，解析，构造Movie对象并返回，最终呈现在界面上。&lt;/p&gt;

&lt;p&gt;下载时我们使用DownloadString方法，这是个同步方法，我们要把它修改成异步的方式。事实上还真有个异步的方法，叫做DownloadStringAsync，不过这就需要我们修改代码，例如要把QueryMovies中的大部分放入DownloadStringCompleted事件的处理函数中。同时，异步编程的痛苦慢慢体现出现了，我们无法返回数据，而必须传递到某个地方，于是QueryMovies方法则要返回void，并接受一个回调函数。&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;void &lt;/span&gt;QueryMovies(&lt;span style="color: blue"&gt;int &lt;/span&gt;year, &lt;span style="color: blue"&gt;int &lt;/span&gt;first, &lt;span style="color: blue"&gt;int &lt;/span&gt;count, &lt;span style="color: #2b91af"&gt;Action&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Movie&lt;/span&gt;[]&amp;gt; action)
{
    &lt;span style="color: blue"&gt;var &lt;/span&gt;client = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;WebClient&lt;/span&gt;();
    &lt;span style="color: blue"&gt;var &lt;/span&gt;url = &lt;span style="color: #2b91af"&gt;String&lt;/span&gt;.Format(query, year, first, count);

    client.DownloadStringCompleted += (sender, e) =&amp;gt;
    {
        &lt;span style="color: blue"&gt;var &lt;/span&gt;data = e.Result;
        &lt;span style="color: blue"&gt;var &lt;/span&gt;movies =
            &lt;span style="color: blue"&gt;from &lt;/span&gt;entry &lt;span style="color: blue"&gt;in &lt;/span&gt;&lt;span style="color: #2b91af"&gt;XDocument&lt;/span&gt;.Parse(data).Descendants(xs + &lt;span style="color: #a31515"&gt;&amp;quot;entry&amp;quot;&lt;/span&gt;)
            &lt;span style="color: blue"&gt;let &lt;/span&gt;properties = entry.Element(xm + &lt;span style="color: #a31515"&gt;&amp;quot;properties&amp;quot;&lt;/span&gt;)
            &lt;span style="color: blue"&gt;select new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Movie
            &lt;/span&gt;{
                &lt;span style="color: green"&gt;/* ... */
            &lt;/span&gt;};

        action(movies.ToArray());
    };

    client.DownloadStringAsync(&lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Uri&lt;/span&gt;(url));
}&lt;/pre&gt;

&lt;p&gt;然后我们还需要处理QueryMovies的调用者，这里实在麻烦到家了，因为我们使用了一个while循环来查询电影，那么我们又该如何反复调用一个异步方法？&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;void &lt;/span&gt;LoadMovies(&lt;span style="color: blue"&gt;int &lt;/span&gt;year)
{
    resultsPanel.Children.Clear();
    statusText.Text = &lt;span style="color: #a31515"&gt;&amp;quot;&amp;quot;&lt;/span&gt;;
    &lt;span style="color: blue"&gt;var &lt;/span&gt;pageSize = 10;
    &lt;span style="color: blue"&gt;var &lt;/span&gt;imageCount = 0;

    &lt;span style="color: #2b91af"&gt;Action&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Movie&lt;/span&gt;[]&amp;gt; action = &lt;span style="color: blue"&gt;null&lt;/span&gt;;
    action = movies =&amp;gt;
    {
        &lt;span style="color: blue"&gt;if &lt;/span&gt;(movie.Length &amp;gt; 0)
        {
            DisplayMovie(movies);
            imageCount += movies.Length;
            QueryMovies(year, imageCount, pageSize, action);
        }
        &lt;span style="color: blue"&gt;else
        &lt;/span&gt;{
            statusText.Text = &lt;span style="color: #2b91af"&gt;String&lt;/span&gt;.Format(&lt;span style="color: #a31515"&gt;&amp;quot;{0} Titles&amp;quot;&lt;/span&gt;, imageCount);
        }
    };

    QueryMovies(year, imageCount, pageSize, action);
}&lt;/pre&gt;

&lt;p&gt;你一定已经发现了，现在的代码已经很难让人保持愉快了。不过它的确是异步的了，运行时界面响应良好。效果是有了，不过这代码变得乱七八糟。想象一下，如果要加上异常处理该怎么做？我们可能要提供两个回调函数，一个处理正常情况，一个处理错误，还到处需要有try...catch，很快麻烦就会接踵而来了。如果不想面对这些麻烦，你可能就要去启用后台线程，这样又有了线程方面的问题。 &lt;/p&gt;

&lt;p&gt;显然我们可以做的更好。首先让我们回到原来的同步代码，然后再用上我们为异步编程设计的新特性。&lt;/p&gt;

&lt;p&gt;如果要把QueryMovies变为异步，则先把它的返回值改为Task&amp;lt;Movie[]&amp;gt;，你如果了解.NET 4则一定已经知道这个类型是任务并行库的一部分。事实上Task类型只是表示一个“开始计算并在未来返回结果”的任务，因此Task&amp;lt;T&amp;gt;表示一个会在将来返回T类型的计算任务，在科学计算领域这通常被称为Future或是Promise。现在方法的返回值是Task&amp;lt;Movie[]&amp;gt;，而最后返回的是Movie[]，这显然不匹配，但我们可以将其标记为一个async方法。对于async方法，编译器会重写整个方法实现来表示一个异步任务，以后我们会来观察它是如何实现这点的。&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&lt;span style="background-color: #ffff00"&gt;async&lt;/span&gt; &lt;/span&gt;&lt;span style="background-color: #ffff00"&gt;&lt;span style="color: #2b91af"&gt;Task&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Movie&lt;/span&gt;[]&amp;gt;&lt;/span&gt; QueryMoviesAsync(&lt;span style="color: blue"&gt;int &lt;/span&gt;year, &lt;span style="color: blue"&gt;int &lt;/span&gt;first, &lt;span style="color: blue"&gt;int &lt;/span&gt;count)
{
    &lt;span style="color: blue"&gt;var &lt;/span&gt;client = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;WebClient&lt;/span&gt;();
    &lt;span style="color: blue"&gt;var &lt;/span&gt;url = &lt;span style="color: #2b91af"&gt;String&lt;/span&gt;.Format(query, year, first, count);
    &lt;span style="color: blue"&gt;var &lt;/span&gt;data = client.DownloadString(&lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Uri&lt;/span&gt;(url));

    &lt;span style="color: blue"&gt;var &lt;/span&gt;movies =
        &lt;span style="color: blue"&gt;from &lt;/span&gt;entry &lt;span style="color: blue"&gt;in &lt;/span&gt;&lt;span style="color: #2b91af"&gt;XDocument&lt;/span&gt;.Parse(data).Descendants(xs + &lt;span style="color: #a31515"&gt;&amp;quot;entry&amp;quot;&lt;/span&gt;)
        &lt;span style="color: blue"&gt;let &lt;/span&gt;properties = entry.Element(xm + &lt;span style="color: #a31515"&gt;&amp;quot;properties&amp;quot;&lt;/span&gt;)
        &lt;span style="color: blue"&gt;select new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Movie
        &lt;/span&gt;{
            &lt;span style="color: green"&gt;/* ... */
        &lt;/span&gt;};

    &lt;span style="color: blue"&gt;return &lt;/span&gt;movies.ToArray();
}&lt;/pre&gt;

&lt;p&gt;不过只做到这点还不够，我们的方法还没有异步化，这还是个同步任务。不过，如今在一个async方法中，我们有能力组合调用另一个async方法，并异步地等待。这里使用了一个扩展方法DownloadStringTaskAsync，以后也会包含在框架中。这个方法返回Task&amp;lt;string&amp;gt;类型，表示未来某一时刻将会得到一个string对象。于是在async方法中，我们使用一个新的await操作符来等待其返回。&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;async &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Task&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Movie&lt;/span&gt;[]&amp;gt; QueryMoviesAsync(&lt;span style="color: blue"&gt;int &lt;/span&gt;year, &lt;span style="color: blue"&gt;int &lt;/span&gt;first, &lt;span style="color: blue"&gt;int &lt;/span&gt;count)
{
    &lt;span style="color: blue"&gt;var &lt;/span&gt;client = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;WebClient&lt;/span&gt;();
    &lt;span style="color: blue"&gt;var &lt;/span&gt;url = &lt;span style="color: #2b91af"&gt;String&lt;/span&gt;.Format(query, year, first, count);
    &lt;span style="color: blue"&gt;var &lt;/span&gt;data = &lt;span style="color: blue"&gt;&lt;span style="background-color: #ffff00"&gt;await&lt;/span&gt; &lt;/span&gt;client.&lt;span style="background-color: #ffff00"&gt;DownloadStringTaskAsync&lt;/span&gt;(&lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Uri&lt;/span&gt;(url));

    &lt;span style="color: blue"&gt;var &lt;/span&gt;movies =
        &lt;span style="color: blue"&gt;from &lt;/span&gt;entry &lt;span style="color: blue"&gt;in &lt;/span&gt;&lt;span style="color: #2b91af"&gt;XDocument&lt;/span&gt;.Parse(data).Descendants(xs + &lt;span style="color: #a31515"&gt;&amp;quot;entry&amp;quot;&lt;/span&gt;)
        &lt;span style="color: blue"&gt;let &lt;/span&gt;properties = entry.Element(xm + &lt;span style="color: #a31515"&gt;&amp;quot;properties&amp;quot;&lt;/span&gt;)
        &lt;span style="color: blue"&gt;select new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Movie
        &lt;/span&gt;{
            &lt;span style="color: green"&gt;/* ... */
        &lt;/span&gt;};

    &lt;span style="color: blue"&gt;return &lt;/span&gt;movies.ToArray();
}&lt;/pre&gt;

&lt;p&gt;在执行时，方法会执行到await操作符这里，并确保接下来的代码是在一个回调函数/continuation中执行的。编译器会在这里重写这个方法，就像为yield重写迭代器那样，于是我们就不需要做其他事情了，任务结束后自然会执行await后面的代码。&lt;/p&gt;

&lt;p&gt;这里的美妙之处在于可以任意组合，对于LoadMovies方法来说，我们也可以将其转化为async方法，并await之前的QueryMoviesAsync方法返回。&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&lt;span style="background-color: #ffff00"&gt;async&lt;/span&gt; void &lt;/span&gt;LoadMoviesAsync(&lt;span style="color: blue"&gt;int &lt;/span&gt;year)
{
    resultsPanel.Children.Clear();
    statusText.Text = &lt;span style="color: #a31515"&gt;&amp;quot;&amp;quot;&lt;/span&gt;;
    &lt;span style="color: blue"&gt;var &lt;/span&gt;pageSize = 10;
    &lt;span style="color: blue"&gt;var &lt;/span&gt;imageCount = 0;

    &lt;span style="color: blue"&gt;while &lt;/span&gt;(&lt;span style="color: blue"&gt;true&lt;/span&gt;)
    {
        &lt;span style="color: blue"&gt;var &lt;/span&gt;movies = &lt;span style="color: blue"&gt;&lt;span style="background-color: #ffff00"&gt;await&lt;/span&gt; &lt;/span&gt;QueryMoviesAsync(year, imageCount, pageSize);
        &lt;span style="color: blue"&gt;if &lt;/span&gt;(movies.Length == 0) &lt;span style="color: blue"&gt;break&lt;/span&gt;;
        DisplayMovies(movies);
        imageCount += movies.Length;
    }

    statusText.Text = &lt;span style="color: #2b91af"&gt;String&lt;/span&gt;.Format(&lt;span style="color: #a31515"&gt;&amp;quot;{0} Titles&amp;quot;&lt;/span&gt;, imageCount);
}&lt;/pre&gt;

&lt;p&gt;于是异步实现就这么完成了，代码和之前几乎完全一致。您可以看出，这使得我们在执行异步代码时保留原本的逻辑实现。&lt;/p&gt;

&lt;p&gt;那么再为应用程序添加一点功能吧。首先是异常处理：&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;async void &lt;/span&gt;LoadMoviesAsync(&lt;span style="color: blue"&gt;int &lt;/span&gt;year)
{
    resultsPanel.Children.Clear();
    statusText.Text = &lt;span style="color: #a31515"&gt;&amp;quot;&amp;quot;&lt;/span&gt;;
    &lt;span style="color: blue"&gt;var &lt;/span&gt;pageSize = 10;
    &lt;span style="color: blue"&gt;var &lt;/span&gt;imageCount = 0;

    &lt;span style="color: blue"&gt;try
    &lt;/span&gt;{
        &lt;span style="color: blue"&gt;while &lt;/span&gt;(&lt;span style="color: blue"&gt;true&lt;/span&gt;)
        {
            &lt;span style="color: blue"&gt;var &lt;/span&gt;movies = &lt;span style="color: blue"&gt;await &lt;/span&gt;QueryMoviesAsync(year, imageCount, pageSize);
            &lt;span style="color: blue"&gt;if &lt;/span&gt;(movies.Length == 0) &lt;span style="color: blue"&gt;break&lt;/span&gt;;
            DisplayMovies(movies);
            imageCount += movies.Length;
        }

        statusText.Text = &lt;span style="color: #2b91af"&gt;String&lt;/span&gt;.Format(&lt;span style="color: #a31515"&gt;&amp;quot;{0} Titles&amp;quot;&lt;/span&gt;, imageCount);
    }
    &lt;span style="color: blue"&gt;catch &lt;/span&gt;(&lt;span style="color: #2b91af"&gt;XmlException&lt;/span&gt;)
    {
        statusText.Text = &lt;span style="color: #a31515"&gt;&amp;quot;Data Error&amp;quot;&lt;/span&gt;;
    }
}&lt;/pre&gt;

&lt;p&gt;我们无需分离代码或是逻辑，这一切都和同步代码完全一致。再来看看“取消（cancellation）”，对于async方法来说，我们可以传递一个CancellationToken，表示任务需要监听这个对象的改变。如QueryMoviesAsync便可以增加一个参数：&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;async &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Task&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Movie&lt;/span&gt;[]&amp;gt; QueryMoviesAsync(&lt;span style="color: blue"&gt;int &lt;/span&gt;year, &lt;span style="color: blue"&gt;int &lt;/span&gt;first, &lt;span style="color: blue"&gt;int &lt;/span&gt;count, &lt;span style="background-color: #ffff00"&gt;&lt;span style="color: #2b91af"&gt;CancellationToken &lt;/span&gt;ct&lt;/span&gt;)
{
    &lt;span style="color: blue"&gt;var &lt;/span&gt;client = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;WebClient&lt;/span&gt;();
    &lt;span style="color: blue"&gt;var &lt;/span&gt;url = &lt;span style="color: #2b91af"&gt;String&lt;/span&gt;.Format(query, year, first, count);
    &lt;span style="color: blue"&gt;var &lt;/span&gt;data = &lt;span style="color: blue"&gt;await &lt;/span&gt;client.DownloadStringTaskAsync(&lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Uri&lt;/span&gt;(url), &lt;span style="background-color: #ffff00"&gt;ct&lt;/span&gt;);

    &lt;span style="color: blue"&gt;var &lt;/span&gt;movies =
        &lt;span style="color: blue"&gt;from &lt;/span&gt;entry &lt;span style="color: blue"&gt;in &lt;/span&gt;&lt;span style="color: #2b91af"&gt;XDocument&lt;/span&gt;.Parse(data).Descendants(xs + &lt;span style="color: #a31515"&gt;&amp;quot;entry&amp;quot;&lt;/span&gt;)
        &lt;span style="color: blue"&gt;let &lt;/span&gt;properties = entry.Element(xm + &lt;span style="color: #a31515"&gt;&amp;quot;properties&amp;quot;&lt;/span&gt;)
        &lt;span style="color: blue"&gt;select new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Movie
        &lt;/span&gt;{
            &lt;span style="color: green"&gt;/* ... */
        &lt;/span&gt;};

    &lt;span style="color: blue"&gt;return &lt;/span&gt;movies.ToArray();
}&lt;/pre&gt;

&lt;p&gt;这样便得到了一个可取消的async方法。对于逻辑流来说，取消操作就相当于一个异常，代码里需要处理一个TaskCanceledException：&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="background-color: #ffff00"&gt;&lt;span style="color: #2b91af"&gt;CancellationTokenSource&lt;/span&gt; cts;&lt;/span&gt;

&lt;span style="color: blue"&gt;async &lt;/span&gt;&lt;span style="color: blue"&gt;void &lt;/span&gt;LoadMoviesAsync(&lt;span style="color: blue"&gt;int &lt;/span&gt;year)
{
    resultsPanel.Children.Clear();
    statusText.Text = &lt;span style="color: #a31515"&gt;&amp;quot;&amp;quot;&lt;/span&gt;;
    &lt;span style="color: blue"&gt;var &lt;/span&gt;pageSize = 10;
    &lt;span style="color: blue"&gt;var &lt;/span&gt;imageCount = 0;

    &lt;span style="background-color: #ffff00"&gt;cts = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;CancellationTokenSource&lt;/span&gt;();&lt;/span&gt;
    &lt;span style="color: blue"&gt;try
    &lt;/span&gt;{
        &lt;span style="color: blue"&gt;while &lt;/span&gt;(&lt;span style="color: blue"&gt;true&lt;/span&gt;)
        {
            &lt;span style="color: blue"&gt;var &lt;/span&gt;movies = &lt;span style="color: blue"&gt;await &lt;/span&gt;QueryMoviesAsync(year, imageCount, pageSize, &lt;span style="background-color: #ffff00"&gt;cts.Token&lt;/span&gt;);
            &lt;span style="color: blue"&gt;if &lt;/span&gt;(movies.Length == 0) &lt;span style="color: blue"&gt;break&lt;/span&gt;;
            DisplayMovies(movies);
            imageCount += movies.Length;
        }
        statusText.Text = &lt;span style="color: #2b91af"&gt;String&lt;/span&gt;.Format(&lt;span style="color: #a31515"&gt;&amp;quot;{0} Titles&amp;quot;&lt;/span&gt;, imageCount);
    }
    &lt;span style="color: blue"&gt;catch &lt;/span&gt;(&lt;span style="color: #2b91af"&gt;TaskCanceledException&lt;/span&gt;) { }

    &lt;span style="background-color: #ffff00"&gt;cts = &lt;span style="color: blue"&gt;null&lt;/span&gt;;&lt;/span&gt;
}

&lt;span style="color: blue"&gt;private void &lt;/span&gt;cancelButton_Click(&lt;span style="color: blue"&gt;object &lt;/span&gt;sender, &lt;span style="color: #2b91af"&gt;RoutedEventArgs &lt;/span&gt;e)
{
    &lt;span style="color: blue"&gt;if &lt;/span&gt;(cts != &lt;span style="color: blue"&gt;null&lt;/span&gt;)
    {
        cts.Cancel();
        statusText.Text = &lt;span style="color: #a31515"&gt;&amp;quot;Canceled&amp;quot;&lt;/span&gt;;
    }
}&lt;/pre&gt;

&lt;p&gt;那么超时又怎么说？超时其实就类似一段时间之后的取消。于是我们可以另写一个小方法来处理这个问题：&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;async &lt;/span&gt;&lt;span style="color: blue"&gt;void &lt;/span&gt;StartTimeoutAsync()
{
    &lt;span style="color: blue"&gt;await &lt;/span&gt;&lt;span style="color: #2b91af"&gt;TaskEx&lt;/span&gt;.Delay(5000);
    &lt;span style="color: blue"&gt;if &lt;/span&gt;(cts != &lt;span style="color: blue"&gt;null&lt;/span&gt;)
    {
        cts.Cancel();
        statusText.Text = &lt;span style="color: #a31515"&gt;&amp;quot;Timeout&amp;quot;&lt;/span&gt;;
    }
}

&lt;span style="color: blue"&gt;private void &lt;/span&gt;searchButton_Click(&lt;span style="color: blue"&gt;object &lt;/span&gt;sender, &lt;span style="color: #2b91af"&gt;RoutedEventArgs &lt;/span&gt;e)
{
    LoadMoviesAsync(&lt;span style="color: #2b91af"&gt;Int32&lt;/span&gt;.Parse(textBox.Text));
    &lt;span style="background-color: #ffff00"&gt;StartTimeoutAsync();&lt;/span&gt;
}&lt;/pre&gt;

&lt;p&gt;第一步，我们先等待5秒钟，如果任务还在执行，那么我们就取消掉。所以无论是超时，取消还是错误处理，程序的逻辑结构都得以最大限度的保留，就好比编写普通的代码一样。例如上面的Delay，看上去是顺序逻辑流，但实际上是异步的。为了表现出这点，我们可以为程序新加上一个有趣的功能：&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;async void &lt;/span&gt;ShowDateTimeAsync()
{
    &lt;span style="color: blue"&gt;while &lt;/span&gt;(&lt;span style="color: blue"&gt;true&lt;/span&gt;)
    {
        Title = &lt;span style="color: #a31515"&gt;&amp;quot;Movie Finder &amp;quot; &lt;/span&gt;+ &lt;span style="color: #2b91af"&gt;DateTime&lt;/span&gt;.Now;
        &lt;span style="color: blue"&gt;await &lt;/span&gt;&lt;span style="color: #2b91af"&gt;TaskEx&lt;/span&gt;.Delay(1000);
    }
}

&lt;span style="color: blue"&gt;public &lt;/span&gt;MainWindow()
{
    InitializeComponent();
    textBox.Focus();
    &lt;span style="background-color: #ffff00"&gt;ShowDateTimeAsync();&lt;/span&gt;
}&lt;/pre&gt;

&lt;p&gt;于是在标题栏上便会每隔一秒刷新显示当前时间，与此同时搜索也好，超时也罢，在程序执行时UI都可以获得响应。&lt;/p&gt;

&lt;p&gt;值得强调的是，上面实现的这些功能都没有启用额外的线程，所有这些都在UI线程上执行。那么什么时候需要额外的线程呢？这便是计算密集型操作。例如这里我要执行五千万次平方根计算，这需要耗费一段时间。不过这样的操作，对于UI线程来说，这也不过是一个异步操作，不是吗？启动操作，然后等待其完成，在它完成之后再对结果做些处理：&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;async void &lt;/span&gt;ComputeStuffAsync()
{
    &lt;span style="color: blue"&gt;double &lt;/span&gt;result = 0;
    &lt;span style="color: blue"&gt;await &lt;/span&gt;&lt;span style="color: #2b91af"&gt;TaskEx&lt;/span&gt;.Run(() =&amp;gt;
    {
        &lt;span style="color: blue"&gt;for &lt;/span&gt;(&lt;span style="color: blue"&gt;int &lt;/span&gt;i = 1; i &amp;lt; 500000000; i++)
        {
            result += &lt;span style="color: #2b91af"&gt;Math&lt;/span&gt;.Sqrt(i);
        }
    });

    &lt;span style="color: #2b91af"&gt;MessageBox&lt;/span&gt;.Show(&lt;span style="color: #a31515"&gt;&amp;quot;The result is &amp;quot; &lt;/span&gt;+ result, &lt;span style="color: #a31515"&gt;&amp;quot;Background Task&amp;quot;&lt;/span&gt;,
        &lt;span style="color: #2b91af"&gt;MessageBoxButton&lt;/span&gt;.OK, &lt;span style="color: #2b91af"&gt;MessageBoxImage&lt;/span&gt;.Information);
}

&lt;span style="color: blue"&gt;private void &lt;/span&gt;searchButton_Click(&lt;span style="color: blue"&gt;object &lt;/span&gt;sender, &lt;span style="color: #2b91af"&gt;RoutedEventArgs &lt;/span&gt;e)
{
    LoadMoviesAsync(&lt;span style="color: #2b91af"&gt;Int32&lt;/span&gt;.Parse(textBox.Text));
    StartTimeoutAsync();
    &lt;span style="background-color: #ffff00"&gt;ComputeStuffAsync();&lt;/span&gt;
}&lt;/pre&gt;

&lt;p&gt;TaskEx.Run方法会构造一个后台线程，并返回异步操作，我们使用await等待其返回，这体现了绝佳的组合能力。启动后在任务管理器中便会发现CPU占用率明显上升。&lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/10.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/pdc2010-future-of-csharp-vb-anders/10-s.png" /&gt;&lt;/a&gt; 

&lt;p&gt;我在这里宣布，之前演示的技术预览版已经可以下载了。我们已经创建了C#和VB编译器的原型，并提供了一些示例。您可以在开发者中心下载，我在演讲最后会给出URL。&lt;/p&gt;

&lt;h1&gt;相关文章&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;PDC 2010：C#与Visual Basic的未来（上） &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://blog.zhaojie.me/2010/10/pdc2010-the-future-of-csharp-and-vb-by-anders-hejlsberg-2.html"&gt;PDC 2010：C#与Visual Basic的未来（中）&lt;/a&gt;&lt;/li&gt;

  &lt;li&gt;&lt;a href="http://blog.zhaojie.me/2010/11/pdc2010-the-future-of-csharp-and-vb-by-anders-hejlsberg-3.html"&gt;PDC 2010：C#与Visual Basic的未来（下）&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <comments>http://blog.zhaojie.me/2010/10/pdc2010-the-future-of-csharp-and-vb-by-anders-hejlsberg-1.html#comments</comments>
      <pubDate>Sat, 30 Oct 2010 18:43:29 GMT</pubDate>
      <lastBuildDate>Wed, 17 Nov 2010 12:55:05 GMT</lastBuildDate>
    </item>
    <item>
      <author>jeffz@live.com (老赵)</author>
      <category domain="http://blog.zhaojie.me/practice/">实践优化</category>
      <category domain="http://blog.zhaojie.me/asp-net/">ASP.NET</category>
      <category domain="http://blog.zhaojie.me/translation/">翻译引进</category>
      <title>Padding Oracle Attack实例分析</title>
      <link>http://blog.zhaojie.me/2010/10/padding-oracle-attack-in-detail.html</link>
      <guid>http://blog.zhaojie.me/2010/10/padding-oracle-attack-in-detail.html</guid>
      <description>&lt;p&gt;在之前的《&lt;a href="http://blog.zhaojie.me/2010/09/things-about-padding-oracle-vulnerability-in-asp-net.html"&gt;浅谈&lt;/a&gt;》一文中，我提到《&lt;a href="http://www.gdssecurity.com/l/b/2010/09/14/automated-padding-oracle-attacks-with-padbuster/"&gt;Automated Padding Oracle Attacks with PadBuster&lt;/a&gt;》一文对理解Padding Oracle Attack非常有帮助，并打算将其翻译出来。现在我便来实现承诺了。《Automated》一文其实是在介绍PadBuster这个自动攻击工具，不过其中也通过实例加配图详细介绍了Padding Oracle Attack的原理——这也是我会翻译的部分。这篇文章写的非常通俗易懂，您只需要了解一点点关于加密的基础概念即可，不需要对加密算法或其证明有任何了解。我想只要配合些许Wikipedia上的定义，大部分朋友应该都能顺利地理解这篇文章。&lt;/p&gt;

&lt;p&gt;以下为翻译内容。&lt;/p&gt;

&lt;p&gt;最近出现了许多有关Padding Oracle Attack的声音，在今年夏天早些时候的BlakHat Europe会议上，&lt;a href="http://netifera.com/research/"&gt;Juliano Rizzo和Thai Duong&lt;/a&gt;在他们的演讲中演示了这种攻击方式。虽然Padding Oracle是种相对容易的攻击方式，但如果您还没有对它的自动攻击原理有一定了解，那么利用它进行攻击还是需要不少时间的。由于缺少好用的工具以识别及利用Padding Oracles，我们开发了一个基于Padding Oracle的内部脚本，PadBuster，现在我们打算将它与社区分享。&lt;a href="https://www.gdssecurity.com/l/t/d.php?k=PadBuster"&gt;您可以在这里下载工具&lt;/a&gt;，现在我们也会花些时间来讨论这个工具的工作方式，以及它所支持的几种场景。&lt;/p&gt;

&lt;h1&gt;一些背景知识&lt;/h1&gt;

&lt;p&gt;在讨论PadBuster之前，我们先来简单讨论一下典型的Padding Oracle Attack基础。故名思义，Padding Oracle Attack背后的关键性概念便是加/解密时的填充（Padding）。明文信息可以是任意长度，但是块状加密算法需要所有的信息都由一定数量的数据块组成。为了满足这样的需求，便需要对明文进行填充，这样便可以将它分割为完整的数据块。&lt;/p&gt;

&lt;p&gt;加密时可以使用多种填充规则，但最常见的填充方式之一是在PKCS#5标准中定义的规则。PCKS#5的填充方式为：明文的最后一个数据块包含N个字节的填充数据（N取决于明文最后一块的数据长度）。下图是一些示例，展示了不同长度的单词（FIG、BANANA、AVOCADO、PLANTAIN、PASSIONFRUIT）以及它们使用PKCS#5填充后的结果（每个数据块为8字节长）。&lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/padding-oracle-attack-in-detail/po_fig1.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/padding-oracle-attack-in-detail/po_fig1.png" width="450" /&gt;&lt;/a&gt; 

&lt;p&gt;请注意，每个字符串都至少有1个字节的填充数据，因此7字节的值（如AVOCADO）则使用0x01进行填充，而8字节的值（如PLANTAIN）则会填充一个额外的数据块。填充字节的值也说明了填充的字节数，因此待加密数据的最后几个字节必须是以下几种情况之一：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;一个0x01（0x01） &lt;/li&gt;

  &lt;li&gt;两个0x02（0x02，0x02） &lt;/li&gt;

  &lt;li&gt;三个0x03（0x03，0x03，0x03） &lt;/li&gt;

  &lt;li&gt;四个0x04（0x04，0x04，0x04，0x04） &lt;/li&gt;

  &lt;li&gt;…… &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;如果解密后的最后一个数据块末尾并非这些合法的字节序列，大部分加/解密程序都会抛出一个填充异常。这个异常对于攻击者尤为关键，它是Padding Oracle Attack的基础。&lt;/p&gt;

&lt;h1&gt;一个基本的Padding Oracle Attack场景&lt;/h1&gt;

&lt;p&gt;作为一个具体例子，请考虑以下场景：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;某个应用程序使用Query String参数来传递一个用户加密后的用户名，公司ID及角色ID。参数使用CBC模式加密，每次都使用不同的初始化向量（IV，Initialization Vector）并添加在密文前段。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;当应用程序接受到加密后的值以后，它将返回三种情况：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;接受到正确的密文之后（填充正确且包含合法的值），应用程序正常返回（200 - OK）。 &lt;/li&gt;

  &lt;li&gt;接受到非法的密文之后（解密后发现填充不正确），应用程序抛出一个解密异常（500 - Internal Server Error）。 &lt;/li&gt;

  &lt;li&gt;接受到合法的密文（填充正确）但解密后得到一个非法的值，应用程序显示自定义错误消息（200 - OK）。 &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;上述的场景体现了一个典型的Padding Oracle（填充提示），我们可以利用应用程序的行为轻易了解某个加密的值是否填充正确。这里的单词Oracle代表了一种机制，用于了解某个测试是否通过。&lt;/p&gt;

&lt;p&gt;既然已经给出了场景，那么我们便来查看应用程序所使用的一个加密后的参数。这个参数保存了使用分号隔离的一系列值，在我们的示例中，则是用户名（BRIAN），公司ID（12）及角色ID（12）：因此这里的明文是“&lt;strong&gt;BRIAN;12;2;&lt;/strong&gt;”。以下则是经过加密的Query String实例，请注意加密后的UID参数使用了ASCII十六进制表示法。&lt;/p&gt;

&lt;pre class="code"&gt;http://sampleapp/home.jsp?UID=7B216A634951170FF851D6CC68FC9537858795A28ED4AAC6&lt;/pre&gt;

&lt;p&gt;在实际情况中，攻击者并不会知道这里所对应的明文是多少，不过作为示例，我们已经知道了明文、填充、以及加密后的值（如下表）。正如之前所提到的那样，IV添加在密文的前段，即最前面8个字节。&lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/padding-oracle-attack-in-detail/po_fig2.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/padding-oracle-attack-in-detail/po_fig2.png" width="450" /&gt;&lt;/a&gt; 

&lt;p&gt;攻击者可以根据加密后值的长度来推测出数据块的大小。由于长度（这里是24）能被8整除但不能被16整除，因此可以得知数据块的大小是8个字节。现在我们来观察下加密和解密的内部实现，下图便展示了字节级别的运算方式，这对以后攻击方式的讨论很有帮助。请注意，其中带圆圈的加号表示XOR（异或）操作。&lt;/p&gt;

&lt;p&gt;加密过程：&lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/padding-oracle-attack-in-detail/po_fig3.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/padding-oracle-attack-in-detail/po_fig3.png" width="450" /&gt;&lt;/a&gt; 

&lt;p&gt;解密过程：&lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/padding-oracle-attack-in-detail/po_fig4.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/padding-oracle-attack-in-detail/po_fig4.png" width="450" /&gt;&lt;/a&gt; 

&lt;p&gt;同样值得指出的是，解密之后的最后一个数据块，其结尾应该包含正确的填充序列。如果这点没有满足，那么加/解密程序就会抛出一个填充异常。&lt;/p&gt;

&lt;h1&gt;利用Padding Oracle进行解密&lt;/h1&gt;

&lt;p&gt;我们现在来关注一下如何利用Padding Oracle Attack进行解密。我们将每次操作一个单独的加密块，因此我们可以独立出第一块密文（IV后的那块），在前面加上全为NULL的IV值，并发送至应用程序。以下是URL极其相关回复：&lt;/p&gt;

&lt;pre class="code"&gt;Request: http://sampleapp/home.jsp?UID=0000000000000000F851D6CC68FC9537
Response: 500 - Internal Server Error&lt;/pre&gt;

&lt;p&gt;回复的500错误是意料之中的，因为这个值在解密后完全非法。下图展示了应用程序在尝试解密的时候究竟做了哪些事情。您会发现，因为我们只处理单个数据块，因此它的结尾必须包含正确的填充字节，才能避免出现非法填充异常。&lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/padding-oracle-attack-in-detail/po_fig5.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/padding-oracle-attack-in-detail/po_fig5.png" width="450" /&gt;&lt;/a&gt; 

&lt;p&gt;如上图所示，在解密之后，数据块的末尾并没有包含正确的填充序列，因此出现了异常。现在我们将IV加一，并发送同样的密文，看看会发生什么：&lt;/p&gt;

&lt;pre class="code"&gt;Request: http://sampleapp/home.jsp?UID=0000000000000001F851D6CC68FC9537
Response: 500 - Internal Server Error&lt;/pre&gt;

&lt;p&gt;与之前一样，我们得到了500异常。这是因为在解密后我们还是没有获得合法的填充序列。稍有不同的是，我们在深入内部之后会发现，最后一个字节的值会有所变化（变成了0x3C而不是0x3D）。&lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/padding-oracle-attack-in-detail/po_fig6.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/padding-oracle-attack-in-detail/po_fig6.png" width="450" /&gt;&lt;/a&gt; 

&lt;p&gt;如果我们重复发送这样的请求，每次将IV的最后一个字节加一（直至0xFF），那么最终我们将会产生一个合法的单字节填充序列（0x01）。对于可能的256个值中，只有一个值会产生正确的填充字节0x01。遇上这个值的时候，你应该得到一个不同于其他255个请求的回复结果：&lt;/p&gt;

&lt;pre class="code"&gt;Request: http://sampleapp/home.jsp?UID=000000000000003CF851D6CC68FC9537
Response: 200 OK&lt;/pre&gt;

&lt;p&gt;同样，我们从示意图中了解一下此时发生了什么：&lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/padding-oracle-attack-in-detail/po_fig7.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/padding-oracle-attack-in-detail/po_fig7.png" width="450" /&gt;&lt;/a&gt; 

&lt;p&gt;在这个情况下，我们便可以推断出中间值（Intermediary Value）的最后一个字节，因为我们知道它和0x3C异或后的结果为0x01，于是：&lt;/p&gt;

&lt;pre class="code"&gt;因为 [Intermediary Byte] ^ 0×3C == 0×01, 
得到 [Intermediary Byte] == 0×3C ^ 0×01, 
所以 [Intermediary Byte] == 0×3D&lt;/pre&gt;

&lt;p&gt;现在我们可以更进一步。我们已经知道了中间值的最后一个字节，于是我们可以推断出解密后的值是多少。您可以回忆一下，在解密的过程中，中间值的每个字节都会与密文中的前一个数据块（对于第一个数据块来说便是IV）的对应字节进行异或操作，于是我们使用之前示例中原来的IV中的最后一个字节（0x0F），与中间值异或一下便可以得到明文。不出意料，我们会得到0x32，这表示数字“2”（明文中第一个数据块的最后一个字节）。&lt;/p&gt;

&lt;p&gt;我们现在已经破解了示例数据块中的第8个字节，是时候关注第7个字节了。在破解第8个字节时，我们使用暴力枚举IV，让解密后的最后一个字节成为0x01（合法填充）。在破解第7个字节的时候，我们要做的事情也差不多，不过此时要求第7个字节与第8个字节都为0x02（再重复一遍，这表示合法的填充）。我们已经知道，中间值的最后一个字节是0x3D，因此我们可以将IV中的第8个字节设为0x3F（这会产生0x02）并暴力枚举IV的第七个字节（从0x00开始，直至0xFF）。&lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/padding-oracle-attack-in-detail/po_fig8.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/padding-oracle-attack-in-detail/po_fig8.png" width="450" /&gt;&lt;/a&gt; 

&lt;p&gt;我们再次遭遇填充异常，直至遇上某个值，它使得解密后的第7个字节成为0x02（正确填充），此时IV中的字节为0x24：&lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/padding-oracle-attack-in-detail/po_fig9.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/padding-oracle-attack-in-detail/po_fig9.png" width="450" /&gt;&lt;/a&gt; 

&lt;p&gt;使用这种技巧，我们可以从后往前破解中间值里的每个字节，最终得到解密后的值（尽管每次一个字节）。下图展示了完全破解后的IV值，此时整个数据块都为填充值（0x08）：&lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/padding-oracle-attack-in-detail/po_fig10.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/padding-oracle-attack-in-detail/po_fig10.png" width="450" /&gt;&lt;/a&gt; 

&lt;h1&gt;使用PadBuster进行解密&lt;/h1&gt;

&lt;p&gt;（译注：这段内容为PadBuster的使用指南，在此略过，如果您对这部分内容感兴趣可以阅读原文。）&lt;/p&gt;

&lt;h1&gt;加密任意的值&lt;/h1&gt;

&lt;p&gt;我们已经知道如何利用Padding Oracle和PadBuster来依次破解每个加密的数据块。现在，我们就来观察下如何使用同样的漏洞来加密任意数据。&lt;/p&gt;

&lt;p&gt;可能您已经发现，一旦我们可以推断出密文数据块的中间值，我们便能通过操作IV的值来完全控制解密所得到的结果。例如，在前面的示例中，如果想要将密文中第一个数据块解密为“TEST”这个值，您可以计算出它所需要的IV值，只要将目标明文与中间值进行异或操作即可。因此，只要您将字符串“TEST”（自然，还包括四个0x04字节作为填充）与中间值异或之后，便可以得到最终的IV，即0×6D，0×36，0×70，0×76，0×03，0×6E，0×22，0×39：&lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/padding-oracle-attack-in-detail/po_fig11.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/padding-oracle-attack-in-detail/po_fig11.png" width="450" /&gt;&lt;/a&gt; 

&lt;p&gt;这种做法对于单个数据块来说自然没有问题，但如果我们想要用它来生成长度超过一个数据块的值又该怎么办呢？我们来看一个简单通俗的实际案例。这次我们要生成一个加密的字符串“ENCRYPT TEST”而不仅仅是“TEST”。第一步，还是将文本分拆成数据块，并补上必须的填充字节，如下图：&lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/padding-oracle-attack-in-detail/po_fig12.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/padding-oracle-attack-in-detail/po_fig12.png" width="450" /&gt;&lt;/a&gt; 

&lt;p&gt;在构造超过一个数据块的值时，我们实际上是从最后一个数据块开始，向前依次生成所需的密文。在这里，最后的数据块与之前的相同，因此我们已经知道以下的IV和密文能够生成字符串“TEST”：&lt;/p&gt;

&lt;pre class="code"&gt;Request: http://sampleapp/home.jsp?UID=6D367076036E2239F851D6CC68FC9537&lt;/pre&gt;

&lt;p&gt;接下来，我们需要弄明白中间值6D367076036E2239在作为密文，而不是IV传递至应用程序时会被如何解密。在这里只要使用与破解过程相同的技巧就行了，我们把它作为密文传递给应用程序，并从全部为NULL的IV开始进行暴力破解：&lt;/p&gt;

&lt;pre class="code"&gt;Request: http://sampleapp/home.jsp?UID=00000000000000006D367076036E2239&lt;/pre&gt;

&lt;p&gt;一旦我们通过暴力破解得到中间值之后，IV便可以用来生成我们想要的任意值。新的IV可以被放在前一个示例的前面，这样便可以得到一个符合我们要求的，包含两个数据块的密文了。这个过程可以不断重复，这样便能生成任意长度的数据了。&lt;/p&gt;

&lt;h1&gt;使用PadBuster加密任意的值&lt;/h1&gt;

&lt;p&gt;（译注：这段内容为PadBuster的使用指南，在此略过，如果您对这部分内容感兴趣可以阅读原文。）&lt;/p&gt;</description>
      <comments>http://blog.zhaojie.me/2010/10/padding-oracle-attack-in-detail.html#comments</comments>
      <pubDate>Fri, 08 Oct 2010 16:20:05 GMT</pubDate>
      <lastBuildDate>Fri, 08 Oct 2010 16:20:05 GMT</lastBuildDate>
    </item>
    <item>
      <author>jeffz@live.com (老赵)</author>
      <category domain="http://blog.zhaojie.me/language/">语言编程</category>
      <category domain="http://blog.zhaojie.me/translation/">翻译引进</category>
      <category domain="http://blog.zhaojie.me/speech/">培训演讲</category>
      <title>编程语言的发展趋势及未来方向（7）：总结</title>
      <link>http://blog.zhaojie.me/2010/06/trends-and-future-directions-in-programming-languages-by-anders-7-conclusion.html</link>
      <guid>http://blog.zhaojie.me/2010/06/trends-and-future-directions-in-programming-languages-by-anders-7-conclusion.html</guid>
      <description>&lt;p&gt;这是&lt;a href="http://en.wikipedia.org/wiki/Anders_Hejlsberg"&gt;Anders Hejlsberg&lt;/a&gt;（不用介绍这是谁了吧）在&lt;a href="http://channel9.msdn.com/posts/adebruyn/TechDays-2010-Developer-Keynote-by-Anders-Hejlsberg/"&gt;比利时TechDays 2010所做的开场演讲&lt;/a&gt;。由于最近我在博客上关于语言的讨论比较多，出于应景，也打算将Anders的演讲完整地听写出来。在上一部分中，Anders谈论了“并发”，这也是他眼中编程语言发展的三种趋势之一，并演示了.NET 4.0中并行库的神奇效果。现在则是此次演讲的最后一部分，Anders对整场演讲内容进行了总结和回顾（本文较短，主要内容请参考之前的文章）。&lt;/p&gt;

&lt;p&gt;如果没有特别说明，所有的文字都直接翻译自Anders的演讲，并使用我自己的口语习惯表达出来，对于Anders的口误及反复等情况，必要时在译文中自然也会进行忽略。为了方便理解，我也会将视频中关键部分进行截图，而某些代码演示则会直接作为文章内容发表。 &lt;/p&gt;

&lt;p&gt;（听写开始，接&lt;a href="http://blog.zhaojie.me/2010/05/trends-and-future-directions-in-programming-languages-by-anders-6-concurrency.html"&gt;上篇&lt;/a&gt;）&lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/prog-lang-trends-anders/49.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/prog-lang-trends-anders/49-thumbnail.png" /&gt;&lt;/a&gt; 

&lt;p&gt;OK，我想现在已经讲的差不多了，我来做个总结吧。&lt;/p&gt;

&lt;p&gt;在我看来，对于编程语言来说，现在出现了许多有趣的东西，也是令人激动的时刻。在过去，大约1995-2005年，的确可以说是一个有些特别的编程语言的黄金时期。你知道，当Java出现的时候，编程语言的门槛变得平坦了，一切都是Java，天啊其他编程语言都完蛋了，我们也没什么可做的了。然后我们又逐渐发现，这远没有结束，现在回顾起来，会发现又出现了许多有趣的编程语言。我很兴奋，因为新语言代表了我们在编程领域上的进步。 &lt;/p&gt;

&lt;p&gt;如果要我概括在未来十年编程语言会变成什么样，首先，我认为编程语言应该变得更加“声明式”，我们需要设法为语言引入一些如元编程，函数式编程的能力，同时可能也要寻找让用户有办法扩展语法，使他们可以构造领域特定语言等等。我想在十年以后，动态语言和静态语言的区别也差不多会消失了，这两者会合并为一种单一的常见的编程范式。在并发方面，语言会采纳一些特性，可以利用起隔离性，函数式的纯粹性，以及更好的不可变数据类型的编写方式。不过总体来说我想强调的是，对于编程语言，新的范式则是“多范式”编程语言。 &lt;/p&gt;

&lt;p&gt;这就是我现在对编程语言的看法，希望我没有给你带来过多内容。如果你对C# 4.0有更多兴趣，今天下午一点我还有一个讲座。多谢捧场，希望你对这次会议感到满意。谢谢。&lt;/p&gt;

&lt;p&gt;（全场演讲到此结束）&lt;/p&gt;

&lt;h1&gt;相关文章&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://blog.zhaojie.me/2010/04/trends-and-future-directions-in-programming-languages-by-anders-1-history-and-trends.html"&gt;编程语言的发展趋势及未来方向（1）：历史回顾及趋势概述&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://blog.zhaojie.me/2010/04/trends-and-future-directions-in-programming-languages-by-anders-2-declarative-programming-and-dsl.html"&gt;编程语言的发展趋势及未来方向（2）：声明式编程与DSL&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://blog.zhaojie.me/2010/05/trends-and-future-directions-in-programming-languages-by-anders-3-functional-programming-and-fsharp.html"&gt;编程语言的发展趋势及未来方向（3）：函数式编程&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://blog.zhaojie.me/2010/05/trends-and-future-directions-in-programming-languages-by-anders-4-dynamic-languages.html"&gt;编程语言的发展趋势及未来方向（4）：动态语言&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://blog.zhaojie.me/2010/05/trends-and-future-directions-in-programming-languages-by-anders-5-meta-programming.html"&gt;编程语言的发展趋势及未来方向（5）：元编程&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://blog.zhaojie.me/2010/05/trends-and-future-directions-in-programming-languages-by-anders-6-concurrency.html"&gt;编程语言的发展趋势及未来方向（6）：并发&lt;/a&gt;&lt;/li&gt;

  &lt;li&gt;编程语言的发展趋势及未来方向（7）：总结&lt;/li&gt;
&lt;/ul&gt;</description>
      <comments>http://blog.zhaojie.me/2010/06/trends-and-future-directions-in-programming-languages-by-anders-7-conclusion.html#comments</comments>
      <pubDate>Sat, 05 Jun 2010 07:53:13 GMT</pubDate>
      <lastBuildDate>Sat, 05 Jun 2010 07:53:13 GMT</lastBuildDate>
    </item>
    <item>
      <author>jeffz@live.com (老赵)</author>
      <category domain="http://blog.zhaojie.me/language/">语言编程</category>
      <category domain="http://blog.zhaojie.me/translation/">翻译引进</category>
      <category domain="http://blog.zhaojie.me/speech/">培训演讲</category>
      <category domain="http://blog.zhaojie.me/dotnet/">.Net框架</category>
      <title>编程语言的发展趋势及未来方向（6）：并发</title>
      <link>http://blog.zhaojie.me/2010/05/trends-and-future-directions-in-programming-languages-by-anders-6-concurrency.html</link>
      <guid>http://blog.zhaojie.me/2010/05/trends-and-future-directions-in-programming-languages-by-anders-6-concurrency.html</guid>
      <description>&lt;p&gt;这是&lt;a href="http://en.wikipedia.org/wiki/Anders_Hejlsberg"&gt;Anders Hejlsberg&lt;/a&gt;（不用介绍这是谁了吧）在&lt;a href="http://channel9.msdn.com/posts/adebruyn/TechDays-2010-Developer-Keynote-by-Anders-Hejlsberg/"&gt;比利时TechDays 2010所做的开场演讲&lt;/a&gt;。由于最近我在博客上关于语言的讨论比较多，出于应景，也打算将Anders的演讲完整地听写出来。在上一部分中，Anders谈论了“元编程”及他正在努力的“编译器即服务”功能。在这一部分中，Anders则谈论了“并发”，这也是他眼中编程语言发展的三种趋势之一，并演示了.NET 4.0中并行库的神奇效果。&lt;/p&gt;

&lt;p&gt;如果没有特别说明，所有的文字都直接翻译自Anders的演讲，并使用我自己的口语习惯表达出来，对于Anders的口误及反复等情况，必要时在译文中自然也会进行忽略。为了方便理解，我也会将视频中关键部分进行截图，而某些代码演示则会直接作为文章内容发表。 &lt;/p&gt;

&lt;p&gt;（听写开始，接&lt;a href="http://blog.zhaojie.me/2010/05/trends-and-future-directions-in-programming-languages-by-anders-5-meta-programming.html"&gt;上篇&lt;/a&gt;）&lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/prog-lang-trends-anders/39.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/prog-lang-trends-anders/39-thumbnail.png" /&gt;&lt;/a&gt; 

&lt;p&gt;好，最后我想谈的内容是“并发”。 &lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/prog-lang-trends-anders/40.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/prog-lang-trends-anders/40-thumbnail.png" /&gt;&lt;/a&gt; 

&lt;p&gt;听说过摩尔定律的请举手……几乎是所有人。那么多少人听说了摩尔定律已经结束了呢？嗯，还是有很多人。我有好消息，也有坏消息。我认为摩尔定律并没有停止。摩尔定律说的是：可以在集成电路上低成本地放置晶体管的数目，约每两年便会增加一倍。有趣的是，这个定律从60年代持续到现在，而从一些迹象上来看，这个定律会继续保持20到30年。 &lt;/p&gt;

&lt;p&gt;摩尔定理有个推论，便是说时钟速度将根据相同的周期提高，也就是说每隔大约24个月，CPU的速度便会加倍──而这点已经停止了。再来统计一下，你们之中有谁的机器里有20GHz的CPU？看到了没？一个人都没有。但如果你从五年前开始计算的话，现在我们应该已经在使用20GHz的CPU了，但事实并非如此。这点在五年前就停止了，而且事实上最大速度还有些下降，因为发热量实在太大了，会消耗许多能源，让电池用的太快。 &lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/prog-lang-trends-anders/41.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/prog-lang-trends-anders/41-thumbnail.png" /&gt;&lt;/a&gt; 

&lt;p&gt;有些物理方面的基础因素让CPU不能运行的太快。然而，另一意义上的摩尔定理出现了。我们还是可以看到容量的增加，因为可以在同一个表盘上放置多个CPU了。目前已经有了双核、四核，Intel的CTO在三年前说，十年后我们可以出现80核的处理器。 &lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/prog-lang-trends-anders/42.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/prog-lang-trends-anders/42-thumbnail.png" /&gt;&lt;/a&gt; 

&lt;p&gt;到了那个时候，你的任务管理器中就可能是这样的。似乎有些吓人，不过这是我们实验室中真实存在的128核机器。你可以看到，计算能力已经完全用上了。这便是个问题，比如你在这台强大的机器上进行一个实验，你自然希望看到100%的使用状况，不过传统的实验都是在一个核上执行的，所以我们面临的挑战是，我们需要换一种写程序的方式来利用此类机器。 &lt;/p&gt;

&lt;p&gt;我的一个同事，Herb Sutter，他写过一篇文章，谈到“&lt;a href="http://www.gotw.ca/publications/concurrency-ddj.htm"&gt;免费的午餐已经结束了&lt;/a&gt;”。没错，我们已经不能写一个程序，然后对客户说：啊，未来的硬件会让它运行的越来越快，我们不用关心太多──不，已经不会这样了，除非你换种不同的写法。实话说，这是个挑战，也是个机遇。说它是个挑战，是因为并发十分困难，至今我们对此还没有简单的答案，稍后我会演示一些正有所改善的东西，但……这也是一个机遇，在这样的机器上，你的确可以用完所有的核，这样便能获得性能提高，不过做法需要有所不同。 &lt;/p&gt;

&lt;p&gt;多核革命的一个有趣之处在于，它对于并发的思维方式会有所改变。传统的并发思维是在单个CPU上执行多个逻辑任务，使用旧有的分时方式、时间片模型来执行多个任务。但是，你想一下便会发现如今的并发情况正好相反，现在是要将一个逻辑上的任务放在多个CPU上执行。这改变了我们编写程序的方式，这意味着对于语言或是API来说，我们需要有办法来分解任务，把它拆分成多个小任务后独立的执行，而传统的编程语言中并不关注这点。 &lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/prog-lang-trends-anders/43.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/prog-lang-trends-anders/43-thumbnail.png" /&gt;&lt;/a&gt; 

&lt;p&gt;使用目前的并发API来完成工作并不容易，比如使用Thread，ThreadPool，lock，Monitor等等，你无法太好的进展。不过.NET 4.0提供了一些美妙的事物，我们称之为.NET并行扩展。它是一种现代的并发模型，将逻辑上的任务并发与我们实际使用的的物理模型分离开来。以前我们的API都是直接处理线程，也就是（上图）下方橙色的部分，不过有了.NET并行扩展之后，你可以使用更为逻辑化的编程风格。任务并行库（Task Parallel Library），并行LINQ（Parallel LINQ）以及协调数据结构（Coordination Data Structures）让你可以直接关注逻辑上的任务，而不必关心它们是如何运行的，或是使用了多少个线程和CPU等等。 &lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/prog-lang-trends-anders/44.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/prog-lang-trends-anders/44-thumbnail.png" /&gt;&lt;/a&gt; 

&lt;p&gt;下面我来简单演示一下它们的使用方式。我带来了一个PLINQ演示，这里是一些代码，读取XML文件的内容。这有个50M大小的popname.xml文件，保存了美国社会安全数据库里的信息，包含某个洲在某一年的人口统计信息。这个程序会读取这个XML文件，把它转化成一系列对象，并存放在一个List中。然后对其执行一个LINQ语句，查找所有在华盛顿名叫Robert的人，再根据年份进行排序：&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;&amp;quot;Loading XML data...&amp;quot;&lt;/span&gt;);
&lt;span style="color: blue"&gt;var &lt;/span&gt;popNames =
    (&lt;span style="color: blue"&gt;from &lt;/span&gt;e &lt;span style="color: blue"&gt;in &lt;/span&gt;&lt;span style="color: #2b91af"&gt;XElement&lt;/span&gt;.Load(&lt;span style="color: #a31515"&gt;&amp;quot;popnames.xml&amp;quot;&lt;/span&gt;).Elements(&lt;span style="color: #a31515"&gt;&amp;quot;Name&amp;quot;&lt;/span&gt;)
     &lt;span style="color: blue"&gt;select new
     &lt;/span&gt;{
         Name = (&lt;span style="color: blue"&gt;string&lt;/span&gt;)e.Attribute(&lt;span style="color: #a31515"&gt;&amp;quot;Name&amp;quot;&lt;/span&gt;),
         State = (&lt;span style="color: blue"&gt;string&lt;/span&gt;)e.Attribute(&lt;span style="color: #a31515"&gt;&amp;quot;State&amp;quot;&lt;/span&gt;),
         Year = (&lt;span style="color: blue"&gt;int&lt;/span&gt;)e.Attribute(&lt;span style="color: #a31515"&gt;&amp;quot;Year&amp;quot;&lt;/span&gt;),
         Count = (&lt;span style="color: blue"&gt;int&lt;/span&gt;)e.Attribute(&lt;span style="color: #a31515"&gt;&amp;quot;Count&amp;quot;&lt;/span&gt;)
     })
    .ToList();

&lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(popNames.Count + &lt;span style="color: #a31515"&gt;&amp;quot; records&amp;quot;&lt;/span&gt;);
&lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine();

&lt;span style="color: blue"&gt;string &lt;/span&gt;targetName = &lt;span style="color: #a31515"&gt;&amp;quot;Robert&amp;quot;&lt;/span&gt;;
&lt;span style="color: blue"&gt;string &lt;/span&gt;targetState = &lt;span style="color: #a31515"&gt;&amp;quot;WA&amp;quot;&lt;/span&gt;;

&lt;span style="color: blue"&gt;var &lt;/span&gt;querySequential =
    &lt;span style="color: blue"&gt;from &lt;/span&gt;n &lt;span style="color: blue"&gt;in &lt;/span&gt;popNames
    &lt;span style="color: blue"&gt;where &lt;/span&gt;n.Name == targetName &amp;amp;&amp;amp; n.State == targetState
    &lt;span style="color: blue"&gt;orderby &lt;/span&gt;n.Year
    &lt;span style="color: blue"&gt;select &lt;/span&gt;n;&lt;/pre&gt;

&lt;p&gt;我们来执行一下……首先加载XML文件，然后进行查询。利用PLINQ我们可以做到并行地查询。我们只要拷贝一份代码……改成queryParallel……现在我唯一要做的只是在数据源上使用AsParallel扩展方法，这样便会引入一套新的类型和实现，此时相同的LINQ操作使用的便是并行的实现：&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;queryParallel =
    &lt;span style="color: blue"&gt;from &lt;/span&gt;n &lt;span style="color: blue"&gt;in &lt;/span&gt;popNames&lt;span style="background-color:yellow;"&gt;.AsParallel()&lt;/span&gt;
    &lt;span style="color: blue"&gt;where &lt;/span&gt;n.Name == targetName &amp;amp;&amp;amp; n.State == targetState
    &lt;span style="color: blue"&gt;orderby &lt;/span&gt;n.Year
    &lt;span style="color: blue"&gt;select &lt;/span&gt;n;&lt;/pre&gt;

&lt;p&gt;我们重新执行两个查询。 &lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/prog-lang-trends-anders/45.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/prog-lang-trends-anders/45-thumbnail.png" /&gt;&lt;/a&gt; 

&lt;p&gt;再次加载XML数据……并行实现使用了1.5秒，我们再试着运行一次，一般结果会更好一些，现在可能刚好在执行一些后台任务。一般我们可以得到更快的结果……这次比较接近了。现在你可以观察到，我们并不需要做太多事情，便可以在我的双核机器上得到并发的效果。 &lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/prog-lang-trends-anders/46.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/prog-lang-trends-anders/46-thumbnail.png" /&gt;&lt;/a&gt; 

&lt;p&gt;这里我无法保证说，我们只要随时加上AsParallel便可以得到两倍的性能，有时可以有时不行，有些查询能够被并行，有的则不可以。然而，我想你一定同意一点，使用如LINQ这样的DSL能够方便我们编写并行的代码，也更有可能利用起并行效果。虽然不是每次都有效，但是尝试的成本也很低。如果我们使用普通的for循环来编写代码，在某个地方使用线程池等等，便很容易在这些API里失去方向。而这里我们只要简单地尝试一下，便能知道是否可以提高性能了。 &lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/prog-lang-trends-anders/47.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/prog-lang-trends-anders/47-thumbnail.png" /&gt;&lt;/a&gt; 

&lt;p&gt;这里你已经看到我使用的LINQ查询，而现在也有很多工作是通过循环来完成的。你可以想象主要的运算是从哪里来的，很自然会是在循环里操作数据。如果循环的每个迭代都是独立的，便有很大的机会可以利用并发操作──我知道这里是“如果”，不过长期来看则一定会出现这样的情况。这时候便可以使用并行扩展，或者说是.NET并行扩展里的新API，把循环转化成并行的循环，只要简单的改变……几乎只要用同样的循环体把for重构成Parallel.For就行了。如果你有foreach操作就可以使用Parallel.ForEach，或是一系列顺序执行的语句也可以用上Parallel.Invoke。此时任务并行库会接管并执行这些任务，根据你的CPU数量使用最优化的线程数量，你不需要关注更深的细节，只需要编写逻辑就可以了。 &lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/prog-lang-trends-anders/48.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/prog-lang-trends-anders/48-thumbnail.png" /&gt;&lt;/a&gt; 

&lt;p&gt;就像我说的那样，可能你会有独立的任务但也可能没有，所以很多时候我们需要编程语言来关注这方面的事情。比如“隔离性（Isolation）”。例如，编译器如何发现这段代码是独立的，可以安全地并发执行，好比我创建了一个对象，在分享给其他人之前，我对它的改变是安全的。但是我一旦把它们共享出去了，那么它们便不安全了。所以如果我们的类型系统可以跟踪到这样的共享，如&lt;a href="http://en.wikipedia.org/wiki/Linear_type_system"&gt;Linear Types&lt;/a&gt;──这在学术界也有一些研究。我们也可以在函数的纯洁性（Purity）方面下功夫，如关注某个函数是否有副作用，有些时候编译器可以做这方面的检查，它可以禁止某些操作，以此保证我们写出纯函数。还有便是不可变性（Immutability），目前的C#或VB，我们需要额外的工作才能写出不可变的代码──但本不该这样，我们应该在语言层面上更好的支持不可变性。这些都是在并发方面需要考虑的问题。 &lt;/p&gt;

&lt;p&gt;如果说有哪个语言特性超出这个范畴，我想说这里还有一个原则：你不该期望C#中出现某个特别的并发模型，而应该是一种通用的，可用于各种不同的并发场景的特性，就像隔离性、纯洁性及不可变性那样。语言拥有这样的特性之后，就可以用于构建各种不同的API，各种并发方式都可以利用到核心的语言特性。&lt;/p&gt;

&lt;p&gt;（未完待续）&lt;/p&gt;

&lt;h1&gt;相关文章&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://blog.zhaojie.me/2010/04/trends-and-future-directions-in-programming-languages-by-anders-1-history-and-trends.html"&gt;编程语言的发展趋势及未来方向（1）：历史回顾及趋势概述&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://blog.zhaojie.me/2010/04/trends-and-future-directions-in-programming-languages-by-anders-2-declarative-programming-and-dsl.html"&gt;编程语言的发展趋势及未来方向（2）：声明式编程与DSL&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://blog.zhaojie.me/2010/05/trends-and-future-directions-in-programming-languages-by-anders-3-functional-programming-and-fsharp.html"&gt;编程语言的发展趋势及未来方向（3）：函数式编程&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://blog.zhaojie.me/2010/05/trends-and-future-directions-in-programming-languages-by-anders-4-dynamic-languages.html"&gt;编程语言的发展趋势及未来方向（4）：动态语言&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://blog.zhaojie.me/2010/05/trends-and-future-directions-in-programming-languages-by-anders-5-meta-programming.html"&gt;编程语言的发展趋势及未来方向（5）：元编程&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;编程语言的发展趋势及未来方向（6）：并发&lt;/li&gt;

  &lt;li&gt;&lt;a href="http://blog.zhaojie.me/2010/06/trends-and-future-directions-in-programming-languages-by-anders-7-conclusion.html"&gt;编程语言的发展趋势及未来方向（7）：总结&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <comments>http://blog.zhaojie.me/2010/05/trends-and-future-directions-in-programming-languages-by-anders-6-concurrency.html#comments</comments>
      <pubDate>Sun, 30 May 2010 14:53:05 GMT</pubDate>
      <lastBuildDate>Sun, 30 May 2010 14:53:05 GMT</lastBuildDate>
    </item>
    <item>
      <author>jeffz@live.com (老赵)</author>
      <category domain="http://blog.zhaojie.me/language/">语言编程</category>
      <category domain="http://blog.zhaojie.me/translation/">翻译引进</category>
      <category domain="http://blog.zhaojie.me/speech/">培训演讲</category>
      <title>编程语言的发展趋势及未来方向（5）：元编程</title>
      <link>http://blog.zhaojie.me/2010/05/trends-and-future-directions-in-programming-languages-by-anders-5-meta-programming.html</link>
      <guid>http://blog.zhaojie.me/2010/05/trends-and-future-directions-in-programming-languages-by-anders-5-meta-programming.html</guid>
      <description>&lt;p&gt;这是&lt;a href="http://en.wikipedia.org/wiki/Anders_Hejlsberg"&gt;Anders Hejlsberg&lt;/a&gt;（不用介绍这是谁了吧）在&lt;a href="http://channel9.msdn.com/posts/adebruyn/TechDays-2010-Developer-Keynote-by-Anders-Hejlsberg/"&gt;比利时TechDays 2010所做的开场演讲&lt;/a&gt;。由于最近我在博客上关于语言的讨论比较多，出于应景，也打算将Anders的演讲完整地听写出来。在上一部分中，Anders谈及了他眼中编程语言的另一个发展趋势：动态性。在这一部分中，Anders则讨论了动态语言所擅长的“元编程”，并简单介绍了他为静态类型语言所设计的一种改进方案：编译器即服务。&lt;/p&gt;

&lt;p&gt;如果没有特别说明，所有的文字都直接翻译自Anders的演讲，并使用我自己的口语习惯表达出来，对于Anders的口误及反复等情况，必要时在译文中自然也会进行忽略。为了方便理解，我也会将视频中关键部分进行截图，而某些代码演示则会直接作为文章内容发表。&lt;/p&gt;

&lt;p&gt;（听写开始，接&lt;a href="http://blog.zhaojie.me/2010/05/trends-and-future-directions-in-programming-languages-by-anders-4-dynamic-languages.html"&gt;上篇&lt;/a&gt;）&lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/prog-lang-trends-anders/36.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/prog-lang-trends-anders/36-thumbnail.png" /&gt;&lt;/a&gt; 

&lt;p&gt;动态语言的另一个关键和有趣之处在于“&lt;a href="http://en.wikipedia.org/wiki/Metaprogramming"&gt;元编程&lt;/a&gt;”。“元编程”实际上是“代码生成”的一种别称，其实在日常应用中我们也经常依赖这种做法。观察动态语言适合元编程的原因也是件十分有趣的事情。 &lt;/p&gt;

&lt;p&gt;在这个蓝框中是一段Ruby on Rails代码（见上图）。简单地说，这里定义了一个Order类，继承了ActiveRecord，也定义了一些关系，如belongs_to和has_many关系。Ruby这种动态语言的关键之处，在于一切事物都是通过执行而得到的，包括类型声明。比如这里的类型申明执行了belongs_to和has_many方法的调用，执行belongs_to会截获一对多或一对一关系所需要的信息，因此在这里语言是在运行的时候，动态为自身生成了代码。 &lt;/p&gt;

&lt;p&gt;实现这点在动态语言里自然会更容易一些，因为它们没有编译期和执行期的区别。静态类型语言在这方面会比较困难。例如在C#或Java里使用ORM时，传统的做法是让代码生成器去观察数据库，生成一大堆代码，然后再编译，有些复杂。不过我时常想着去改善这一点。&lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/prog-lang-trends-anders/37.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/prog-lang-trends-anders/37-thumbnail.png" /&gt;&lt;/a&gt; 

&lt;p&gt;其中一种做法，是我们正在努力实现的“编译器即服务”，我现在先对它进行一些简单的介绍。传统的编译器像是一个黑盒，你在一端输入代码，而另一端便会生成.NET程序集或是对象代码等等。而这个黑盒却很神秘，你目前很难参与或理解它的工作。 &lt;/p&gt;

&lt;p&gt;你可以想象，一些代码往往是不包含在源文件中的。如果你想要交互式编程的体验，例如一个交互式的提示符，那么代码不是保存在源文件中而是由用户输入的。如果您在实现一个DSL，例如Windows Workflow或是Biztalk，则可能用C#或VB实现了一些需要动态执行的规则，它们也不是保存在源文件中，而可能是放在XML属性中的。此时你想编译它们却做不到，你还是要把它们放入源文件，这就变的复杂了。&lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/prog-lang-trends-anders/38.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/prog-lang-trends-anders/38-thumbnail.png" /&gt;&lt;/a&gt; 

&lt;p&gt;另一方面，对于编译器来说，我们不一定需要它生成程序集，有时候需要的是一些树状的表现形式。例如一些由用户反射生成的代码，便可能不要程序集而是一个解析树，然后可以对它进行识别和重写。因此，我们可能越来越需要的是一些API，以此开放编译器的功能。 &lt;/p&gt;

&lt;p&gt;例如，你可以给它一小段代码，让它返回一段可执行的程序，或是一个可以识别或重写的解析树。这么做可以让静态类型语言获得许多有用的功能，例如元编程，以及可操作的完整的对象模型等等。我们正在朝这方面努力，我也会在下午1点的C# 4.0演讲中谈论更多这方面的内容。&lt;/p&gt;

&lt;p&gt;（未完待续）&lt;/p&gt;

&lt;h1&gt;相关文章&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://blog.zhaojie.me/2010/04/trends-and-future-directions-in-programming-languages-by-anders-1-history-and-trends.html"&gt;编程语言的发展趋势及未来方向（1）：历史回顾及趋势概述&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://blog.zhaojie.me/2010/04/trends-and-future-directions-in-programming-languages-by-anders-2-declarative-programming-and-dsl.html"&gt;编程语言的发展趋势及未来方向（2）：声明式编程与DSL&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://blog.zhaojie.me/2010/05/trends-and-future-directions-in-programming-languages-by-anders-3-functional-programming-and-fsharp.html"&gt;编程语言的发展趋势及未来方向（3）：函数式编程&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://blog.zhaojie.me/2010/05/trends-and-future-directions-in-programming-languages-by-anders-4-dynamic-languages.html"&gt;编程语言的发展趋势及未来方向（4）：动态语言&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;编程语言的发展趋势及未来方向（5）：元编程&lt;/li&gt;

  &lt;li&gt;&lt;a href="http://blog.zhaojie.me/2010/05/trends-and-future-directions-in-programming-languages-by-anders-6-concurrency.html"&gt;编程语言的发展趋势及未来方向（6）：并发&lt;/a&gt;&lt;/li&gt;

  &lt;li&gt;&lt;a href="http://blog.zhaojie.me/2010/06/trends-and-future-directions-in-programming-languages-by-anders-7-conclusion.html"&gt;编程语言的发展趋势及未来方向（7）：总结&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <comments>http://blog.zhaojie.me/2010/05/trends-and-future-directions-in-programming-languages-by-anders-5-meta-programming.html#comments</comments>
      <pubDate>Sun, 30 May 2010 09:42:13 GMT</pubDate>
      <lastBuildDate>Sun, 30 May 2010 09:42:13 GMT</lastBuildDate>
    </item>
    <item>
      <author>jeffz@live.com (老赵)</author>
      <category domain="http://blog.zhaojie.me/language/">语言编程</category>
      <category domain="http://blog.zhaojie.me/translation/">翻译引进</category>
      <category domain="http://blog.zhaojie.me/speech/">培训演讲</category>
      <title>编程语言的发展趋势及未来方向（4）：动态语言</title>
      <link>http://blog.zhaojie.me/2010/05/trends-and-future-directions-in-programming-languages-by-anders-4-dynamic-languages.html</link>
      <guid>http://blog.zhaojie.me/2010/05/trends-and-future-directions-in-programming-languages-by-anders-4-dynamic-languages.html</guid>
      <description>&lt;p&gt;这是&lt;a href="http://en.wikipedia.org/wiki/Anders_Hejlsberg"&gt;Anders Hejlsberg&lt;/a&gt;（不用介绍这是谁了吧）在&lt;a href="http://channel9.msdn.com/posts/adebruyn/TechDays-2010-Developer-Keynote-by-Anders-Hejlsberg/"&gt;比利时TechDays 2010所做的开场演讲&lt;/a&gt;。由于最近我在博客上关于语言的讨论比较多，出于应景，也打算将Anders的演讲完整地听写出来。在上一部分中，Anders谈及了声明式编程的另一个重要组成部分：函数式编程，并使用.NET平台上的函数式编程语言F#进行了演示。在这一部分中，Anders讨论了动态语言及JavaScript的相关内容，“动态性”也是Anders眼中编程语言的发展趋势之一。&lt;/p&gt;

&lt;p&gt;如果没有特别说明，所有的文字都直接翻译自Anders的演讲，并使用我自己的口语习惯表达出来，对于Anders的口误及反复等情况，必要时在译文中自然也会进行忽略。为了方便理解，我也会将视频中关键部分进行截图，而某些代码演示则会直接作为文章内容发表。&lt;/p&gt;

&lt;p&gt;（听写开始，接&lt;a href="http://blog.zhaojie.me/2010/05/trends-and-future-directions-in-programming-languages-by-anders-3-functional-programming-and-fsharp.html"&gt;上篇&lt;/a&gt;）&lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/prog-lang-trends-anders/26.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/prog-lang-trends-anders/26-thumbnail.png" /&gt;&lt;/a&gt; 

&lt;p&gt;我下面继续要讲的是动态语言，这也是我之前提到的三种趋势之一。 &lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/prog-lang-trends-anders/27.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/prog-lang-trends-anders/27-thumbnail.png" /&gt;&lt;/a&gt; 

&lt;p&gt;我还是尝试着去找到动态语言的定义，但是你也知道……一般地说，动态语言是一些不对编译时和运行时进行严格区分的语言。这不像一些静态编程语言，比如C#，你先进行编译，然后会得到一些编译期错误，稍后再执行，而对于动态语言来说这两个阶段便混合在一起了。我们都熟悉一些动态语言，比如JavaScript，Python，Ruby，LISP等等。 &lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/prog-lang-trends-anders/28.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/prog-lang-trends-anders/28-thumbnail.png" /&gt;&lt;/a&gt; 

&lt;p&gt;动态语言有一些优势，而静态语言也有着另一些优势，这也是两个阵营争论多年的内容。老实讲，我认为结果不是两者中的任意一个，它们都有各自十分重要的优点，而长期来看，我认为结果应该是两者的杂交产物，我认为在语言发展中也可以看到这样的趋势，这两部分内容正在合并。 &lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/prog-lang-trends-anders/29.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/prog-lang-trends-anders/29-thumbnail.png" /&gt;&lt;/a&gt; 

&lt;p&gt;许多人认定动态语言执行起来很慢，也没有类型安全等等。我想在这里观察并比较一下，究竟是什么原因会让静态语言和动态语言在这方面有不同的性质。这里有一段有趣的代码，它的语法在JavaScript和C#里都是正确的，这样我们便能比较两种语言是如何处理这段代码的。 &lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/prog-lang-trends-anders/30.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/prog-lang-trends-anders/30-thumbnail.png" /&gt;&lt;/a&gt; 

&lt;p&gt;首先我们把它看作是一段C#代码，它只是用for循环把一堆整数相加，你肯定不会这么做，这只是一个示例。在C#中，当我们使用var关键字时，它表示“请为我推断这里的类型”，所以在这里a和i的类型都是int。 &lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/prog-lang-trends-anders/31.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/prog-lang-trends-anders/31-thumbnail.png" /&gt;&lt;/a&gt; 

&lt;p&gt;这断代码在执行的时候，这两个值都是32位整数，而for循环只是简单的使用ADD指令即可，执行起来自然效率很高。 &lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/prog-lang-trends-anders/32.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/prog-lang-trends-anders/32-thumbnail.png" /&gt;&lt;/a&gt; 

&lt;p&gt;但如果从JavaScript或是动态语言的角度来看……或者说对于动态类型的语言来说，var只代表了“一个值”，它可以是任意类型，我们不知道它究竟是什么。所以当我们使用var a或var i时，我们只是定义了两个值，其中包含了一个“类型”标记，表明在运行时它是个什么类型。在这里它是一个int，因此包含了存储int值的空间。但有些时候，例如要存储一个double值，那么可能便需要更多的空间，还可能是一个字符串，于是便包含一个引用。 &lt;/p&gt;

&lt;p&gt;所以两者的区别之一便是，表示同样的值在动态语言中会有一些额外的开销，代价较高。而在如今的CPU中，“空间”便等于“速度”，所以较大的值便需要较长时间进行处理，这里便损失了一部分效率。 &lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/prog-lang-trends-anders/33.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/prog-lang-trends-anders/33-thumbnail.png" /&gt;&lt;/a&gt; 

&lt;p&gt;在JavaScript中，我们如果要处理a加i，那么便不仅仅是一个ADD指令。首先它必须查看两个变量中的类型标记，然后根据类型选择合适的相加操作。于是再去加载两个值，然后再进行加法操作。这里还需要进行越界检查，因为在JavaScript中一旦越界了便要使用double，等等。很明显在这里也有许多开销。一般来说，动态语言是使用解释器来执行的，因此还有一些解释器需要的二进制码。你把这些开销全部加起来以后，便会发现执行代码时需要10倍到100倍的开销。 &lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/prog-lang-trends-anders/34.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/prog-lang-trends-anders/34-thumbnail.png" /&gt;&lt;/a&gt; 

&lt;p&gt;不过由于近几年来出现的一些动态虚拟机或引擎，目前这些情况改善了许多。比方说，这是传统的情况（上图左），如在IE 6或IE 7里使用的非常缓慢的解释器。目前的情况是，大部分的JavaScript引擎使用了JIT编译器（上图中），于是便省下了解释器的开销，这样性能损失便会减小至3到10倍。而在过去的两三年间，JIT编译器也变得越来越高效，浏览器中新一代的适应性JIT编译器（上图右），如&lt;a href="https://wiki.mozilla.org/JavaScript:TraceMonkey"&gt;TraceMonkey&lt;/a&gt;，&lt;a href="http://code.google.com/p/v8/"&gt;V8&lt;/a&gt;，还有如今&lt;a href="http://blogs.msdn.com/ie/archive/2010/03/18/the-new-javascript-engine-in-internet-explorer-9.aspx"&gt;微软在IE 9中使用的Chakra引擎&lt;/a&gt;。这种适应性的JIT编译器使用了一部分有趣的技术，如Inline Caching、Type Specialization、Hidden Classes、Tracing等等，它们可以将开销降低至2到3倍的范围内，这种效率的提升可谓十分神奇。 &lt;/p&gt;

&lt;p&gt;在我看来，JavaScript引擎可能已经接近了性能优化的极限，我们在效率上可以提升的空间已经不多。不过我同样认为，如今JavaScript语言的性能已经足够快了，完全有能力统治Web客户端。 &lt;/p&gt;

&lt;p&gt;有人认为，JavaScript从来不是一种适合进行大规模编程的语言。如今也有一些有趣的工具，如&lt;a href="http://code.google.com/webtoolkit/"&gt;Google Web Tookit&lt;/a&gt;，在微软&lt;a href="http://www.nikhilk.net/"&gt;Nikhil Kothari&lt;/a&gt;也创建了&lt;a href="http://projects.nikhilk.net/ScriptSharp"&gt;Script#&lt;/a&gt;，让你可以编写C#或Java代码，然后将代码编译成JavaScript，这就像是将JavaScript当作是一种中间语言。Google Wave的所有代码都用GWT写成，它的团队坚持认为用JavaScript不可能完成这样的工作，因为复杂度实在太高了。如今在这方面还有一些有趣的开发成果，我不清楚什么时候会结束。不过我认为，这些都不算是大规模的JavaScript开发方案，而编写C#或Java代码再生成JavaScript的方式也不能算是完全正确的做法。我们可以关注这方面的走向。 &lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/prog-lang-trends-anders/35.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/prog-lang-trends-anders/35-thumbnail.png" /&gt;&lt;/a&gt; 

&lt;p&gt;在.NET 4.0的运行时进行动态编程时，我们引入了一个新功能：&lt;a href="http://dlr.codeplex.com/"&gt;动态语言运行时&lt;/a&gt;。可以这样理解，CLR的目的是为静态类型的编程语言提供一个统一的框架或编程模型，而DLR便是在.NET平台上为动态语言提供了统一的编程模型。CLR本身已经有一些支持动态编程能力，如反射，Emit等等。不过在.NET上实现动态语言的时候，总会一遍又一遍地去实现某些功能，还有如动态语言如何与静态语言进行交互，这些都由DLR来提供。DLR的特性包含了，如表达式树、动态分发、Call Site缓存，这可以提高动态代码的执行效率。&lt;/p&gt;

&lt;p&gt;在.NET 4.0中我们使用了DLR，不仅仅是IronPython和IronRuby，还有C# 4和VB.NET 10，它们使用DLR实现动态分发功能。因此我们共享了语言的动态能力实现方式，于是这些语言之间可以轻松地进行交互。同样我们可以与其他多样性的技术进行交互，例如使用JavaScript操作Silverlight的DOM，或是与Ruby、Python代码沟通，甚至用来控制Office等自动化服务。&lt;/p&gt;

&lt;p&gt;（未完待续）&lt;/p&gt;

&lt;h1&gt;相关文章&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://blog.zhaojie.me/2010/04/trends-and-future-directions-in-programming-languages-by-anders-1-history-and-trends.html"&gt;编程语言的发展趋势及未来方向（1）：历史回顾及趋势概述&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://blog.zhaojie.me/2010/04/trends-and-future-directions-in-programming-languages-by-anders-2-declarative-programming-and-dsl.html"&gt;编程语言的发展趋势及未来方向（2）：声明式编程与DSL&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://blog.zhaojie.me/2010/05/trends-and-future-directions-in-programming-languages-by-anders-3-functional-programming-and-fsharp.html"&gt;编程语言的发展趋势及未来方向（3）：函数式编程&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;编程语言的发展趋势及未来方向（4）：动态语言&lt;/li&gt;

  &lt;li&gt;&lt;a href="http://blog.zhaojie.me/2010/05/trends-and-future-directions-in-programming-languages-by-anders-5-meta-programming.html"&gt;编程语言的发展趋势及未来方向（5）：元编程&lt;/a&gt;&lt;/li&gt;

  &lt;li&gt;&lt;a href="http://blog.zhaojie.me/2010/05/trends-and-future-directions-in-programming-languages-by-anders-6-concurrency.html"&gt;编程语言的发展趋势及未来方向（6）：并发&lt;/a&gt;&lt;/li&gt;

  &lt;li&gt;&lt;a href="http://blog.zhaojie.me/2010/06/trends-and-future-directions-in-programming-languages-by-anders-7-conclusion.html"&gt;编程语言的发展趋势及未来方向（7）：总结&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <comments>http://blog.zhaojie.me/2010/05/trends-and-future-directions-in-programming-languages-by-anders-4-dynamic-languages.html#comments</comments>
      <pubDate>Sun, 23 May 2010 14:16:22 GMT</pubDate>
      <lastBuildDate>Sun, 23 May 2010 14:16:22 GMT</lastBuildDate>
    </item>
    <item>
      <author>jeffz@live.com (老赵)</author>
      <category domain="http://blog.zhaojie.me/language/">语言编程</category>
      <category domain="http://blog.zhaojie.me/translation/">翻译引进</category>
      <category domain="http://blog.zhaojie.me/speech/">培训演讲</category>
      <title>编程语言的发展趋势及未来方向（3）：函数式编程</title>
      <link>http://blog.zhaojie.me/2010/05/trends-and-future-directions-in-programming-languages-by-anders-3-functional-programming-and-fsharp.html</link>
      <guid>http://blog.zhaojie.me/2010/05/trends-and-future-directions-in-programming-languages-by-anders-3-functional-programming-and-fsharp.html</guid>
      <description>&lt;p&gt;这是&lt;a href="http://en.wikipedia.org/wiki/Anders_Hejlsberg"&gt;Anders Hejlsberg&lt;/a&gt;（不用介绍这是谁了吧）在&lt;a href="http://channel9.msdn.com/posts/adebruyn/TechDays-2010-Developer-Keynote-by-Anders-Hejlsberg/"&gt;比利时TechDays 2010所做的开场演讲&lt;/a&gt;。由于最近我在博客上关于语言的讨论比较多，出于应景，也打算将Anders的演讲完整地听写出来。在上一部分中，Anders阐述了他眼中声明式编程的理念及DSL，并演示C#中一种内部DSL的形式：LINQ。在这一部分中，Anders谈及了声明式编程的另一个重要组成部分：函数式编程，并使用.NET平台上的函数式编程语言F#进行了演示。&lt;/p&gt;

&lt;p&gt;如果没有特别说明，所有的文字都直接翻译自Anders的演讲，并使用我自己的口语习惯表达出来，对于Anders的口误及反复等情况，必要时在译文中自然也会进行忽略。为了方便理解，我也会将视频中关键部分进行截图，而某些代码演示则会直接作为文章内容发表。&lt;/p&gt;

&lt;p&gt;（听写开始，接&lt;a href="http://blog.zhaojie.me/2010/04/trends-and-future-directions-in-programming-languages-by-anders-2-declarative-programming-and-dsl.html"&gt;上篇&lt;/a&gt;）&lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/prog-lang-trends-anders/17.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/prog-lang-trends-anders/17-thumbnail.png" /&gt;&lt;/a&gt; 

&lt;p&gt;关于声明式编程的还有一部分重要的内容，那便是&lt;a href="http://en.wikipedia.org/wiki/Functional_programming"&gt;函数式编程&lt;/a&gt;。函数式编程已经有很长时间的历史了，当年&lt;a href="http://en.wikipedia.org/wiki/Lisp_programming_language"&gt;LISP&lt;/a&gt;便是个函数式编程语言。除了LISP以外我们还有其他许多函数式编程语言，如&lt;a href="http://en.wikipedia.org/wiki/APL_programming_language"&gt;APL&lt;/a&gt;、&lt;a href="http://en.wikipedia.org/wiki/Haskell_(programming_language)"&gt;Haskell&lt;/a&gt;、&lt;a href="http://en.wikipedia.org/wiki/Scheme_(programming_language)"&gt;Scheme&lt;/a&gt;、&lt;a href="http://en.wikipedia.org/wiki/ML_programming_language"&gt;ML&lt;/a&gt;等等。关于函数式编程在学术界已经有过许多研究了，在大约5到10年前许多人开始吸收和整理这些研究内容，想要把它们融入更为通用的编程语言。现在的编程语言，如C#、Python、Ruby、&lt;a href="http://www.scala-lang.org/"&gt;Scala&lt;/a&gt;等等，它们都受到了函数式编程语言的影响。&lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/prog-lang-trends-anders/18.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/prog-lang-trends-anders/18-thumbnail.png" /&gt;&lt;/a&gt; 

&lt;p&gt;我想在这里先花几分钟时间简单介绍一下我眼中的函数式编程语言。我发现很多人听说过函数式编程语言，但还不十分清楚它们和普通的命令式编程语言究竟有什么区别。如今我们在使用命令式编程语言写程序时，我们经常会写这样的语句，嗨，x等于x加一，此时我们大量依赖的是状态，可变的状态，或者说变量，它们的值可以随程序运行而改变。 &lt;/p&gt;

&lt;p&gt;可变状态非常强大，但随之而来的便是叫做“副作用”的问题。在使用可变状态时，你的程序则会包含副作用，比如你会写一个无需参数的void方法，然后它会根据你的调用次数或是在哪个线程上进行调用对程序产生影响，因为void方法会改变程序内部的状态，从而影响之后的运行效果。 &lt;/p&gt;

&lt;p&gt;而在函数式编程中则不会出现这个情况，因为所有的状态都是不可变的。你可以声明一个状态，但是不能改变这个状态。而且由于你无法改变它，所以在函数式编程中不需要变量。事实上对函数式编程的讨论更像是数学、公式，而不像是程序语句。如果你把x = x + 1这句话交给一个程序员看，他会说“啊，你在增加x的值”，而如果你把它交给一个数学家看，他会说“嗯，我知道这不是true”。&lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/prog-lang-trends-anders/19.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/prog-lang-trends-anders/19-thumbnail.png" /&gt;&lt;/a&gt; 

&lt;p&gt;然而，如果你给他看这条语言，他会说“啊，y等于x加一，就是把x + 1的计算结果交给y，你是为这个计算指定了一个名字”。这时候在思考时就是另一种方式了，这里y不是一个变量，它只是x + 1的名称，它不会改变，永远代表了x + 1。 &lt;/p&gt;

&lt;p&gt;所以在函数式编程语言中，当你写了一个函数，接受一些参数，那么当你调用这个函数时，影响函数调用的只是你传进去的参数，而你得到的也只是计算结果。在一个纯函数式编程语言中，函数在计算时不会对进行一些神奇的改变，它只会使用你给它的参数，然后返回结果。在函数式编程语言中，一个void方法是没有意义的，它唯一的作用只是让你的CPU发热，而不能给你任何东西，也不会有副作用。当然现在你可能会说，这个CPU发多少热也是一个副作用，好吧，不过我们现在先不讨论这个问题。&lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/prog-lang-trends-anders/20.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/prog-lang-trends-anders/20-thumbnail.png" /&gt;&lt;/a&gt; 

&lt;p&gt;这里的关键在于，你解决问题的方法和以前大不一样了。我这里还是用代码来说明问题。使用函数式语言写没有副作用的代码，就好比在Java或C#中使用final或是readonly的成员。 &lt;/p&gt;

&lt;p&gt;例如这里，我们有一个Point类，构造函数接受x和y，还有一个MoveBy方法，可以把一个点移动一些位置。 在传统的命令式编程中，我们会改变Point实例的状态，这么做在平时可能不会有什么问题。但是，如果我把一个Point对象同时交给3个API使用，然后我修改了Point，那么如何才能告诉它们状态改变了呢？可能我们可以使用事件，blablabla，如果我们没有事件，那么就会出现那些不愉快的副作用了。 &lt;/p&gt;

&lt;p&gt;那么使用函数式编程的形式写代码，你的Point类还是可以包含状态，例如x和y，不过它们是readonly的，一旦初始化以后就不能改变了。MoveBy方法不能改变Point对象，它只能创建一个新的Point对象并返回出来。这就是一个创建新Point对象的函数，不是吗？这样就可以让调用者来决定是使用新的还是旧的Point对象，但这里不会有产生副作用的情况出现。 &lt;/p&gt;

&lt;p&gt;在函数式编程里自然不会只有Point对象，例如我们会有集合，如Dictionary，Map，List等等，它们都是不可变的。在函数式编程中，当我们向一个List里添加元素时，我们会得到一个新的List，它包含了新增的元素，但之前的List依然存在。所以这些数据结构的实现方式是有根本性区别的，它们的内部结构会设法让这类操作变的尽可能高效。 &lt;/p&gt;

&lt;p&gt;在函数式编程中访问状态是十分安全的，因为状态不会改变，我可以把一个Point或List对象交给任意多的地方去访问，完全不用担心副作用。函数式编程的十分容易并行，因为我在运行时不会修改状态，因此无论多少线程在运行时都可以观察到正确的状态。两个函数完全无关，因此它们是并行还是顺序地执行便没有什么区别了。我们还可以有延迟计算，可以进行Memorization，这些都是函数式编程中十分有趣的方面。 &lt;/p&gt;

&lt;p&gt;你可能会说，那么我们为什么不都用这种方法来写程序呢？嗯，最终，就像我之前说的那样，我们不能只让CPU发热，我们必须要把计算结果表现出来。那么我们在屏幕上打印内容时，或者把数据写入文件或是Socket时，其实就产生了副作用。因此真实世界中的函数式编程，往往都是把纯粹的部分进行隔离，或是进行更细致的控制。事实上也不会有真正纯粹的函数式编程语言，它们都会带来一定的副作用或是命令式编程的能力。但是，它们默认是函数式的，例如在函数式编程语言中，所有东西默认都是不可变的，你必须做些额外的事情才能使用可变状态或是产生危险的副作用。此时你的编程观念便会有所不同了。&lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/prog-lang-trends-anders/21.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/prog-lang-trends-anders/21-thumbnail.png" /&gt;&lt;/a&gt; 

&lt;p&gt;我们在自己的环境中开发出了这样一个函数式编程语言，F#，已经包含在VS 2010中了。F#诞生于微软剑桥研究院，由&lt;a href="http://blogs.msdn.com/dsyme/"&gt;Don Syme&lt;/a&gt;提出，他在F#上已经工作了5到10年了。F#使用了另一个函数式编程语言OCaml的常见核心部分，因此它是一个强类型语言，并支持一些如模式匹配，类型推断等现代函数式编程语言的特性。在此之上，F#又增加了异步工作流，度量单位等较为前沿的语言功能。 &lt;/p&gt;

&lt;p&gt;而F#最为重要的一点可能是，在我看来，它是第一个和工业级的框架和工具集，如.NET和Visual Studio，有深入集成的函数式编程语言。F#允许你使用整个.NET框架，它和C#也有类似的执行期特征，例如强类型，而且都会生成高效的代码等等。我想，现在应该是展示一些F#代码的时候了。&lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/prog-lang-trends-anders/22.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/prog-lang-trends-anders/22-thumbnail.png" /&gt;&lt;/a&gt; 

&lt;p&gt;首先我想先从F#中我最喜欢的特性讲起，这是个F#命令行……（打开命令行窗口以及一个F#源文件）……F#包含了一个交互式的命令行，这允许你直接输入代码并执行。例如输入5……x等于5……然后x……显示出x的值是5。然后让sqr x等于x乘以x，于是我这里定义了一个简单的函数，名为sqr。于是我们就可以计算sqr 5等于25，sqr 10等于100。 &lt;/p&gt;

&lt;p&gt;F#的使用方式十分动态，但事实上它是一个强类型的编程语言。我们再来看看这里。这里我定义了一个计算平方和的函数sumSquares，它会遍历每个列表中每个元素，平方后再把它们相加。让我先用命令式的方式编写这个函数，再使用函数式的方式，这样你可以看出其中的区别。&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;let &lt;/span&gt;sumSquaresI l = 
    &lt;span style="color: blue"&gt;let mutable &lt;/span&gt;acc = 0
    &lt;span style="color: blue"&gt;for &lt;/span&gt;x &lt;span style="color: blue"&gt;in &lt;/span&gt;l &lt;span style="color: blue"&gt;do
        &lt;/span&gt;acc &lt;- acc + sqr x
    acc&lt;/pre&gt;

&lt;p&gt;这里先是命令式的代码，我们先创建一个累加器acc为0，然后遍历列表l，把平方加到acc中，然后最后我返回acc。有几件事情值得注意，首先为了创建一个可变的状态，我必须显式地使用mutable进行声明，在默认情况下这是不可变的。&lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/prog-lang-trends-anders/23.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/prog-lang-trends-anders/23-thumbnail.png" /&gt;&lt;/a&gt; 

&lt;p&gt;还有一点，这段代码里我没有提供任何的类型信息。当我把鼠标停留在方法上时，就会显示sumSquaresI方法接受一个int序列作为参数并返回一个int。你可能会想int是哪里来的，嗯，它是由类型推断而来的。编译器从这里的0发现acc必须是一个int，于是它发现这里的加号表示两个int的相加，于是sqr函数返回的是个int，再接下来blablabla……最终它发现这里到处都是int。&lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/prog-lang-trends-anders/24.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/prog-lang-trends-anders/24-thumbnail.png" /&gt;&lt;/a&gt; 

&lt;p&gt;如果我把这里修改为浮点数0.0，鼠标再停留一下，你就会发现这个函数接受和返回的类型都变成float了。所以这里的类型推断功能十分强大，也十分方便。&lt;/p&gt;
&lt;a href="http://img.zhaojie.me/blog/prog-lang-trends-anders/25.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/prog-lang-trends-anders/25-thumbnail.png" /&gt;&lt;/a&gt; 

&lt;p&gt;现在我可以选择这个函数，让它在命令行里执行，然后调用sumSquaresI，提供1到100的序列，就能得到结果了。&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;let rec &lt;/span&gt;sumSquaresF l = 
    &lt;span style="color: blue"&gt;match &lt;/span&gt;l &lt;span style="color: blue"&gt;with
    &lt;/span&gt;| [] &lt;span style="color: blue"&gt;-&gt; &lt;/span&gt;0
    | h :: t &lt;span style="color: blue"&gt;-&gt; &lt;/span&gt;sqr h + sumSquaresF t&lt;/pre&gt;

&lt;p&gt;那么现在我们来换一种函数式的风格。这里是另一种写法，可以说是纯函数式的实现方式。如果你去理解这段代码，你会发现有不少数学的感觉。这里我定义了sumSqauresF函数，输入一个l列表，然后使用下面的模式去匹配l。如果它为空，则结果为0，否则把列表匹配为头部和尾部，然后便将头部的平方和尾部的平方和相加。 &lt;/p&gt;

&lt;p&gt;你会发现，在计算时我不会去改变任何一个变量的值，我只是创建新的值。我这里会使用递归，就像在数学里我们经常使用递归，把一个公式分解成几个变化的形式，以此进行递归的定义。在编程时我们也使用递归的做法，然后编译器会设法帮我们转化成尾递归或是循环等等。 &lt;/p&gt;

&lt;p&gt;于是我们便可以执行sumSquaresF函数，也可以得到相同的结果。当然实际上可能你并不会像之前这样写代码，你可能会使用高阶函数：&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;let &lt;/span&gt;sumSquares l = Seq.sum (Seq.map (&lt;span style="color: blue"&gt;fun &lt;/span&gt;x &lt;span style="color: blue"&gt;-&gt; &lt;/span&gt;x * x) l )&lt;/pre&gt;

&lt;p&gt;例如这里，我只是把函数x乘以x映射到列表上，然后相加。这样也可以得到相同的结果，而且这可能是更典型的做法。我这里只是想说明，这个语言在编程时可能会给你带来完全不同的感受，虽然它的执行期特征和C#比较接近。 &lt;/p&gt;

&lt;p&gt;这便是关于F#的内容。&lt;/p&gt;

&lt;p&gt;（未完待续）&lt;/p&gt;

&lt;h1&gt;相关文章&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://blog.zhaojie.me/2010/04/trends-and-future-directions-in-programming-languages-by-anders-1-history-and-trends.html"&gt;编程语言的发展趋势及未来方向（1）：历史回顾及趋势概述&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://blog.zhaojie.me/2010/04/trends-and-future-directions-in-programming-languages-by-anders-2-declarative-programming-and-dsl.html"&gt;编程语言的发展趋势及未来方向（2）：声明式编程与DSL&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;编程语言的发展趋势及未来方向（3）：函数式编程&lt;/li&gt;

  &lt;li&gt;&lt;a href="http://blog.zhaojie.me/2010/05/trends-and-future-directions-in-programming-languages-by-anders-4-dynamic-languages.html"&gt;编程语言的发展趋势及未来方向（4）：动态语言&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://blog.zhaojie.me/2010/05/trends-and-future-directions-in-programming-languages-by-anders-5-meta-programming.html"&gt;编程语言的发展趋势及未来方向（5）：元编程&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://blog.zhaojie.me/2010/05/trends-and-future-directions-in-programming-languages-by-anders-6-concurrency.html"&gt;编程语言的发展趋势及未来方向（6）：并发&lt;/a&gt;&lt;/li&gt;

  &lt;li&gt;&lt;a href="http://blog.zhaojie.me/2010/06/trends-and-future-directions-in-programming-languages-by-anders-7-conclusion.html"&gt;编程语言的发展趋势及未来方向（7）：总结&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <comments>http://blog.zhaojie.me/2010/05/trends-and-future-directions-in-programming-languages-by-anders-3-functional-programming-and-fsharp.html#comments</comments>
      <pubDate>Tue, 04 May 2010 11:09:21 GMT</pubDate>
      <lastBuildDate>Tue, 04 May 2010 11:09:21 GMT</lastBuildDate>
    </item>
    <item>
      <author>jeffz@live.com (老赵)</author>
      <category domain="http://blog.zhaojie.me/language/">语言编程</category>
      <category domain="http://blog.zhaojie.me/translation/">翻译引进</category>
      <category domain="http://blog.zhaojie.me/speech/">培训演讲</category>
      <title>编程语言的发展趋势及未来方向（2）：声明式编程与DSL</title>
      <link>http://blog.zhaojie.me/2010/04/trends-and-future-directions-in-programming-languages-by-anders-2-declarative-programming-and-dsl.html</link>
      <guid>http://blog.zhaojie.me/2010/04/trends-and-future-directions-in-programming-languages-by-anders-2-declarative-programming-and-dsl.html</guid>
      <description>&lt;p&gt;这是&lt;a href="http://en.wikipedia.org/wiki/Anders_Hejlsberg"&gt;Anders Hejlsberg&lt;/a&gt;（不用介绍这是谁了吧）在&lt;a href="http://channel9.msdn.com/posts/adebruyn/TechDays-2010-Developer-Keynote-by-Anders-Hejlsberg/"&gt;比利时TechDays 2010所做的开场演讲&lt;/a&gt;。由于最近我在博客上关于语言的讨论比较多，出于应景，也打算将Anders的演讲完整地听写出来。在上一部分中，Anders指出语言本身在过去的数十年里并没有明显的发展，并给出了他眼中编程语言发展趋势的预测。在现在的第2部分中，Anders将阐述声明式编程的理念及DSL，并演示C#中一种内部DSL的形式：LINQ。&lt;/p&gt;  &lt;p&gt;如果没有特别说明，所有的文字都直接翻译自Anders的演讲，并使用我自己的口语习惯表达出来，对于Anders的口误及反复等情况，必要时在译文中自然也会进行忽略。为了方便理解，我也会将视频中关键部分进行截图，而某些代码演示则会直接作为文章内容发表。&lt;/p&gt;  &lt;p&gt;（听写开始，接&lt;a href="http://blog.zhaojie.me/2010/04/trends-and-future-directions-in-programming-languages-by-anders-1-history-and-trends.html"&gt;上篇&lt;/a&gt;）&lt;/p&gt; &lt;a target="_blank" href="http://img.zhaojie.me/blog/prog-lang-trends-anders/9.png"&gt;&lt;img src="http://img.zhaojie.me/blog/prog-lang-trends-anders/9-thumbnail.png" /&gt;&lt;/a&gt;   &lt;p&gt;这里先从&lt;a href="http://en.wikipedia.org/wiki/Declarative_programming"&gt;声明式（Declarative）编程&lt;/a&gt;谈起。 &lt;/p&gt; &lt;a target="_blank" href="http://img.zhaojie.me/blog/prog-lang-trends-anders/10.png"&gt;&lt;img src="http://img.zhaojie.me/blog/prog-lang-trends-anders/10-thumbnail.png" /&gt;&lt;/a&gt;   &lt;p&gt;目前我们在编写软件时大量使用的是&lt;a href="http://en.wikipedia.org/wiki/Imperative_programming"&gt;命令式（Imperative）编程&lt;/a&gt;语言，例如C#，Java或是C++等等。这些语言的特征在于，写出的代码除了表现出“什么（What）”是你想做的事情之外，更多的代码则表现出实现的细节，也就是“如何（How）”完成工作。这部分代码有时候多到掩盖了我们原来问题的解决方案。比如，你会在代码里写for循环，if语句，a等于b，i加一等等，这体现出机器是如何处理数据。首先，这种做法让代码变得冗余，而且它也很难让执行代码的基础设施更聪明地判断该如何去执行代码。当你写出这样的命令是代码，然后把编译后的中间语言交给虚拟机去执行，此时虚拟机并没有多少空间可以影响代码的执行方式，它只能根据指令一条一条老老实实地去执行。例如，我们现在想要并行地执行程序就很困难了，因为更高层次的一些信息已经丢失了。这样，我们只能在代码里给出“How”，而不能体现出“What”的信息。 &lt;/p&gt;  &lt;p&gt;有多种方式可以将“What”转化为更为“声明式”的编程风格，我们只要能够在代码中体现出更多“What”，而不是“How”的信息，这样执行环境便可以更加聪明地去适应当前的执行要求。例如，它可以决定投入多少CPU进行计算，你的当前硬件是什么样的，等等。 &lt;/p&gt; &lt;a target="_blank" href="http://img.zhaojie.me/blog/prog-lang-trends-anders/11.png"&gt;&lt;img src="http://img.zhaojie.me/blog/prog-lang-trends-anders/11-thumbnail.png" /&gt;&lt;/a&gt;   &lt;p&gt;我之前提到过，现在有两种比较重要的成果，一是&lt;a href="http://en.wikipedia.org/wiki/Domain-specific_language"&gt;DSL&lt;/a&gt;（Domain Specific Language，领域特定语言），另一个则是&lt;a href="http://en.wikipedia.org/wiki/Functional_programming"&gt;函数式编程&lt;/a&gt;。 &lt;/p&gt;  &lt;p&gt;其实DSL不是什么新鲜的玩意儿，我们平时一直在用类似的东西，比如，SQL，CSS，正则表达式，有的可能更加专注于一个方面，例如&lt;a href="http://en.wikipedia.org/wiki/Mathematica"&gt;Mathematica&lt;/a&gt;，&lt;a href="http://en.wikipedia.org/wiki/Logo_%28programming_language%29"&gt;LOGO&lt;/a&gt;等等。这些语言的目标都是特定的领域，与之相对的则是&lt;a href="http://en.wikipedia.org/wiki/General-purpose_programming_language"&gt;GPPL&lt;/a&gt;（General Purpose Programming Language，通用目的编程语言）。 &lt;/p&gt; &lt;a target="_blank" href="http://img.zhaojie.me/blog/prog-lang-trends-anders/12.png"&gt;&lt;img src="http://img.zhaojie.me/blog/prog-lang-trends-anders/12-thumbnail.png" /&gt;&lt;/a&gt;   &lt;p&gt;对于DSL而言其实并没有一个明确的定义，在这里我也不打算为它下个定义，例如&lt;a href="http://en.wikipedia.org/wiki/Unified_Modeling_Language"&gt;UML&lt;/a&gt;甚至根本没有特定的语法。不过我这里会谈一些我觉得比较重要的东西。 &lt;/p&gt; &lt;a target="_blank" href="http://img.zhaojie.me/blog/prog-lang-trends-anders/13.png"&gt;&lt;img src="http://img.zhaojie.me/blog/prog-lang-trends-anders/13-thumbnail.png" /&gt;&lt;/a&gt;   &lt;p&gt;&lt;a href="http://martinfowler.com/"&gt;Martin Fowler&lt;/a&gt;提出DSL应该分为外部DSL及内部DSL两种，我认为这种划分方式还是比较有意义的。外部DSL是自我包含的语言，它们有自己特定语法、解析器和词法分析器等等，它往往是一种小型的编程语言，甚至不会像GPPL那样需要源文件。与之相对的则是内部DSL。内部DSL其实更像是种别称，它代表一类特别API及使用模式。这里我会给你们看一些示例。 &lt;/p&gt; &lt;a target="_blank" href="http://img.zhaojie.me/blog/prog-lang-trends-anders/14.png"&gt;&lt;img src="http://img.zhaojie.me/blog/prog-lang-trends-anders/14-thumbnail.png" /&gt;&lt;/a&gt;   &lt;p&gt;这些是我们平时会遇到的一些外部DSL，如这张幻灯片上表现的XSLT，SQL或是Unix脚本。外部DSL的特点是，你在构建这种DSL时，其实扮演的是编程语言设计者的角色，这个工作并不会交给普通人去做。外部DSL一般会直接针对特定的领域设计，而不考虑其他东西。&lt;a href="http://en.wikipedia.org/wiki/James_Gosling"&gt;James Gosling&lt;/a&gt;曾经说过这样的话，每个配置文件最终都会变成一门编程语言。你一开始可能只会用它表示一点点东西，然后慢慢你便会想要一些规则，而这些规则则变成了表达式，可能你还会定义变量，进行条件判断等等。而最终它就变成了一种奇怪的编程语言，这样的情况屡见不鲜。 &lt;/p&gt;  &lt;p&gt;事实上，现在有一些公司也在关注DSL的开发。例如以前在微软工作的&lt;a href="http://en.wikipedia.org/wiki/Charles_Simonyi"&gt;Charles Simonyi&lt;/a&gt;提出了&lt;a href="http://en.wikipedia.org/wiki/Intentional_programming"&gt;Intentional Programming&lt;/a&gt;的概念，还有一个叫做&lt;a href="http://en.wikipedia.org/wiki/JetBrains"&gt;JetBrains&lt;/a&gt;的公司提供一个叫做&lt;a href="http://en.wikipedia.org/wiki/JetBrains_MPS"&gt;MPS（Meta Programming System）&lt;/a&gt;的产品。最近微软也提出了自己的&lt;a href="http://en.wikipedia.org/wiki/Oslo_%28Microsoft%29"&gt;Oslo&lt;/a&gt;项目，而在Eclipse世界里也有个叫做&lt;a href="http://www.eclipse.org/Xtext/"&gt;Xtext&lt;/a&gt;的东西，所以其实在这方面现在也有不少人在尝试。 &lt;/p&gt;  &lt;p&gt;我在观察外部DSL时，往往会关注它的语法到底提供了多少空间，例如一种XML的方言，利用XML方言的好处在于有不少现成的工具可用，这样可以更快地定义自己的语法。 &lt;/p&gt; &lt;a target="_blank" href="http://img.zhaojie.me/blog/prog-lang-trends-anders/15.png"&gt;&lt;img src="http://img.zhaojie.me/blog/prog-lang-trends-anders/15-thumbnail.png" /&gt;&lt;/a&gt;   &lt;p&gt;而内部DSL，正像我之前说的那样，它其实只是一系列特别的API及使用模式的别称。这里则是一些LINQ查询语句，&lt;a href="http://rubyonrails.org/"&gt;Ruby on Rails&lt;/a&gt;以及&lt;a href="http://jquery.com/"&gt;jQuery&lt;/a&gt;代码。内部DSL的特点是，它其实只是一系列API，但是你可以“假装”它们一种DSL。内部DSL往往会利用一些“流畅化”的技巧，例如像这里的LINQ或jQuery那样把一些方法通过“点”连接起来。有些则利用了元编程的方式，如这里的Ruby on Rails就涉及到了一些元编程。这种DSL可以访问语言中的代码或变量，以及利用如代码补全，重构等母语言的所有特性。 &lt;/p&gt; &lt;a target="_blank" href="http://img.zhaojie.me/blog/prog-lang-trends-anders/16.png"&gt;&lt;img src="http://img.zhaojie.me/blog/prog-lang-trends-anders/16-thumbnail.png" /&gt;&lt;/a&gt;   &lt;p&gt;现在我会花几分钟时间演示一下我所创建的DSL，也就是LINQ。我相信你们也已经用过不少LINQ了，不过这里我还是快速的展示一下我所表达的更为“声明式”的编程方式。&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Product
&lt;/span&gt;{
    &lt;span style="color: blue"&gt;public int &lt;/span&gt;ProductID { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }
    &lt;span style="color: blue"&gt;public string &lt;/span&gt;ProductName { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }
    &lt;span style="color: blue"&gt;public string &lt;/span&gt;CategoryName { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }
    &lt;span style="color: blue"&gt;public int &lt;/span&gt;UnitPrice { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }

    &lt;span style="color: blue"&gt;public static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&lt;&lt;span style="color: #2b91af"&gt;Product&lt;/span&gt;&gt; GetProducts() { &lt;span style="color: green"&gt;/* ... */ &lt;/span&gt;}
}

&lt;span style="color: blue"&gt;public partial class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;_Default &lt;/span&gt;: System.Web.UI.&lt;span style="color: #2b91af"&gt;Page
&lt;/span&gt;{
    &lt;span style="color: blue"&gt;protected void &lt;/span&gt;Page_Load(&lt;span style="color: blue"&gt;object &lt;/span&gt;sender, &lt;span style="color: #2b91af"&gt;EventArgs &lt;/span&gt;e)
    {
        &lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&lt;&lt;span style="color: #2b91af"&gt;Product&lt;/span&gt;&gt; products = &lt;span style="color: #2b91af"&gt;Product&lt;/span&gt;.GetProducts();

        &lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&lt;&lt;span style="color: #2b91af"&gt;Product&lt;/span&gt;&gt; result = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&lt;&lt;span style="color: #2b91af"&gt;Product&lt;/span&gt;&gt;();
        &lt;span style="color: blue"&gt;foreach &lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Product &lt;/span&gt;p &lt;span style="color: blue"&gt;in &lt;/span&gt;products)
        {
            &lt;span style="color: blue"&gt;if &lt;/span&gt;(p.UnitPrice &gt; 20) result.Add(p);
        }

        GridView1.DataSource = result;
        GridView1.DataBind();
    }
}&lt;/pre&gt;

&lt;p&gt;这里有许多Product对象，那么现在我要筛选出所有单价大于20的那些， 再把他们显示在一个GridView中。传统的做法就是这样，我先得到所有的Product对象，然后foreach遍历每个对象，再判断每个对象的单价，最终把数据绑定到GridView里。运行这个程序……（打开页面）这就是就能得到结果。 &lt;/p&gt;

&lt;p&gt;好，那么现在我要做一些稍微复杂的事情。可能我不是要展示单价超过20的Product对象，而是要查看每个分类中究竟有多少个单价超过20的对象，然后根据数量进行排序。如果不用DSL完成这个工作，那么我可能会先定义一个对象来表示结果：&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Grouping
&lt;/span&gt;{
    &lt;span style="color: blue"&gt;public string &lt;/span&gt;CategoryName { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }
    &lt;span style="color: blue"&gt;public int &lt;/span&gt;ProductCount { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }
}&lt;/pre&gt;

&lt;p&gt;这是个表示分组的对象，用于保存分类的名称和产品数量。然后我们就会写一些十分丑陋的代码：&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: #2b91af"&gt;Dictionary&lt;/span&gt;&lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;Grouping&lt;/span&gt;&gt; groups = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Dictionary&lt;/span&gt;&lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;Grouping&lt;/span&gt;&gt;();
&lt;span style="color: blue"&gt;foreach &lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Product &lt;/span&gt;p &lt;span style="color: blue"&gt;in &lt;/span&gt;products)
{
    &lt;span style="color: blue"&gt;if &lt;/span&gt;(p.UnitPrice &gt;= 20)
    {
        &lt;span style="color: blue"&gt;if &lt;/span&gt;(!groups.ContainsKey(p.CategoryName))
        {
            &lt;span style="color: #2b91af"&gt;Grouping &lt;/span&gt;r = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Grouping&lt;/span&gt;();
            r.CategoryName = p.CategoryName;
            r.ProductCount = 0;
            groups[p.CategoryName] = r;
        }
        groups[p.CategoryName].ProductCount++;
    }
}

&lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&lt;&lt;span style="color: #2b91af"&gt;Grouping&lt;/span&gt;&gt; result = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&lt;&lt;span style="color: #2b91af"&gt;Grouping&lt;/span&gt;&gt;(groups.Values);
result.Sort(&lt;span style="color: blue"&gt;delegate&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Grouping &lt;/span&gt;x, &lt;span style="color: #2b91af"&gt;Grouping &lt;/span&gt;y)
{
    &lt;span style="color: blue"&gt;return
        &lt;/span&gt;x.ProductCount &gt; y.ProductCount ? -1 :
        x.ProductCount &lt; y.ProductCount ? 1 :
        0;
});&lt;/pre&gt;

&lt;p&gt;我先创建一个新的字典，用于保存分类名称到分组的对应关系。然后我遍历每个Product对象，对于每个单价大于20的对象，如果字典中还没有保存对应的分组则创建一个，然后将数量加一。然后为了排序，我调用Sort方法，于是我要提供一个委托作为排序方法，然后blablablabla……执行之后……（打开页面）我自然可以得到想要的结果。 &lt;/p&gt;

&lt;p&gt;但是，首先这些代码写起来需要花费一些时间，很显然。然后仔细观察，你会发现这写代码几乎都是在表示“How”，而“What”基本已经丢失了。假设我离开了，现在新来了一个程序员要维护这段代码，他会需要一点时间才能完整理解这段代码，因为他无法直接看清代码的目标。 &lt;/p&gt;

&lt;p&gt;不过如果这里我们使用DSL，也就是LINQ，就像这样：&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;result = products
    .Where(p =&gt; p.UnitPrice &gt;= 20)
    .GroupBy(p =&gt; p.CategoryName)
    .OrderByDescending(g =&gt; g.Count())
    .Select(g =&gt; &lt;span style="color: blue"&gt;new &lt;/span&gt;{ CategoryName = g.Key, ProductCount = g.Count() });&lt;/pre&gt;

&lt;p&gt;products……先调用Where……blablabla……再GroupBy等等。由于我们这里可以使用DSL来表示高阶的术语，用以体现我们想做的事情。于是这段代码则更加关注于“What”而不是“How”。我这里不会明确地指示我想要过滤的方式，我也不会明确地说我要建立字典和分类，这样基础结构就可以聪明地，或者说更加聪明地去确定具体的执行方式。你可能比较容易想到我们可以并行地执行这段代码，因为我没有显式地指定做事方式，我只是表示出我的意图。 &lt;/p&gt;

&lt;p&gt;我们打开页面……（打开页面）很显然我们得到了相同的结果。 &lt;/p&gt;

&lt;p&gt;这里比较有趣的是，内部DSL是如何设计进C#语法中的，为此我们为C# 3.0添加了一系列的特性，例如Lambda表达式，扩展方法，类型推断等等。这些特性统一起来之后，我们就可以设计出更为丰富的API，组合之后便成为一种内部DSL，就像这里的LINQ查询语言。 &lt;/p&gt;

&lt;p&gt;除了使用API的形式之外，我们还可以这样做：&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;result =
    &lt;span style="color: blue"&gt;from &lt;/span&gt;p &lt;span style="color: blue"&gt;in &lt;/span&gt;products
    &lt;span style="color: blue"&gt;where &lt;/span&gt;p.UnitPrice &gt;= 20
    &lt;span style="color: blue"&gt;group &lt;/span&gt;p &lt;span style="color: blue"&gt;by &lt;/span&gt;p.CategoryName &lt;span style="color: blue"&gt;into &lt;/span&gt;g
    &lt;span style="color: blue"&gt;orderby &lt;/span&gt;g.Count() &lt;span style="color: blue"&gt;descending
    select new &lt;/span&gt;{ CategoryName = g.Key, ProductCount = g.Count() };&lt;/pre&gt;

&lt;p&gt;编译器会简单地将这种形式转化为前一种形式。不过，这里我认为有意思的地方在于，你完全可以创建一门和领域编程语言完全无关的语法，然后等这种语法和API变得流行且丰富起来之后，再来创一种新的表现形式，就如这里的LINQ查询语法。我颇为中意这种语言设计的交流方式。 &lt;/p&gt;

&lt;p&gt;OK，现在我们回到下面的内容。&lt;/p&gt;

&lt;p&gt;（未完待续）&lt;/p&gt;

&lt;h1&gt;相关文章&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://blog.zhaojie.me/2010/04/trends-and-future-directions-in-programming-languages-by-anders-1-history-and-trends.html"&gt;编程语言的发展趋势及未来方向（1）：历史回顾及趋势概述&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;编程语言的发展趋势及未来方向（2）：声明式编程与DSL&lt;/li&gt;

  &lt;li&gt;&lt;a href="http://blog.zhaojie.me/2010/05/trends-and-future-directions-in-programming-languages-by-anders-3-functional-programming-and-fsharp.html"&gt;编程语言的发展趋势及未来方向（3）：函数式编程&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://blog.zhaojie.me/2010/05/trends-and-future-directions-in-programming-languages-by-anders-4-dynamic-languages.html"&gt;编程语言的发展趋势及未来方向（4）：动态语言&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://blog.zhaojie.me/2010/05/trends-and-future-directions-in-programming-languages-by-anders-5-meta-programming.html"&gt;编程语言的发展趋势及未来方向（5）：元编程&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://blog.zhaojie.me/2010/05/trends-and-future-directions-in-programming-languages-by-anders-6-concurrency.html"&gt;编程语言的发展趋势及未来方向（6）：并发&lt;/a&gt;&lt;/li&gt;

  &lt;li&gt;&lt;a href="http://blog.zhaojie.me/2010/06/trends-and-future-directions-in-programming-languages-by-anders-7-conclusion.html"&gt;编程语言的发展趋势及未来方向（7）：总结&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <comments>http://blog.zhaojie.me/2010/04/trends-and-future-directions-in-programming-languages-by-anders-2-declarative-programming-and-dsl.html#comments</comments>
      <pubDate>Wed, 14 Apr 2010 13:24:51 GMT</pubDate>
      <lastBuildDate>Wed, 14 Apr 2010 13:24:51 GMT</lastBuildDate>
    </item>
    <item>
      <author>jeffz@live.com (老赵)</author>
      <category domain="http://blog.zhaojie.me/language/">语言编程</category>
      <category domain="http://blog.zhaojie.me/translation/">翻译引进</category>
      <category domain="http://blog.zhaojie.me/speech/">培训演讲</category>
      <title>编程语言的发展趋势及未来方向（1）：历史回顾及趋势概述</title>
      <link>http://blog.zhaojie.me/2010/04/trends-and-future-directions-in-programming-languages-by-anders-1-history-and-trends.html</link>
      <guid>http://blog.zhaojie.me/2010/04/trends-and-future-directions-in-programming-languages-by-anders-1-history-and-trends.html</guid>
      <description>&lt;p&gt;这是&lt;a href="http://en.wikipedia.org/wiki/Anders_Hejlsberg"&gt;Anders Hejlsberg&lt;/a&gt;（不用介绍这是谁了吧）在&lt;a href="http://channel9.msdn.com/posts/adebruyn/TechDays-2010-Developer-Keynote-by-Anders-Hejlsberg/"&gt;比利时TechDays 2010所做的开场演讲&lt;/a&gt;。由于最近我在博客上关于语言的讨论比较多，出于应景，也打算将Anders的演讲完整地听写出来。我希望这个讲座可以从侧面回答某些朋友关于“语言讨论是否有价值”的疑问，并且展示出目前语言的发展状况以及微软在这方面的努力。完整内容将分为多次发表，每次一小部分，包含大约10分钟的演讲内容。等不及的朋友也和可以下载演讲视频一睹为快。现在的第1部分则包含Anders对编程语言发展的历史回顾，以及对趋势简单概述。&lt;/p&gt;  &lt;p&gt;如果没有特别说明，所有的文字都直接翻译自Anders的演讲，并使用我自己的口语习惯表达出来，对于Anders的口误及反复等情况，必要时在译文中自然也会进行忽略。为了方便理解，我也会将视频中关键部分进行截图，而某些代码演示则会直接作为文章内容发表。&lt;/p&gt;  &lt;p&gt;（听写开始）&lt;/p&gt; &lt;a href="http://img.zhaojie.me/blog/prog-lang-trends-anders/0.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/prog-lang-trends-anders/0-thumbnail.png" /&gt;&lt;/a&gt;   &lt;p&gt;大家好，我是Anders Hejlsberg，现在是微软的&lt;a href="http://www.microsoft.com/presspass/exec/techfellow/default.mspx"&gt;Technical Fellow&lt;/a&gt;，担任C#编程语言的首席架构师，也参与并领导.NET Framework以及各种语言的开发。我现在打算谈一下……实际上是我脑海中一些影响未来5到10年编程语言设计的内容。比如C#或VB该怎么走，&lt;a href="http://research.microsoft.com/en-us/um/cambridge/projects/fsharp/"&gt;F#&lt;/a&gt;该怎么办，这次演讲主要就是讨论这些影响我们的东西。&lt;/p&gt; &lt;a href="http://img.zhaojie.me/blog/prog-lang-trends-anders/1.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/prog-lang-trends-anders/1-thumbnail.png" /&gt;&lt;/a&gt;   &lt;p&gt;虽然主要内容是谈论未来的，但是我还是想先回顾一下历史。你们有些人可能对这个产品有印象，这是我大约27年前的工作内容，&lt;a href="http://en.wikipedia.org/wiki/Turbo_Pascal"&gt;Turbo Pascal&lt;/a&gt;，这也是我进入这个领域的起点。我先在拿出这个东西是想展示当年写程序的情况，然后可以讨论目前究竟的发展到哪儿了。&lt;/p&gt; &lt;a href="http://img.zhaojie.me/blog/prog-lang-trends-anders/2.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/prog-lang-trends-anders/2-thumbnail.png" /&gt;&lt;/a&gt;   &lt;p&gt;事实上，我现在的机器里正好有TURBO.COM文件，大约39K，嘿，现在还可以运行。我们现在来试着写一点程序。先来创建的程序叫做Hello.pas……（开始写代码）……一个Pascal小程序写好了，我们来运行一下……（出现编译错误）啊噢，有地方我写错了……这个特性在当年是个创新，它会自动打开编辑器，直接把我们带去出错的地方。嗯，我们现在来纠正语法错误，把双引号改成单引号。&lt;/p&gt; &lt;a href="http://img.zhaojie.me/blog/prog-lang-trends-anders/3.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/prog-lang-trends-anders/3-thumbnail.png" /&gt;&lt;/a&gt;   &lt;p&gt;再运行一下，现在成功了，（观众掌声）呵呵，谢谢，谢谢。事实上，在27年后这个程序还能在这台机器上运行还真是挺神奇的。&lt;/p&gt; &lt;a href="http://img.zhaojie.me/blog/prog-lang-trends-anders/4.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/prog-lang-trends-anders/4-thumbnail.png" /&gt;&lt;/a&gt;   &lt;p&gt;现在，我们来看一下，从那时算起硬件已经发展了……嗯，我那时写Pascal的机器是&lt;a href="http://en.wikipedia.org/wiki/Zilog_Z80"&gt;Z-80&lt;/a&gt;，拥有48K内存。从那时算起，我现在这台机器已经有大约10万倍的外部存储容量，1万倍的内存大小，CPU速度也有大约1000倍的提高。&lt;/p&gt; &lt;a href="http://img.zhaojie.me/blog/prog-lang-trends-anders/5.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/prog-lang-trends-anders/5-thumbnail.png" /&gt;&lt;/a&gt;   &lt;p&gt;但是如果你关注一下目前的软件……过去27年里编程语言到底进步了多少？呵呵，有趣的是如果你仔细观察这些代码，会发现C#还比Turbo Pascal的版本多一行。这也给我们带来了一些值得关注的东西。&lt;/p&gt; &lt;a href="http://img.zhaojie.me/blog/prog-lang-trends-anders/6.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/prog-lang-trends-anders/6-thumbnail.png" /&gt;&lt;/a&gt;   &lt;p&gt;首先，编程语言的发展非常缓慢。期间当然出现了一些东西，例如面向对象等等，但是远没有好上1000倍。另一方面，你可能会想，那么这些努力都到哪里去了呢？事实上这些努力没有体现在编程语言上，而是出现在框架及工具等方面了。如果你关注如今我们使用的框架，它们的体积的确有1000倍的增长。例如当年Turbo Pascal所带的框架大约有，比如说100个功能，而现在的.NET Framework里则有一万个类，十万个方法，的确有1000倍的增长。与此类似，如果你观察现在的IDE，我们现在已经有了无数强大的功能，例如语法提示，重构，调试器，探测器等等，这方面的新东西有很多。与此相比，编程语言的改进的确很不明显。&lt;/p&gt;  &lt;p&gt;另一方面，如.NET，Java等框架的重要性提高了许多。而编程语言往往都倾向于构建于现有的工具上，而不会从头写起。现在出现的编程语言，例如F#，如果你关注Java领域那么还有&lt;a href="http://www.scala-lang.org/"&gt;Scala&lt;/a&gt;，&lt;a href="http://clojure.org/"&gt;Clojure&lt;/a&gt;等等，它们都是基于现有框架构建的。现在已经有太多东西可以直接利用了，每次从头开始的代价实在太高。&lt;/p&gt; &lt;a href="http://img.zhaojie.me/blog/prog-lang-trends-anders/7.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/prog-lang-trends-anders/7-thumbnail.png" /&gt;&lt;/a&gt;   &lt;p&gt;还有件事，便是在过去5、60年的编程历史中，我们都不断地提高抽象级别，我们都在不断地让编程语言更有表现力，让我们可以用更少的代码完成更多的工作。我们一开始先使用汇编，然后使用面向过程的语言，例如Pascal和C，然后便是面向对象语言，如C++，随后就进入了托管时代──受托管的执行环境，例如.NET，Java，它们的主要特性有自动的垃圾收集，类型安全等等。我目前还没有看出这样的趋势有停止的迹象，因此我们还会看到抽象级别越来越高的语言，而语言的设计者则必须理解并预测下一个抽象级别是什么样子的。&lt;/p&gt; &lt;a href="http://img.zhaojie.me/blog/prog-lang-trends-anders/8.png" target="_blank"&gt;&lt;img src="http://img.zhaojie.me/blog/prog-lang-trends-anders/8-thumbnail.png" /&gt;&lt;/a&gt;   &lt;p&gt;我认为，现在影响力较大的趋势主要有3种。首先，我们会越来越多地使用&lt;a href="http://en.wikipedia.org/wiki/Declarative_programming"&gt;声明式的编程风格&lt;/a&gt;。这里我主要会提到例如&lt;a href="http://en.wikipedia.org/wiki/Domain-specific_language"&gt;DSL&lt;/a&gt;（Domain Specific Language，领域特定语言）以及&lt;a href="http://en.wikipedia.org/wiki/Functional_programming"&gt;函数式编程&lt;/a&gt;。然后在过去的五年里，我发现对于动态语言的研究变得非常火热，其中对我们产生重大影响的无疑是动态语言所拥有的良好的元编程能力，还有一些非常有趣的东西，例如JavaScript引擎的发展。然后便是并发编程，无论我们愿不愿意，多核的产生都在迫使我们不得不重视并发编程。&lt;/p&gt;  &lt;p&gt;有一点值得一提，那便是随着语言的发展，原本的编程语言分类方式也要有所改变了。以前我们经常说面向对象语言，&lt;a href="http://en.wikipedia.org/wiki/Dynamic_programming_language"&gt;动态语言&lt;/a&gt;或是函数式语言。但是我们现在发现，这些边界变得越来越模糊，经常会互相学习各自的范式。静态语言中出现了动态类型，动态语言里也出现了静态能力，而如今所有主要的编程语言都受到函数式语言的影响。因此，一个越来越明显的趋势是“多范式程序设计语言”。&lt;/p&gt;  &lt;p&gt;在接下来的部分中，我将深入讨论以上提到的这些内容。&lt;/p&gt;

&lt;p&gt;（未完待续）&lt;/p&gt;

&lt;h1&gt;相关文章&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;编程语言的发展趋势及未来方向（1）：历史回顾及趋势概述&lt;/li&gt;

  &lt;li&gt;&lt;a href="http://blog.zhaojie.me/2010/04/trends-and-future-directions-in-programming-languages-by-anders-2-declarative-programming-and-dsl.html"&gt;编程语言的发展趋势及未来方向（2）：声明式编程与DSL&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://blog.zhaojie.me/2010/05/trends-and-future-directions-in-programming-languages-by-anders-3-functional-programming-and-fsharp.html"&gt;编程语言的发展趋势及未来方向（3）：函数式编程&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://blog.zhaojie.me/2010/05/trends-and-future-directions-in-programming-languages-by-anders-4-dynamic-languages.html"&gt;编程语言的发展趋势及未来方向（4）：动态语言&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://blog.zhaojie.me/2010/05/trends-and-future-directions-in-programming-languages-by-anders-5-meta-programming.html"&gt;编程语言的发展趋势及未来方向（5）：元编程&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://blog.zhaojie.me/2010/05/trends-and-future-directions-in-programming-languages-by-anders-6-concurrency.html"&gt;编程语言的发展趋势及未来方向（6）：并发&lt;/a&gt;&lt;/li&gt;

  &lt;li&gt;&lt;a href="http://blog.zhaojie.me/2010/06/trends-and-future-directions-in-programming-languages-by-anders-7-conclusion.html"&gt;编程语言的发展趋势及未来方向（7）：总结&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <comments>http://blog.zhaojie.me/2010/04/trends-and-future-directions-in-programming-languages-by-anders-1-history-and-trends.html#comments</comments>
      <pubDate>Mon, 12 Apr 2010 16:52:16 GMT</pubDate>
      <lastBuildDate>Mon, 12 Apr 2010 16:52:16 GMT</lastBuildDate>
    </item>
    <item>
      <author>jeffz@live.com (老赵)</author>
      <category domain="http://blog.zhaojie.me/news/">新闻信息</category>
      <category domain="http://blog.zhaojie.me/translation/">翻译引进</category>
      <category domain="http://blog.zhaojie.me/essential/">重中之重</category>
      <title>所有程序员都应该至少读上两遍的十篇论文</title>
      <link>http://blog.zhaojie.me/2009/03/1401259.html</link>
      <guid>http://blog.zhaojie.me/2009/03/1401259.html</guid>
      <description>&lt;p&gt;转载自刘江老师的博文《&lt;a href="http://blog.csdn.net/turingbook/archive/2009/03/01/3946421.aspx"&gt;所有程序员都应该至少读上两遍的十篇论文&lt;/a&gt;》。关于读论文的重要性我不多作解释，事实上我也解释不清，但是可以确定的是，论文让我感受到技术之美，是一件很惬意的事情。当然，我们不一定要读“前沿”的内容，但是一些经典的论文是不能错过的。&lt;/p&gt; &lt;hr&gt;  &lt;p&gt;今天（噢，应该是昨天了）图灵在北京搞了一次Ajax群英会，盛况空前。（会议实况下周整理一下，贴过来吧。）其间&lt;a href="http://www.turingbook.com/Books/ShowBook-332.aspx"&gt;《Erlang程序设计》&lt;/a&gt;的&lt;a href="http://erlang-china.org/"&gt;赵东炜&lt;/a&gt;说到读论文的重要性。我还附和说，其实许多名家在讲治学的时候都会讲到，要读自己领域里最经典的和最重要的论文。  &lt;p&gt;很巧，刚才从&lt;a href="http://www.reddit.com/r/programming/"&gt;Reddit&lt;/a&gt;上看到了题为“10 Papers Every Programmer Should Read (At Least Twice) ”的文章，打开&lt;a href="http://blog.objectmentor.com/articles/2009/02/26/10-papers-every-programmer-should-read-at-least-twice"&gt;链接&lt;/a&gt;一看，是我们&lt;a href="http://www.turingbook.com/Books/ShowBook-196.aspx"&gt;《修改代码的艺术》&lt;/a&gt;一书的作者Michael Feathers写的。他的那本书被称为&lt;a href="http://blog.csdn.net/turingbook/archive/2007/07/13/1688703.aspx"&gt;“近十年来最有影响的计算机图书”&lt;/a&gt;之一，可是在国内的关注并不太够，这是为什么呢？  &lt;p&gt;言归正传，看看是哪10篇论文入了Feathers大师的法眼吧：  &lt;ol&gt; &lt;li&gt;&lt;a href="http://sunnyday.mit.edu/16.355/parnas-criteria.html"&gt;On the criteria to be used in decomposing systems into modules&lt;/a&gt; – David Parnas  &lt;li&gt;&lt;a href="http://research.sun.com/techrep/1994/abstract-29.html"&gt;A Note On Distributed Computing&lt;/a&gt; – Jim Waldo, Geoff Wyant, Ann Wollrath, Sam Kendall  &lt;li&gt;&lt;a href="http://portal.acm.org/citation.cfm?id=365257"&gt;The Next 700 Programming Languages&lt;/a&gt; – P. J. Landin  &lt;li&gt;&lt;a href="http://portal.acm.org/citation.cfm?id=359579"&gt;Can Programming Be Liberated from the von Neumann Style?&lt;/a&gt; – John Backus  &lt;li&gt;&lt;a href="http://cm.bell-labs.com/who/ken/trust.html"&gt;Reflections on Trusting Trust&lt;/a&gt; – Ken Thompson  &lt;li&gt;&lt;a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.50.6083"&gt;Lisp: Good News, Bad News, How to Win Big&lt;/a&gt; – Richard Gabriel  &lt;li&gt;&lt;a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.29.363"&gt;An experimental evaluation of the assumption of independence in multiversion programming&lt;/a&gt; – John Knight and Nancy Leveson  &lt;li&gt;&lt;a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.50.7565"&gt;Arguments and Results&lt;/a&gt; – James Noble  &lt;li&gt;&lt;a href="http://c2.com/doc/oopsla89/paper.html"&gt;A Laboratory For Teaching Object-Oriented Thinking&lt;/a&gt; – Kent Beck, Ward Cunningham  &lt;li&gt;&lt;a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.31.562"&gt;Programming as an Experience: the inspiration for Self&lt;/a&gt; – David Ungar, Randall B. Smith &lt;/li&gt;&lt;/ol&gt; &lt;p&gt;这里面文章的作者大牛如云啊，图灵奖得主、IEEE和ACM的Fellow。当然，还有Beck和Cunningham这样的实干家（没有听说过？面壁十天。XP、设计模式、重构、JUnit甚至Wiki都是他们搞出来的啊。）  &lt;p&gt;Feathers的文章里还有这些论文的摘要，等有时间我把它们都翻译出来。  &lt;p&gt;这里链接有的不能直接访问，因为它们都是学术杂志文章，不开放的。是不是因为这个，Reddit上最热的文章变成了&lt;a href="http://www.reddit.com/r/programming/comments/80zae/httpportalacmorg_should_be_free/"&gt;http://portal.acm.org Should be free&lt;/a&gt;呢？  &lt;p&gt;Feathers的文章显然成了这几天网上的热门话题，我们另外一本已经获得版权的书《SOA Patterns》（Manning，2009）的作者Arnon Rotem-Gal-Oz受他启发，写了&lt;a href="http://www.rgoarchitects.com/nblog/2009/02/27/10PapersEverySoftwareArchitectShouldReadAtLeastTwice.aspx"&gt;“所有架构师都应该至少读上两遍的十篇论文”&lt;/a&gt;：  &lt;p&gt;1. &lt;a href="http://www.rgoarchitects.com/nblog/ct.ashx?id=ee9b28a4-7f61-4d7b-8796-b82420097c96&amp;amp;url=http%3a%2f%2fresearch.microsoft.com%2fen-us%2fum%2fpeople%2flamport%2fpubs%2fbyz.pdf"&gt;The Byzantine Generals Problem&lt;/a&gt; (1982) by Leslie Lamport, Robert Shostak and Marshall Pease&lt;br&gt;2. &lt;a href="http://www.rgoarchitects.com/nblog/ct.ashx?id=ee9b28a4-7f61-4d7b-8796-b82420097c96&amp;amp;url=http%3a%2f%2fwww.u.arizona.edu%2f%257Erubinson%2fcopyright_violations%2fGo_To_Considered_Harmful.html"&gt;Go To statements considered harmfull&lt;/a&gt; (1968) - by Edsger W. Dijkstra &lt;br&gt;3.&lt;a href="http://www.rgoarchitects.com/nblog/ct.ashx?id=ee9b28a4-7f61-4d7b-8796-b82420097c96&amp;amp;url=http%3a%2f%2fresearch.sun.com%2ftechrep%2f1994%2fabstract-29.html"&gt; A Note on Distributed Computing&lt;/a&gt; (1994) - by Samuel C. Kendall, Jim Waldo, Ann Wollrath and Geoff Wyant &lt;br&gt;4. &lt;a href="http://www.rgoarchitects.com/nblog/ct.ashx?id=ee9b28a4-7f61-4d7b-8796-b82420097c96&amp;amp;url=http%3a%2f%2fwww.laputan.org%2fmud%2f"&gt;Big Ball of Mud&lt;/a&gt; (1999) - Brian Foote and Joseph Yoder &lt;a href="http://www.rgoarchitects.com/nblog/2007/11/28/BigBallOfMudAndOtherArchitecturalDisastersNot.aspx"&gt;&lt;br&gt;&lt;/a&gt;5. &lt;a href="http://www.rgoarchitects.com/nblog/ct.ashx?id=ee9b28a4-7f61-4d7b-8796-b82420097c96&amp;amp;url=http%3a%2f%2fwww.lips.utexas.edu%2fee382c-15005%2fReadings%2fReadings1%2f05-Broo87.pdf"&gt;No Silver Bullet Essence and Accidents of Software Engineering&lt;/a&gt; (1987) - Frederick P. Brooks &lt;br&gt;6. &lt;a href="http://www.rgoarchitects.com/nblog/ct.ashx?id=ee9b28a4-7f61-4d7b-8796-b82420097c96&amp;amp;url=http%3a%2f%2fwww.objectmentor.com%2fresources%2farticles%2focp.pdf"&gt;The Open Closed Principle&lt;/a&gt; (1996) - Robert C. Martin (Uncle Bob) &lt;br&gt;7. &lt;a href="http://www.rgoarchitects.com/nblog/ct.ashx?id=ee9b28a4-7f61-4d7b-8796-b82420097c96&amp;amp;url=http%3a%2f%2fstandards.ieee.org%2freading%2fieee%2fstd_public%2fdescription%2fse%2f1471-2000_desc.html"&gt;IEEE1471-2000 A recommended practice for architectural description of software intensive systems&lt;/a&gt; (2000) &lt;br&gt;8. &lt;a href="http://www.rgoarchitects.com/nblog/ct.ashx?id=ee9b28a4-7f61-4d7b-8796-b82420097c96&amp;amp;url=http%3a%2f%2fciteseerx.ist.psu.edu%2fviewdoc%2fsummary%3fdoi%3d10.1.1.33.411"&gt;Harvest, Yield, and Scalable Tolerant Systems&lt;/a&gt; (1999) Armando Fox, Eric A. Brewer &lt;br&gt;9. &lt;a href="http://www.rgoarchitects.com/nblog/ct.ashx?id=ee9b28a4-7f61-4d7b-8796-b82420097c96&amp;amp;url=http%3a%2f%2fwww.cs.cmu.edu%2fafs%2fcs%2fproject%2fvit%2fftp%2fpdf%2fintro_softarch.pdf"&gt;An Introduction to Software Architecture&lt;/a&gt; (1993) - David Garlan and Mary Shaw &lt;br&gt;10. &lt;a href="http://www.rgoarchitects.com/nblog/ct.ashx?id=ee9b28a4-7f61-4d7b-8796-b82420097c96&amp;amp;url=http%3a%2f%2fmartinfowler.com%2fieeeSoftware%2fwhoNeedsArchitect.pdf"&gt;Who Needs an Architect?&lt;/a&gt; (2003) Martin Fowler  &lt;p&gt;注意到了吗，其中的第3篇是Feathers也推荐的。  &lt;p&gt;更有意思的是，我们大家熟悉的Robert Martin大叔 [也是我们图灵的作者呵呵，&lt;a href="http://www.turingbook.com/Books/ShowBook-220.aspx"&gt;《敏捷软件开发》（C#版）&lt;/a&gt;，什么，你搞.NET的居然没有读过？面壁十天。] 也因此写了&lt;a href="http://blog.objectmentor.com/articles/category/uncle-bobs-blatherings"&gt;blog&lt;/a&gt;。原来有位叫David的同学在Feathers的blog下说了几句不靠谱的话，把一向脾气很好的Bob大叔也激怒了。David小子说：“你咋不直接给出PDF呢？要是这些文章真的重要，应该免费读到不是？瞧你那口气，牛X得不行，真让人不爽。得了您吧。” 说实话，这口气咋让我觉得像是咱同胞呢……瀑布汗啊。  &lt;p&gt;Bob大叔的回复发人深省。他说，你们知道这篇文章以及其中提到的论文有多重要吗？Feathers同学读了成百上千篇论文，然后向你介绍其中最好的10篇！&lt;strong&gt;人家把金砖放在你眼前，你却说太重了，我拿不动。&lt;/strong&gt;笨蛋啊，蠢材啊！  &lt;p&gt;他接着说：“我们是自食其力而且为自己的职业负责的技术人员呢，还是指望爹妈来擦屁股的小屁孩？是你，而不是别人，要为你自己的职业负责。你的老板可没有责任管这些。提升自己的职业水平不应该指望老板。你不能指望老板给你买书（如果他们真能这样当然好，但是这不是他们的义务）。老板不买，你自己买啊！老板没有责任教你学习新语言。如果他们能送你去培训当然好，但是如果他们不送，你要自己学啊！  &lt;p&gt;“我非常忧虑，我们的福利文化已经制造出一大批喜欢哭兮兮娘娘腔的程序员，他们居然认为必须为有版权的文章花钱是不公平的。（什么？还要我出钱？那是老板的事儿！那是我老师的事儿！那是Michael Feathers的事儿！他们要想我成为好的程序员，可别指望我出钱去读那些文章，也别指望我在Google里搜索文章，他们最好到我的办公室格子里来，哦，上午9点到10点吧，一边轻捋我的头发，一边把文章读给我听！）  &lt;p&gt;“请记住，这世界可不欠你的。老板也不欠你。Michael Feathers更不欠你。”  &lt;p&gt;（沉思十分钟……）&lt;/p&gt;</description>
      <comments>http://blog.zhaojie.me/2009/03/1401259.html#comments</comments>
      <pubDate>Mon, 02 Mar 2009 02:29:00 GMT</pubDate>
      <lastBuildDate>Mon, 02 Mar 2009 02:29:00 GMT</lastBuildDate>
    </item>
    <item>
      <author>jeffz@live.com (老赵)</author>
      <category domain="http://blog.zhaojie.me/architecture/">架构设计</category>
      <category domain="http://blog.zhaojie.me/translation/">翻译引进</category>
      <category domain="http://blog.zhaojie.me/practice/">实践优化</category>
      <title>Scaling a Rails Application from the Bottom Up</title>
      <link>http://blog.zhaojie.me/2007/06/793756.html</link>
      <guid>http://blog.zhaojie.me/2007/06/793756.html</guid>
      <description>&lt;p&gt;&lt;a title="http://media.joyent.com/JHoffmanRailsConf-May2007.pdf" href="http://media.joyent.com/JHoffmanRailsConf-May2007.pdf"&gt;http://media.joyent.com/JHoffmanRailsConf-May2007.pdf&lt;/a&gt;&lt;/p&gt; &lt;p&gt;这是今年Rails大会上的一个报告。虽然讲的是RoR应用程序，但实际该报告里包括了许多其他方面要素的阐述，例如操作系统，硬件配置等等。对于要构造大型网络应用的人来说是一个不可不读的文档。&lt;/p&gt;</description>
      <comments>http://blog.zhaojie.me/2007/06/793756.html#comments</comments>
      <pubDate>Fri, 22 Jun 2007 22:31:00 GMT</pubDate>
      <lastBuildDate>Fri, 22 Jun 2007 22:31:00 GMT</lastBuildDate>
    </item>
    <item>
      <author>jeffz@live.com (老赵)</author>
      <category domain="http://blog.zhaojie.me/translation/">翻译引进</category>
      <category domain="http://blog.zhaojie.me/news/">新闻信息</category>
      <title>第17届Jolt Award终于出炉了</title>
      <link>http://blog.zhaojie.me/2007/03/jolt-2007.html</link>
      <guid>http://blog.zhaojie.me/2007/03/jolt-2007.html</guid>
      <description>&lt;p style="font-size: 10pt; font-family: verdana"&gt;第17届Jolt Award终于&lt;a href="http://www.joltawards.com/2007"&gt;出炉&lt;/a&gt;了，再这之前，我们再来回顾一下&lt;a href="http://blog.zhaojie.me/2007/01/627575.html"&gt;候选选手们&lt;/a&gt;。&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;每一届Jolt Award都是重要的参考，其中的每个奖项都可以是过去一年中的顶级作品，而对于我这种嗜书如命的“书痴”自然不会放过Jolt大奖中评选出来的好书，每年的Jolt Winner和部分Productivity Winner的书我都会从国外购买原版，手不释卷，心情也会相当愉快。不过我在想，放眼望去Jolt Award中尽是美国货，不论书籍或是别的产品。什么时候能够出现中国人的身影呢？&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;与去年相比，微软公司推出的产品收获少了很多——不过，其实应该这么说，Jolt 2006中微软实在太过风光了。&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="font-size: 15pt; font-family: verdana; text-align: center"&gt;&lt;u&gt;&lt;strong&gt;BOOKS GENERAL&lt;/strong&gt;&lt;/u&gt;&lt;/p&gt; &lt;p style="font-size: 11pt; font-family: verdana; text-align: center"&gt;&lt;font color="#ff0000"&gt;&lt;strong&gt;Jolt Winner&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana; text-align: center"&gt;&lt;font color="#ff0000"&gt;&lt;strong&gt;Agile Software Development: The Cooperative Game&lt;/strong&gt;&amp;nbsp;by Alistair Cockburn (Addison-Wesley Professional)&lt;/font&gt;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana; text-align: center"&gt;&lt;img alt="1" src="http://img.zhaojie.me/blog/Jolt2007/1.jpg"&gt;&lt;br&gt;&lt;b&gt;Agile Software Development&lt;/b&gt;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="font-size: 11pt; font-family: verdana; text-align: center"&gt;&lt;strong&gt;Productivity Winners&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt; &lt;div style="font-size: 10pt; font-family: verdana"&gt;&lt;strong&gt;Catastrophe Disentanglement&lt;/strong&gt; by E. M. Bennatan (Addison-Wesley Professional) &lt;/div&gt; &lt;li&gt; &lt;div style="font-size: 10pt; font-family: verdana"&gt;&lt;strong&gt;Practices of an Agile Developer&lt;/strong&gt; by V. Subramaniam and A. Hunt (Pragmatic Bookshelf) &lt;/div&gt; &lt;li&gt; &lt;div style="font-size: 10pt; font-family: verdana"&gt;&lt;strong&gt;Software Estimation Demystifying&lt;/strong&gt; the Black Art by Steve McConnell (Microsoft Press)&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt; &lt;table cellspacing="5" width="95%"&gt; &lt;tbody align="middle"&gt; &lt;tr&gt; &lt;td align="middle" width="30%"&gt;&lt;img src="http://img.zhaojie.me/blog/Jolt2007/2.jpg"&gt; &lt;/td&gt; &lt;td align="middle" width="30%"&gt;&lt;img src="http://img.zhaojie.me/blog/Jolt2007/3.jpg"&gt; &lt;/td&gt; &lt;td align="middle" width="30%"&gt;&lt;img src="http://img.zhaojie.me/blog/Jolt2007/4.jpg"&gt; &lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td style="font-size: 10pt; font-family: verdana"&gt;&lt;strong&gt;Catastrophe Disentanglement&lt;/strong&gt; &lt;/td&gt; &lt;td style="font-size: 10pt; font-family: verdana"&gt;&lt;strong&gt;Practices of an Agile Developer&lt;/strong&gt; &lt;/td&gt; &lt;td style="font-size: 10pt; font-family: verdana"&gt;&lt;strong&gt;Software Estimation Demystifying&lt;/strong&gt; &lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="font-size: 15pt; font-family: verdana; text-align: center"&gt;&lt;u&gt;&lt;strong&gt;BOOKS TECHNICAL&lt;/strong&gt;&lt;/u&gt;&lt;/p&gt; &lt;p style="font-size: 11pt; font-family: verdana; text-align: center"&gt;&lt;font color="#ff0000"&gt;&lt;strong&gt;Jolt Winner&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana; text-align: center"&gt;&lt;font color="#ff0000"&gt;&lt;strong&gt;Head First Object-Oriented Analysis &amp;amp; Design&lt;/strong&gt; by B. McLaughlin, G. Pollice, and D. West (O'Reilly Media)&lt;/font&gt;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana; text-align: center"&gt;&lt;img alt="5" src="http://img.zhaojie.me/blog/Jolt2007/5.jpg"&gt;&lt;br&gt;&lt;b&gt;Head First Object-Oriented Analysis &amp;amp; Design&lt;/b&gt;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="font-size: 11pt; font-family: verdana; text-align: center"&gt;&lt;strong&gt;Productivity Winners&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt; &lt;div style="font-size: 10pt; font-family: verdana"&gt;&lt;strong&gt;Code Quality: The Open Source Perspective&lt;/strong&gt;&amp;nbsp;by Diomidis Spinellis (Addison-Wesley Professional) &lt;/div&gt; &lt;li&gt; &lt;div style="font-size: 10pt; font-family: verdana"&gt;&lt;strong&gt;Refactoring Databases: Evolutionary Database Design&lt;/strong&gt;&amp;nbsp;by Scott W. Ambler and P. J. Sadalage (Addison-Wesley Professional) &lt;/div&gt; &lt;li&gt; &lt;div style="font-size: 10pt; font-family: verdana"&gt;&lt;strong&gt;CSS: The Missing Manual&lt;/strong&gt; by David Sawyer McFarland (O'Reilly Media)&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt; &lt;table cellspacing="5" width="95%"&gt; &lt;tbody align="middle"&gt; &lt;tr&gt; &lt;td align="middle" width="30%"&gt;&lt;img src="http://img.zhaojie.me/blog/Jolt2007/6.jpg"&gt; &lt;/td&gt; &lt;td align="middle" width="30%"&gt;&lt;img src="http://img.zhaojie.me/blog/Jolt2007/7.jpg"&gt; &lt;/td&gt; &lt;td align="middle" width="30%"&gt;&lt;img src="http://img.zhaojie.me/blog/Jolt2007/8.jpg"&gt; &lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td style="font-size: 10pt; font-family: verdana"&gt;&lt;strong&gt;Code Quality: The Open Source Perspective&lt;/strong&gt; &lt;/td&gt; &lt;td style="font-size: 10pt; font-family: verdana"&gt;&lt;strong&gt;Refactoring Databases: Evolutionary Database Design&lt;/strong&gt; &lt;/td&gt; &lt;td style="font-size: 10pt; font-family: verdana"&gt;&lt;strong&gt;CSS: The Missing Manual&lt;/strong&gt; &lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="font-size: 15pt; font-family: verdana; text-align: center"&gt;&lt;u&gt;&lt;strong&gt;HALL OF FAME&lt;/strong&gt;&lt;/u&gt;&lt;/p&gt; &lt;p style="font-size: 12pt; font-family: verdana; text-align: center"&gt;&lt;strong&gt;&lt;font color="#ff0000"&gt;IBM DeveloperWorks (IBM)&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;strong&gt;&lt;u&gt;Change and Configuration Management&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;font color="#ff0000"&gt;Jolt Winner:&lt;/font&gt;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;AccuRev 4.5 with AccuWorkflow (AccuRev)&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;font color="#ff0000"&gt;Productivity Winners:&lt;/font&gt; &lt;/p&gt; &lt;ul&gt; &lt;li&gt; &lt;div style="font-size: 10pt; font-family: verdana"&gt;AnthillPro3 (Urbancode)&lt;/div&gt; &lt;li&gt; &lt;div style="font-size: 10pt; font-family: verdana"&gt;Perforce SCM (Perforce) &lt;/div&gt; &lt;li&gt; &lt;div style="font-size: 10pt; font-family: verdana"&gt;Team Foundation Server (Microsoft)&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;strong&gt;&lt;u&gt;Collaboration Tools&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;font color="#ff0000"&gt;Jolt Winner:&lt;/font&gt;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;Confluence (Atlassian Software Systems) &lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;font color="#ff0000"&gt;Productivity Winners:&lt;/font&gt; &lt;/p&gt; &lt;ul&gt; &lt;li&gt; &lt;div style="font-size: 10pt; font-family: verdana"&gt;Adobe Acrobat Connect Professional (Adobe Systems) &lt;/div&gt; &lt;li&gt; &lt;div style="font-size: 10pt; font-family: verdana"&gt;NetBeans IDE (Sun Microsystems) &lt;/div&gt; &lt;li&gt; &lt;div style="font-size: 10pt; font-family: verdana"&gt;TeamCity (JetBrains)&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;strong&gt;&lt;u&gt;Database Engines and Data Tools&lt;/u&gt;&lt;/strong&gt; &lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;font color="#ff0000"&gt;Jolt Winner:&lt;/font&gt;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;Visual Studio 2005 Team Edition for Database Professionals (Microsoft) &lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;font color="#ff0000"&gt;Productivity Winners:&lt;/font&gt; &lt;/p&gt; &lt;ul&gt; &lt;li&gt; &lt;div style="font-size: 10pt; font-family: verdana"&gt;Coral8 Engine (Coral8) &lt;/div&gt; &lt;li&gt; &lt;div style="font-size: 10pt; font-family: verdana"&gt;Dbdeploy (ThoughtWorks) &lt;/div&gt; &lt;li&gt; &lt;div style="font-size: 10pt; font-family: verdana"&gt;SQL Refactor (Red Gate Software)&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;strong&gt;&lt;u&gt;Design and Modeling Tools&lt;/u&gt;&lt;/strong&gt; &lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;font color="#ff0000"&gt;Jolt Winner:&lt;/font&gt;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;stpBA Storyboarding (stpsoft) &lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;font color="#ff0000"&gt;Productivity Winners:&lt;/font&gt; &lt;/p&gt; &lt;ul&gt; &lt;li&gt; &lt;div style="font-size: 10pt; font-family: verdana"&gt;Corticon Business Rules Modeling Studio (Corticon) &lt;/div&gt; &lt;li&gt; &lt;div style="font-size: 10pt; font-family: verdana"&gt;MagicDraw UML (No Magic) &lt;/div&gt; &lt;li&gt; &lt;div style="font-size: 10pt; font-family: verdana"&gt;Stylus Studio 2007 XML Enterprise Suite (DataDirect Technologies)&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;strong&gt;&lt;u&gt;Development Environments&lt;/u&gt;&lt;/strong&gt; &lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;font color="#ff0000"&gt;Jolt Winner:&lt;/font&gt; &lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;NetBeans IDE (Sun Microsystems) &lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;font color="#ff0000"&gt;Productivity Winners:&lt;/font&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt; &lt;div style="font-size: 10pt; font-family: verdana"&gt;IntelliJ IDEA (JetBrains)&lt;/div&gt;&lt;/li&gt; &lt;li&gt; &lt;div style="font-size: 10pt; font-family: verdana"&gt;IronPython (Microsoft)&lt;/div&gt;&lt;/li&gt; &lt;li&gt; &lt;div style="font-size: 10pt; font-family: verdana"&gt;Wolfram Workbench (Wolfram Research)&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;strong&gt;&lt;u&gt;Enterprise Tools&lt;/u&gt;&lt;/strong&gt; &lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;font color="#ff0000"&gt;Jolt Winner:&lt;/font&gt; &lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;Cape Clear ESB Platform (Cape Clear Software) &lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;font color="#ff0000"&gt;Productivity Winners:&lt;/font&gt; &lt;/p&gt; &lt;ul&gt; &lt;li&gt; &lt;div style="font-size: 10pt; font-family: verdana"&gt;Liferay Portal (Liferay) &lt;/div&gt;&lt;/li&gt; &lt;li&gt; &lt;div style="font-size: 10pt; font-family: verdana"&gt;Appistry EAF (Appistry) &lt;/div&gt;&lt;/li&gt; &lt;li&gt; &lt;div style="font-size: 10pt; font-family: verdana"&gt;Pentaho Open BI Suite (Pentaho)&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;strong&gt;&lt;u&gt;Libraries, Frameworks and Components&lt;/u&gt;&lt;/strong&gt; &lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;font color="#ff0000"&gt;Jolt Winner:&lt;/font&gt; &lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;NetAdvantage for .NET (Infragistics) &lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;font color="#ff0000"&gt;Productivity Winners:&lt;/font&gt; &lt;/p&gt; &lt;ul&gt; &lt;li&gt; &lt;div style="font-size: 10pt; font-family: verdana"&gt;JViews (ILOG) &lt;/div&gt;&lt;/li&gt; &lt;li&gt; &lt;div style="font-size: 10pt; font-family: verdana"&gt;.NET Framework 3.0 (Microsoft) &lt;/div&gt;&lt;/li&gt; &lt;li&gt; &lt;div style="font-size: 10pt; font-family: verdana"&gt;Intel Threading Building Blocks (Intel)&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;strong&gt;&lt;u&gt;Mobile Development Tools&lt;/u&gt;&lt;/strong&gt; &lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;font color="#ff0000"&gt;Jolt Winner:&lt;/font&gt; &lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;Carbide .c++ Professional Edition (Nokia) &lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;font color="#ff0000"&gt;Productivity Winners:&lt;/font&gt; &lt;/p&gt; &lt;ul&gt; &lt;li&gt; &lt;div style="font-size: 10pt; font-family: verdana"&gt;Crossfire (AppForge) &lt;/div&gt;&lt;/li&gt; &lt;li&gt; &lt;div style="font-size: 10pt; font-family: verdana"&gt;NetBeans Mobility Pack and Sun Java Wireless Tookit (Sun Microsystems) &lt;/div&gt;&lt;/li&gt; &lt;li&gt; &lt;div style="font-size: 10pt; font-family: verdana"&gt;Qtopia (Trolltech)&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;strong&gt;&lt;u&gt;Project Management&lt;/u&gt;&lt;/strong&gt; &lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;font color="#ff0000"&gt;Jolt Winner:&lt;/font&gt;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;Rally Enterprise (Rally Software) &lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;font color="#ff0000"&gt;Productivity Winners:&lt;/font&gt; &lt;/p&gt; &lt;ul&gt; &lt;li&gt; &lt;div style="font-size: 10pt; font-family: verdana"&gt;6th Sense Analytics (6th Sense Analytics) &lt;/div&gt;&lt;/li&gt; &lt;li&gt; &lt;div style="font-size: 10pt; font-family: verdana"&gt;Teamwork (Open Lab) &lt;/div&gt;&lt;/li&gt; &lt;li&gt; &lt;div style="font-size: 10pt; font-family: verdana"&gt;V1: Agile Enterprise (VersionOne) &lt;/div&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;strong&gt;&lt;u&gt;Security&lt;/u&gt;&lt;/strong&gt; &lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;font color="#ff0000"&gt;Jolt Winner:&lt;/font&gt; &lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;AppScan (Watchfire) &lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;font color="#ff0000"&gt;Productivity Winners:&lt;/font&gt; &lt;/p&gt; &lt;ul&gt; &lt;li&gt; &lt;div style="font-size: 10pt; font-family: verdana"&gt;DevInspect (SPI Dynamics) &lt;/div&gt;&lt;/li&gt; &lt;li&gt; &lt;div style="font-size: 10pt; font-family: verdana"&gt;Fortify Source Code Analysis (Fortify) &lt;/div&gt;&lt;/li&gt; &lt;li&gt; &lt;div style="font-size: 10pt; font-family: verdana"&gt;Metasploit Framework (Metasploit) &lt;/div&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;strong&gt;&lt;u&gt;Testing&lt;/u&gt;&lt;/strong&gt; &lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;font color="#ff0000"&gt;Jolt Winner:&lt;/font&gt;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;AgitarOne (Agitar Software) &lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;font color="#ff0000"&gt;Productivity Winners:&lt;/font&gt; &lt;/p&gt; &lt;ul&gt; &lt;li&gt; &lt;div style="font-size: 10pt; font-family: verdana"&gt;Mindreef SOAPscope (Mindreef) &lt;/div&gt;&lt;/li&gt; &lt;li&gt; &lt;div style="font-size: 10pt; font-family: verdana"&gt;Parasoft SOAtest (Parasoft) &lt;/div&gt;&lt;/li&gt; &lt;li&gt; &lt;div style="font-size: 10pt; font-family: verdana"&gt;TestComplete (AutomatedQA)&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;strong&gt;&lt;u&gt;Bug and Defect Tracking&lt;/u&gt;&lt;/strong&gt; &lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;font color="#ff0000"&gt;Jolt Winner:&lt;/font&gt;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;TestTrack Studio (Seapine Software) &lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;font color="#ff0000"&gt;Productivity Winners:&lt;/font&gt; &lt;/p&gt; &lt;ul&gt; &lt;li&gt; &lt;div style="font-size: 10pt; font-family: verdana"&gt;JIRA (Atlassian Software Systems) &lt;/div&gt;&lt;/li&gt; &lt;li&gt; &lt;div style="font-size: 10pt; font-family: verdana"&gt;OnTime 2007 (Axosoft) &lt;/div&gt;&lt;/li&gt; &lt;li&gt; &lt;div style="font-size: 10pt; font-family: verdana"&gt;Software Planner Professional (Pragmatic Software)&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;strong&gt;&lt;u&gt;Utilities&lt;/u&gt;&lt;/strong&gt; &lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;font color="#ff0000"&gt;Jolt Winner:&lt;/font&gt;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;VMware Lab Manager (VMware) &lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;font color="#ff0000"&gt;Productivity Winners:&lt;/font&gt; &lt;/p&gt; &lt;ul&gt; &lt;li&gt; &lt;div style="font-size: 10pt; font-family: verdana"&gt;Adobe Captivate 2 (Adobe) &lt;/div&gt;&lt;/li&gt; &lt;li&gt; &lt;div style="font-size: 10pt; font-family: verdana"&gt;ElectricCommander (Electric Cloud) &lt;/div&gt;&lt;/li&gt; &lt;li&gt; &lt;div style="font-size: 10pt; font-family: verdana"&gt;Textmate (MacroMates)&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;strong&gt;&lt;u&gt;Web Development&lt;/u&gt;&lt;/strong&gt; &lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;font color="#ff0000"&gt;Jolt Winner:&lt;/font&gt; &lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;Adobe Flex 2 (Adobe Systems) &lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;font color="#ff0000"&gt;Productivity Winners:&lt;/font&gt; &lt;/p&gt; &lt;ul&gt; &lt;li&gt; &lt;div style="font-size: 10pt; font-family: verdana"&gt;IntelliJ IDEA (JetBrains) &lt;/div&gt;&lt;/li&gt; &lt;li&gt; &lt;div style="font-size: 10pt; font-family: verdana"&gt;Mindreef SOAPscope Server (Mindreef) &lt;/div&gt;&lt;/li&gt; &lt;li&gt; &lt;div style="font-size: 10pt; font-family: verdana"&gt;NetBeans Visual Web Pack 5.5 (Sun Microsystems) &lt;/div&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;strong&gt;&lt;u&gt;Websites and Developer Networks &lt;/u&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;font color="#ff0000"&gt;Jolt Winner:&lt;/font&gt;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;Sun Developer Network (Sun Microsystems) &lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;font color="#ff0000"&gt;Productivity Winners:&lt;/font&gt; &lt;/p&gt; &lt;ul&gt; &lt;li&gt; &lt;div style="font-size: 10pt; font-family: verdana"&gt;CM Crossroads (CMC Media) &lt;/div&gt;&lt;/li&gt; &lt;li&gt; &lt;div style="font-size: 10pt; font-family: verdana"&gt;Koders.com (Koders) &lt;/div&gt;&lt;/li&gt; &lt;li&gt; &lt;div style="font-size: 10pt; font-family: verdana"&gt;Krugle (Krugle)&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;/p&gt;</description>
      <comments>http://blog.zhaojie.me/2007/03/jolt-2007.html#comments</comments>
      <pubDate>Thu, 22 Mar 2007 20:13:00 GMT</pubDate>
      <lastBuildDate>Thu, 22 Mar 2007 20:13:00 GMT</lastBuildDate>
    </item>
    <item>
      <author>jeffz@live.com (老赵)</author>
      <category domain="http://blog.zhaojie.me/front-end/">前端表现</category>
      <category domain="http://blog.zhaojie.me/translation/">翻译引进</category>
      <title>WPF/E CTP Quick Start - 第十一部分：示例控件（翻译）</title>
      <link>http://blog.zhaojie.me/2006/12/wpfe-ctp-quick-start-part-11.html</link>
      <guid>http://blog.zhaojie.me/2006/12/wpfe-ctp-quick-start-part-11.html</guid>
      <description>&lt;link href="http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/cnblogs/QuickStart.css" type="text/css" rel="stylesheet"&gt; &lt;script src="http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/cnblogs/QuickStart.js" type="text/javascript"&gt;&lt;/script&gt;  &lt;div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 5px; font-size: 10pt; padding-bottom: 5px; border-left: #cccccc 1px solid; padding-top: 5px; border-bottom: #cccccc 1px solid; font-family: verdana"&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;这片文档包含了几个例子，演示了如何使用WPF/E来创建交互式的控件。&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;这篇文档包含了如下部分：&lt;/p&gt; &lt;ul&gt; &lt;li class="WpfeQS"&gt;&lt;a href="#hyperlinkexample"&gt;&amp;#8220;超级链接&amp;#8221;示例&lt;/a&gt;  &lt;li class="WpfeQS"&gt;&lt;a href="#buttonexample"&gt;&amp;#8220;按钮&amp;#8221;示例&lt;/a&gt;  &lt;li class="WpfeQS"&gt;&lt;a href="#sliderexample"&gt;&amp;#8220;滚动条&amp;#8221;示例&lt;/a&gt;&amp;nbsp;  &lt;li class="WpfeQS"&gt;&lt;a href="#whatsnext"&gt;下面该做什么呢？&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;&lt;a name="hyperlinkexample"&gt;&lt;/a&gt; &lt;p style="font-size: 14pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;&amp;#8220;超级链接&amp;#8221;示例&lt;/strong&gt;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;下面的示例使用一个&lt;strong&gt;TextBlock&lt;/strong&gt;和一个&lt;strong&gt;Line&lt;/strong&gt;创建了一个超级链接。&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Canvas&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"300"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"300"&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"http://schemas.microsoft.com/client/2007"&lt;/span&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;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
  
    &lt;span style="color: #008000"&gt;&amp;lt;!-- Hyperlink --&amp;gt;&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Canvas&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"90"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"30"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Left&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"20"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"20"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;Background&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"transparent"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;MouseEnter&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"javascript:hyperlink_MouseEnter"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;MouseLeave&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"javascript:hyperlink_MouseLeave"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;MouseLeftButtonDown&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"javascript:hyperlink_MouseLeftButtonDown"&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: #ff0000"&gt;Text&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"hyperlink"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Foreground&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Blue"&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;Line&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Stroke&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"blue"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;StrokeThickness&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"1"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;X1&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"0"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Y1&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"20"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;X2&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"65"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Y2&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"20"&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;"hyperlink_line"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Opacity&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"0"&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;Canvas&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;Canvas&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;function&lt;/span&gt; hyperlink_MouseLeftButtonDown(sender, args) {
    &lt;span style="color: #0000ff"&gt;window&lt;/span&gt;.&lt;span style="color: #0000ff"&gt;location&lt;/span&gt; = "&lt;span style="color: #8b0000"&gt;about-frames.html&lt;/span&gt;";
}

&lt;span style="color: #0000ff"&gt;function&lt;/span&gt; hyperlink_MouseEnter(sender,args)
{
    sender.findName("&lt;span style="color: #8b0000"&gt;hyperlink_line&lt;/span&gt;").opacity = 1;
}

&lt;span style="color: #0000ff"&gt;function&lt;/span&gt; hyperlink_MouseLeave(sender,args)
{
    sender.findName("&lt;span style="color: #8b0000"&gt;hyperlink_line&lt;/span&gt;").opacity = 0;
}&lt;/pre&gt;
&lt;div class="agHost" id="agHost0"&gt;&lt;/div&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;a class="agButton" href="javascript:start('agHost0', 'agButton0', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/controls-hyperlink.html');"&gt;重新开始&lt;/a&gt;&lt;a class="agButton" id="agButton0" href="javascript:turn('agHost0', 'agButton0', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/controls-hyperlink.html');"&gt;查看内容&lt;/a&gt;&lt;/p&gt;
&lt;script language="javascript"&gt;
start('agHost0', 'agButton0', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/controls-hyperlink.html');
&lt;/script&gt;

&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;&lt;a name="buttonexample"&gt;&lt;/a&gt;
&lt;p style="font-size: 14pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;&amp;#8220;按钮&amp;#8221;示例&lt;/strong&gt;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;下面的示例使用两个&lt;strong&gt;Rectangle&lt;/strong&gt;元素和一个&lt;strong&gt;TextBlock&lt;/strong&gt;创建了一个按钮。&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Canvas&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"300"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"300"&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"http://schemas.microsoft.com/client/2007"&lt;/span&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;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
    &lt;span style="color: #008000"&gt;&amp;lt;!-- Button --&amp;gt;&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Canvas&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;"button"&lt;/span&gt;
            &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"10"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Left&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"20"&lt;/span&gt;
            &lt;span style="color: #ff0000"&gt;MouseLeftButtonDown&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"javascript:button_MouseLeftButtonDown"&lt;/span&gt;
            &lt;span style="color: #ff0000"&gt;MouseLeftButtonUp&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"javascript:button_MouseLeftButtonUp"&lt;/span&gt;
            &lt;span style="color: #ff0000"&gt;MouseEnter&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"javascript:button_MouseEnter"&lt;/span&gt;
            &lt;span style="color: #ff0000"&gt;MouseLeave&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"javascript:button_MouseLeave"&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;Canvas.RenderTransform&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;TransformGroup&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;TranslateTransform&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;"button_transform"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;X&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"0"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Y&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"0"&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;TransformGroup&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;Canvas.RenderTransform&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;Rectangle&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"128.8"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"56"&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;"button_rectangle"&lt;/span&gt;
            &lt;span style="color: #ff0000"&gt;Stroke&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"#FF000000"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Fill&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"sc#1, 0.8123474, 0.8123474, 0.8123474"&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;Rectangle&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Stroke&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"sc#1, 0.912730157, 0.37122494, 0.17111966"&lt;/span&gt;
            &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"126.8"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"54"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Left&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"1"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"1"&lt;/span&gt;
            &lt;span style="color: #ff0000"&gt;Opacity&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"0"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;StrokeThickness&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"5"&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;"button_highlight"&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: #ff0000"&gt;Text&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Press me!"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;FontSize&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"20"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Left&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"22"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"12"&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;Canvas&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;Canvas&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;var&lt;/span&gt; mouseOver = &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;;
&lt;span style="color: #0000ff"&gt;var&lt;/span&gt; pressed = &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;;

&lt;span style="color: #0000ff"&gt;function&lt;/span&gt; button_MouseLeftButtonDown(sender,args) {
    sender.captureMouse();
    mouseOver = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;;
    pressed = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;;
    updateVisuals(sender);
}

&lt;span style="color: #0000ff"&gt;function&lt;/span&gt; button_MouseLeftButtonUp(sender,args) {
    sender.releaseMouseCapture();
    pressed = &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;;
    
    updateVisuals(sender);
    
    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (mouseOver) {
        &lt;span style="color: #0000ff"&gt;alert&lt;/span&gt;("&lt;span style="color: #8b0000"&gt;you pressed the button!&lt;/span&gt;");
    }
}

&lt;span style="color: #0000ff"&gt;function&lt;/span&gt; button_MouseEnter(sender,args) {
    mouseOver = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;;
    updateVisuals(sender);
}

&lt;span style="color: #0000ff"&gt;function&lt;/span&gt; button_MouseLeave(sender,args) {
    mouseOver = &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;;
    updateVisuals(sender);
}

&lt;span style="color: #0000ff"&gt;function&lt;/span&gt; updateVisuals(sender) {
    &lt;span style="color: #008000"&gt;//background&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (pressed &amp;amp;&amp;amp; mouseOver) {
        sender.findName("&lt;span style="color: #8b0000"&gt;button_rectangle&lt;/span&gt;").fill = "&lt;span style="color: #8b0000"&gt;sc#1, 0.548430264, 0.5354195, 0.5354195&lt;/span&gt;";
        &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; transform = sender.findName("&lt;span style="color: #8b0000"&gt;button_transform&lt;/span&gt;");
        transform.x = 2;
        transform.y = 2;
    } &lt;span style="color: #0000ff"&gt;else&lt;/span&gt; {
        sender.findName("&lt;span style="color: #8b0000"&gt;button_rectangle&lt;/span&gt;").fill = "&lt;span style="color: #8b0000"&gt;sc#1, 0.8123474, 0.8123474, 0.8123474&lt;/span&gt;";
        &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; transform = sender.findName("&lt;span style="color: #8b0000"&gt;button_transform&lt;/span&gt;");
        transform.x = 0;
        transform.y = 0;
    }
    
    &lt;span style="color: #008000"&gt;// highlight&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (mouseOver || pressed) {
        sender.findName("&lt;span style="color: #8b0000"&gt;button_highlight&lt;/span&gt;").opacity = 1;
    } &lt;span style="color: #0000ff"&gt;else&lt;/span&gt; {
        sender.findName("&lt;span style="color: #8b0000"&gt;button_highlight&lt;/span&gt;").opacity = 0;
    }
}&lt;/pre&gt;
&lt;div class="agHost" id="agHost1"&gt;&lt;/div&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;a class="agButton" href="javascript:start('agHost1', 'agButton1', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/controls-button.html');"&gt;重新开始&lt;/a&gt;&lt;a class="agButton" id="agButton1" href="javascript:turn('agHost1', 'agButton1', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/controls-button.html');"&gt;查看内容&lt;/a&gt;&lt;/p&gt;
&lt;script language="javascript"&gt;
start('agHost1', 'agButton1', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/controls-button.html');
&lt;/script&gt;

&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;&lt;a name="sliderexample"&gt;&lt;/a&gt;
&lt;p style="font-size: 14pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;&amp;#8220;滚动条&amp;#8221;示例&lt;/strong&gt;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;下面的示例使用了一个&lt;strong&gt;Line&lt;/strong&gt;和&lt;strong&gt;Path&lt;/strong&gt;创建了一个滚动条。&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Canvas&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"300"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"300"&lt;/span&gt;
  &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"http://schemas.microsoft.com/client/2007"&lt;/span&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;span style="color: #ff0000"&gt;Loaded&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"javascript:slider_loaded"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
  &lt;span style="color: #008000"&gt;&amp;lt;!-- Slider --&amp;gt;&lt;/span&gt;
  &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Canvas&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"50"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Left&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"20"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"200"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"45"&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;Background&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"transparent"&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;"slider"&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;MouseLeftButtonDown&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"javascript:slider_MouseLeftButtonDown"&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;Line&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;"slider_line"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Stroke&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"black"&lt;/span&gt; 
      &lt;span style="color: #ff0000"&gt;StrokeThickness&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"1"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;X1&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"0"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Y1&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"25"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;X2&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"200"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Y2&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"25"&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;Path&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;"slider_thumb"&lt;/span&gt;  &lt;span style="color: #ff0000"&gt;Stroke&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"#FF000000"&lt;/span&gt; 
      &lt;span style="color: #ff0000"&gt;Fill&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"sc#1, 0.548430264, 0.5354195, 0.5354195"&lt;/span&gt;
      &lt;span style="color: #ff0000"&gt;Data&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"M0,0 L11.5,0 11.5,30 5.75,40 0,30z"&lt;/span&gt;
      &lt;span style="color: #ff0000"&gt;MouseLeftButtonUp&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"javascript:slider_thumb_MouseLeftButtonUp"&lt;/span&gt;
      &lt;span style="color: #ff0000"&gt;MouseMove&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"javascript:slider_thumb_MouseMove"&lt;/span&gt;
      &lt;span style="color: #ff0000"&gt;MouseLeftButtonDown&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"javascript:slider_thumb_MouseLeftButtonDown"&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;Canvas&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;Canvas&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;var&lt;/span&gt; mouseDownPosition = 0;
&lt;span style="color: #0000ff"&gt;var&lt;/span&gt; mouseDownValue = -1;

&lt;span style="color: #0000ff"&gt;function&lt;/span&gt; slider_Loaded(sender, args) {
    slider_SetValue(slider, 0);
}

&lt;span style="color: #0000ff"&gt;function&lt;/span&gt; slider_MouseLeftButtonDown(sender, args) {
    &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; coordinate = args.x;
    coordinate -= sender["&lt;span style="color: #8b0000"&gt;Canvas.Left&lt;/span&gt;"];
    slider_SetValue(sender, coordinate);
}

&lt;span style="color: #0000ff"&gt;function&lt;/span&gt; slider_thumb_MouseLeftButtonDown(sender, args) {
    &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; slider = sender.findName("&lt;span style="color: #8b0000"&gt;slider&lt;/span&gt;");
    sender.captureMouse();
    mouseDownValue = slider_GetValue(slider);
    mouseDownPosition = args.x;
}

&lt;span style="color: #0000ff"&gt;function&lt;/span&gt; slider_thumb_MouseLeftButtonUp(sender, args) {
    &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; slider = sender.findName("&lt;span style="color: #8b0000"&gt;slider&lt;/span&gt;");
    sender.releaseMouseCapture();
    mouseDownValue = -1;
}

&lt;span style="color: #0000ff"&gt;function&lt;/span&gt; slider_thumb_MouseMove(sender, args) {
    &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; slider = sender.findName("&lt;span style="color: #8b0000"&gt;slider&lt;/span&gt;");
    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (mouseDownValue != -1) {
        &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; newValue = mouseDownValue
        + (args.x - mouseDownPosition);
        
        slider_SetValue(slider, newValue);
    }
}

&lt;span style="color: #0000ff"&gt;function&lt;/span&gt; slider_GetValue(sender) {
    &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; thumb = sender.findName("&lt;span style="color: #8b0000"&gt;slider_thumb&lt;/span&gt;");
    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; thumb["&lt;span style="color: #8b0000"&gt;Canvas.Left&lt;/span&gt;"] + .5 * thumb.width;
}

&lt;span style="color: #0000ff"&gt;function&lt;/span&gt; slider_SetValue(sender, newValue) {
    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (newValue &amp;gt; sender.width) {
        newValue = sender.width;
    }
    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (newValue &amp;lt; 0) {
        newValue = 0;
    }
    &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; thumb = sender.findName("&lt;span style="color: #8b0000"&gt;slider_thumb&lt;/span&gt;");
    thumb["&lt;span style="color: #8b0000"&gt;Canvas.Left&lt;/span&gt;"] = newValue - .5 * thumb.width;
}&lt;/pre&gt;
&lt;div class="agHost" id="agHost2"&gt;&lt;/div&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;a class="agButton" href="javascript:start('agHost2', 'agButton2', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/controls-slider.html');"&gt;重新开始&lt;/a&gt;&lt;a class="agButton" id="agButton2" href="javascript:turn('agHost2', 'agButton2', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/controls-slider.html');"&gt;查看内容&lt;/a&gt;&lt;/p&gt;
&lt;script language="javascript"&gt;
start('agHost2', 'agButton2', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/controls-slider.html');
&lt;/script&gt;

&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;&lt;a name="whatsnext"&gt;&lt;/a&gt;
&lt;p style="font-size: 14pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;下面该做什么呢？&lt;/strong&gt;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;在下一部分&amp;#8220;&lt;a href="#" target="_blank"&gt;创建一个Visual Studio的WPF/E项目&lt;/a&gt;&amp;#8221;中，您会了解如何在Visual Studio中创建一个WPF/E项目。&lt;/p&gt;</description>
      <comments>http://blog.zhaojie.me/2006/12/wpfe-ctp-quick-start-part-11.html#comments</comments>
      <pubDate>Thu, 21 Dec 2006 05:27:00 GMT</pubDate>
      <lastBuildDate>Thu, 21 Dec 2006 05:27:00 GMT</lastBuildDate>
    </item>
    <item>
      <author>jeffz@live.com (老赵)</author>
      <category domain="http://blog.zhaojie.me/front-end/">前端表现</category>
      <category domain="http://blog.zhaojie.me/translation/">翻译引进</category>
      <title>WPF/E CTP Quick Start - 第十部分：脚本和鼠标事件（翻译）</title>
      <link>http://blog.zhaojie.me/2006/12/wpfe-ctp-quick-start-part-10.html</link>
      <guid>http://blog.zhaojie.me/2006/12/wpfe-ctp-quick-start-part-10.html</guid>
      <description>&lt;link href="http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/cnblogs/QuickStart.css" type="text/css" rel="stylesheet"&gt; &lt;script src="http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/cnblogs/QuickStart.js" type="text/javascript"&gt;&lt;/script&gt;  &lt;div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 5px; font-size: 10pt; padding-bottom: 5px; border-left: #cccccc 1px solid; padding-top: 5px; border-bottom: #cccccc 1px solid; font-family: verdana"&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;WPF/E支持使用JavaScript进行编程，能够使您为WPF/E内容增加交互性。&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;这篇文档包含了如下部分：&lt;/p&gt; &lt;ul&gt; &lt;li class="WpfeQS"&gt;&lt;a href="#scriptingandevents"&gt;脚本与事件&lt;/a&gt;&amp;nbsp;  &lt;li class="WpfeQS"&gt;&lt;a href="#settingproperties"&gt;设置属性&lt;/a&gt;&amp;nbsp;  &lt;li class="WpfeQS"&gt;&lt;a href="#settingattachedproperties"&gt;设置附加属性&lt;/a&gt;&amp;nbsp;  &lt;li class="WpfeQS"&gt;&lt;a href="#commonmouseevents"&gt;公有鼠标事件&lt;/a&gt;&amp;nbsp;  &lt;li class="WpfeQS"&gt;&lt;a href="#naming"&gt;为对象命名并重新获取它们&lt;/a&gt;&amp;nbsp;  &lt;li class="WpfeQS"&gt;&lt;a href="#dynamicallycreating"&gt;动态创建WPF/E对象&lt;/a&gt;&amp;nbsp;  &lt;li class="WpfeQS"&gt;&lt;a href="#controllinganimations"&gt;交互地控制动画&lt;/a&gt;&amp;nbsp;  &lt;li class="WpfeQS"&gt;&lt;a href="#whatsnext"&gt;下面该做什么呢？&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;&lt;a name="scriptingandevents"&gt;&lt;/a&gt; &lt;p style="font-size: 14pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;脚本与事件&lt;/strong&gt;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;WPF/E能够让您在事件触发时执行JavaScript代码，例如一个对象被加载之后，或者鼠标进入了一个对象。这样的脚本被称之为&amp;#8220;Event Handler&amp;#8221;。&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;为了定义一个&amp;#8220;Event Handler&amp;#8221;，您需要执行以下两步：&lt;/p&gt; &lt;ul&gt; &lt;li class="WpfeQS"&gt; &lt;p&gt;在一个XAML文件里，添加下面的属性，使对象能够触发您的函数。&lt;/p&gt; &lt;p style="font-family: courier new"&gt;&lt;em&gt;someEvent="javaScript:myFunction"&lt;/em&gt;&lt;/p&gt; &lt;p&gt;其中someEvent是您希望响应的事件名，而myFunction是您希望处理该事件的函数。&lt;/p&gt; &lt;li class="WpfeQS"&gt;在您的JavaScript文件中定义该函数。（关于建立一个JavaScript文件，请参照《&lt;a href="http://blog.zhaojie.me/2006/12/wpfe-ctp-quick-start-part-1.html" target="_blank"&gt;WPF/E CTP Quick Start - 第一部分：创建一个WPF/E项目&lt;/a&gt;》。）&lt;/li&gt;&lt;/ul&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;让我们来尝试写一个示例。在WPF/E中，所有的&lt;strong&gt;Canvas&lt;/strong&gt;和形状元素都有一个事件叫做&lt;strong&gt;MouseLefButtonDown&lt;/strong&gt;，它会在用户鼠标在元素之上，并且左键被按下时被触发。让我们来为这个事件写一个Event Hander，调用JavaScript的alert函数来创建一个对话框。&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Canvas&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"300"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"300"&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"http://schemas.microsoft.com/client/2007"&lt;/span&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;span style="color: #ff0000"&gt;Background&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"transparent"&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;MouseLeftButtonDown&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"javascript:helloworld"&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: #ff0000"&gt;Text&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"click me"&lt;/span&gt;  &lt;span style="color: #ff0000"&gt;FontSize&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"50"&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;Canvas&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;function&lt;/span&gt; helloworld() {
    &lt;span style="color: #0000ff"&gt;alert&lt;/span&gt;("&lt;span style="color: #8b0000"&gt;hello world&lt;/span&gt;");
}&lt;/pre&gt;
&lt;div class="agHost" id="agHost0"&gt;&lt;/div&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;a class="agButton" href="javascript:start('agHost0', 'agButton0', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/scripting-helloworld.html');"&gt;重新开始&lt;/a&gt;&lt;a class="agButton" id="agButton0" href="javascript:turn('agHost0', 'agButton0', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/scripting-helloworld.html');"&gt;查看内容&lt;/a&gt;&lt;/p&gt;
&lt;script language="javascript"&gt;
start('agHost0', 'agButton0', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/scripting-helloworld.html');
&lt;/script&gt;

&lt;p style="font-size: 10pt; font-family: verdana"&gt;您在声明一个Event Handler时不需要指定参数，但是如果您确实需要的话，您可以使用第一个参数&amp;#8220;sender&amp;#8221;作为触发事件的元素，而第二个参数&amp;#8220;args&amp;#8221;是一个包含了事件信息的对象。&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;&lt;a name="settingproperties"&gt;&lt;/a&gt;
&lt;p style="font-size: 14pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;设置属性&lt;/strong&gt;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;您可以使用JavaScript来设置WPF/E对象的属性。当一个属性为一个字符串或一个数字时，您可以简单地使用JavaScirpt设置它。如果属性为一个WPF/E对象，但是它有个类型转换器，例如一个&lt;strong&gt;SolidColorBrush&lt;/strong&gt;，您可以用字符串形式来设置它。否则，您必须使用&lt;strong&gt;createFromXaml&lt;/strong&gt;方法来实例化一个新的属性值。&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;下面的例子响应了&lt;strong&gt;Canvas&lt;/strong&gt;的&lt;strong&gt;MouseLeftButtonDown&lt;/strong&gt;事件。在这个Event Handler中，通过sender参数访问了&lt;strong&gt;Canvas&lt;/strong&gt;对象。在示例中将&lt;strong&gt;Canvas&lt;/strong&gt;的&lt;strong&gt;Background&lt;/strong&gt;属性设为了红色，并且显示了它的&lt;strong&gt;Height&lt;/strong&gt;属性。&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Canvas&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"300"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"300"&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"http://schemas.microsoft.com/client/2007"&lt;/span&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;span style="color: #ff0000"&gt;Background&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Transparent"&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;MouseLeftButtonDown&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"javascript:changecolor"&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: #ff0000"&gt;Text&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"click me"&lt;/span&gt;  &lt;span style="color: #ff0000"&gt;FontSize&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"50"&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;Canvas&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;function&lt;/span&gt; changecolor(sender, args) {
    sender.background = "&lt;span style="color: #8b0000"&gt;red&lt;/span&gt;";

    &lt;span style="color: #0000ff"&gt;alert&lt;/span&gt;("&lt;span style="color: #8b0000"&gt;Height is &lt;/span&gt;" + sender.Height);
}&lt;/pre&gt;
&lt;div class="agHost" id="agHost1"&gt;&lt;/div&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;a class="agButton" href="javascript:start('agHost1', 'agButton1', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/scripting-properties1.html');"&gt;重新开始&lt;/a&gt;&lt;a class="agButton" id="agButton1" href="javascript:turn('agHost1', 'agButton1', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/scripting-properties1.html');"&gt;查看内容&lt;/a&gt;&lt;/p&gt;
&lt;script language="javascript"&gt;
start('agHost1', 'agButton1', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/scripting-properties1.html');
&lt;/script&gt;

&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;&lt;a name="settingattachedproperties"&gt;&lt;/a&gt;
&lt;p style="font-size: 14pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;设置附加属性&lt;/strong&gt;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;如果要使用JavaScript设置一个附加属性，例如&lt;strong&gt;Canvas.Top&lt;/strong&gt;，您可以使用下面的语法：&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;em&gt;　　object[attachedPropertyName] = value;&lt;/em&gt;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;其中attachedPropertyName您想设置的附加属性的名称。&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;下面的示例在左键被点击之后，将设置&lt;strong&gt;TextBlock&lt;/strong&gt;的&lt;strong&gt;Canvas.Top&lt;/strong&gt;属性设为了70。&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Canvas&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"300"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"300"&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"http://schemas.microsoft.com/client/2007"&lt;/span&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;span style="color: #ff0000"&gt;Background&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Transparent"&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: #ff0000"&gt;Text&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"click me"&lt;/span&gt;  &lt;span style="color: #ff0000"&gt;FontSize&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"50"&lt;/span&gt; 
        &lt;span style="color: #ff0000"&gt;MouseLeftButtonDown&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"javascript:changelocation"&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;Canvas&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;function&lt;/span&gt; changelocation(sender, args) {
    
    sender["&lt;span style="color: #8b0000"&gt;Canvas.Top&lt;/span&gt;"] = 70;
}&lt;/pre&gt;
&lt;div class="agHost" id="agHost2"&gt;&lt;/div&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;a class="agButton" href="javascript:start('agHost2', 'agButton2', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/scripting-properties2.html');"&gt;重新开始&lt;/a&gt;&lt;a class="agButton" id="agButton2" href="javascript:turn('agHost2', 'agButton2', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/scripting-properties2.html');"&gt;查看内容&lt;/a&gt;&lt;/p&gt;
&lt;script language="javascript"&gt;
start('agHost2', 'agButton2', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/scripting-properties2.html');
&lt;/script&gt;

&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;&lt;a name="commonmouseevents"&gt;&lt;/a&gt;
&lt;p style="font-size: 14pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;公有鼠标事件&lt;/strong&gt;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;strong&gt;UIElement&lt;/strong&gt;对象提供了一些不同的鼠标事件供您响应：&lt;strong&gt;MouseLeftButtonDown&lt;/strong&gt;、&lt;strong&gt;MouseLeftButtonUp&lt;/strong&gt;、&lt;strong&gt;MouseEnter&lt;/strong&gt;（在鼠标进入元素时触发）、&lt;strong&gt;MouseLeave&lt;/strong&gt;和&lt;strong&gt;MouseMove&lt;/strong&gt;（鼠标在元素内移动时触发）。鼠标事件在触发之后，能够从args对象的x和y中获得鼠标的位置。&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;下面的例子响应了这些鼠标事件，以改变&lt;strong&gt;Ellipse&lt;/strong&gt;的属性。&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Canvas&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"http://schemas.microsoft.com/client/2007"&lt;/span&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;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;Ellipse&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;"e1"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;MouseMove&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"javascript:e1Move"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;MouseEnter&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"javascript:e1Enter"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;MouseLeave&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"javascript:e1Leave"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;MouseLeftButtonDown&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"javascript:e1Down"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;MouseLeftButtonUp&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"javascript:e1Up"&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: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"100"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Left&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"80"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"30"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;Stroke&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Black"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Fill&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"LightBlue"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;StrokeThickness&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"10"&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;Canvas&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;function&lt;/span&gt; e1Enter(sender, args) {
    sender.stroke = "&lt;span style="color: #8b0000"&gt;red&lt;/span&gt;";
}

&lt;span style="color: #0000ff"&gt;function&lt;/span&gt; e1Leave(sender, args) {
    sender.stroke = "&lt;span style="color: #8b0000"&gt;black&lt;/span&gt;";
}

&lt;span style="color: #0000ff"&gt;function&lt;/span&gt; e1Down(sender, args) {
    sender.fill = "&lt;span style="color: #8b0000"&gt;Green&lt;/span&gt;";
}

&lt;span style="color: #0000ff"&gt;function&lt;/span&gt; e1Up(sender, args) {
    sender.fill = "&lt;span style="color: #8b0000"&gt;LightBlue&lt;/span&gt;";
}

&lt;span style="color: #0000ff"&gt;function&lt;/span&gt; e1Move(sender, args) {
    sender.fill = "&lt;span style="color: #8b0000"&gt;yellow&lt;/span&gt;";
}&lt;/pre&gt;
&lt;div class="agHost" id="agHost3"&gt;&lt;/div&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;a class="agButton" href="javascript:start('agHost3', 'agButton3', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/scripting-mouseevents.html');"&gt;重新开始&lt;/a&gt;&lt;a class="agButton" id="agButton3" href="javascript:turn('agHost3', 'agButton3', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/scripting-mouseevents.html');"&gt;查看内容&lt;/a&gt;&lt;/p&gt;
&lt;script language="javascript"&gt;
start('agHost3', 'agButton3', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/scripting-mouseevents.html');
&lt;/script&gt;

&lt;p style="font-size: 10pt; font-family: verdana"&gt;另一个非常有用的事件是&lt;strong&gt;Loaded&lt;/strong&gt;事件。通常您会在根元素里声明响应该事件，但是&lt;strong&gt;Loaded&lt;/strong&gt;事件可以在任何&lt;strong&gt;UIElement&lt;/strong&gt;上响应。&lt;strong&gt;Loaded&lt;/strong&gt;事件提供了一个非常好的机会，可以让您在WPF/E控件显示的最后进行一些最后的改变。下面的例子响应了&lt;strong&gt;Loaded&lt;/strong&gt;事件，将&lt;strong&gt;Ellipse&lt;/strong&gt;的&lt;strong&gt;Fill&lt;/strong&gt;属性从&lt;strong&gt;Blue&lt;/strong&gt;改成&lt;strong&gt;Red&lt;/strong&gt;。&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Canvas&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"http://schemas.microsoft.com/client/2007"&lt;/span&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;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;Ellipse&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Loaded&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"javascript:ellipse_loaded"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"200"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"200"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Left&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"30"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"30"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;Stroke&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Black"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;StrokeThickness&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"10"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Fill&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"LightBlue"&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;Canvas&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;function&lt;/span&gt; ellipse_loaded(sender, args) {
    sender.Fill = "&lt;span style="color: #8b0000"&gt;Red&lt;/span&gt;";
}&lt;/pre&gt;
&lt;div class="agHost" id="agHost4"&gt;&lt;/div&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;a class="agButton" href="javascript:start('agHost4', 'agButton4', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/scripting-loaded.html');"&gt;重新开始&lt;/a&gt;&lt;a class="agButton" id="agButton4" href="javascript:turn('agHost4', 'agButton4', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/scripting-loaded.html');"&gt;查看内容&lt;/a&gt;&lt;/p&gt;
&lt;script language="javascript"&gt;
start('agHost4', 'agButton4', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/scripting-loaded.html');
&lt;/script&gt;

&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;&lt;a name="naming"&gt;&lt;/a&gt;
&lt;p style="font-size: 14pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;为对象命名并重新获取它们&lt;/strong&gt;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;在之前的示例中，我们使用了JavaScript来修改发起事件的对象，但是如果您需要调用的方法或者修改的属性是属于其它对象的呢？WPF/E元素提供了一个方法叫做&lt;strong&gt;findName&lt;/strong&gt;，可以使您获得子元素。在使用&lt;strong&gt;findNam&lt;/strong&gt;e获得对象之前，您必须使用x:Name属性在申明XAML时为对象提供一个名字。&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;下面的示例在鼠标点击&lt;strong&gt;Canvas&lt;/strong&gt;时修改了&lt;strong&gt;Ellipse&lt;/strong&gt;的&lt;strong&gt;Fill&lt;/strong&gt;属性。当&lt;strong&gt;Canvas&lt;/strong&gt;发起事件时，changeEllipseColor函数被调用，sender是&lt;strong&gt;Canvas&lt;/strong&gt;对象。该函数调用了sender.findName()函数获得了myEllipse对象，并且将它的&lt;strong&gt;Fill&lt;/strong&gt;属性设为了红色。&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Canvas&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"http://schemas.microsoft.com/client/2007"&lt;/span&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;span style="color: #ff0000"&gt;Background&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Transparent"&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;MouseLeftButtonDown&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"javascript:changeEllipseColor"&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: #ff0000"&gt;Text&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"click me"&lt;/span&gt;  &lt;span style="color: #ff0000"&gt;FontSize&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"50"&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;Ellipse&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;"myEllipse"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"200"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"200"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Left&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"30"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"80"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;Stroke&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Black"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;StrokeThickness&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"10"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Fill&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"LightBlue"&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;Canvas&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;function&lt;/span&gt; changeEllipseColor(sender, args) {
    sender.findName("&lt;span style="color: #8b0000"&gt;myEllipse&lt;/span&gt;").Fill = "&lt;span style="color: #8b0000"&gt;red&lt;/span&gt;";
}&lt;/pre&gt;
&lt;div class="agHost" id="agHost5"&gt;&lt;/div&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;a class="agButton" href="javascript:start('agHost5', 'agButton5', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/scripting-FindName.html');"&gt;重新开始&lt;/a&gt;&lt;a class="agButton" id="agButton5" href="javascript:turn('agHost5', 'agButton5', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/scripting-FindName.html');"&gt;查看内容&lt;/a&gt;&lt;/p&gt;
&lt;script language="javascript"&gt;
start('agHost5', 'agButton5', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/scripting-FindName.html');
&lt;/script&gt;

&lt;p style="font-size: 10pt; font-family: verdana"&gt;当您编写的脚本代码并不是被WPF/E元素的事件触发时（例如一个普通的HTML事件），您就无法得到一个sender参数，用来使用&lt;strong&gt;findName&lt;/strong&gt;以获得一个WPF/E对象了。在这个情况下，您可以使用document.getElementById()来获得WPF/E的ActiveX控件，然后可以使用ActiveX控件的&lt;strong&gt;findName&lt;/strong&gt;方法。&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Canvas&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"http://schemas.microsoft.com/client/2007"&lt;/span&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;span style="color: #ff0000"&gt;Background&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Transparent"&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;MouseLeftButtonDown&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"javascript:changeEllipseColor2"&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: #ff0000"&gt;Text&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"click me"&lt;/span&gt;  &lt;span style="color: #ff0000"&gt;FontSize&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"50"&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;Ellipse&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;"myEllipse"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"200"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"200"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Left&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"30"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"80"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;Stroke&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Black"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;StrokeThickness&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"10"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Fill&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"LightBlue"&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;Canvas&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;function&lt;/span&gt; changeEllipseColor2(sender, args) {
    &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; ag6 = &lt;span style="color: #0000ff"&gt;document&lt;/span&gt;.getElementById("&lt;span style="color: #8b0000"&gt;ag6&lt;/span&gt;");
    ag6.findName("&lt;span style="color: #8b0000"&gt;myEllipse&lt;/span&gt;").fill = "&lt;span style="color: #8b0000"&gt;red&lt;/span&gt;";
}&lt;/pre&gt;
&lt;div class="agHost" id="agHost6"&gt;&lt;/div&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;a class="agButton" href="javascript:start('agHost6', 'agButton6', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/scripting-getElementById.html');"&gt;重新开始&lt;/a&gt;&lt;a class="agButton" id="agButton6" href="javascript:turn('agHost6', 'agButton6', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/scripting-getElementById.html');"&gt;查看内容&lt;/a&gt;&lt;/p&gt;
&lt;script language="javascript"&gt;
start('agHost6', 'agButton6', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/scripting-getElementById.html');
&lt;/script&gt;

&lt;p style="font-size: 10pt; font-family: verdana"&gt;在之前的例子里，ag6是您在HTML页面中创建WPF/E的ActiveX控件时，传入new agHost()ID，例如在文档中&amp;#8220;&lt;a href="http://blog.zhaojie.me/2006/12/wpfe-ctp-quick-start-part-1.html" target="_blank"&gt;第一部分：创建一个WPF/E项目&lt;/a&gt;&amp;#8221;描述的那样：&lt;/p&gt;&lt;pre class="code"&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;language&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"javascript"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
    &lt;span style="color: #008000"&gt;// 创建一个WPF/E的ActiveX控件，这里的&lt;/span&gt;
    &lt;span style="color: #008000"&gt;// 方法使您的WPF/E的内容在这个ActiveX控件&lt;/span&gt;
    &lt;span style="color: #008000"&gt;// 被点击之前就创建完毕。&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; agHost(
       &lt;span style="color: #008000"&gt;// 用于插入WPF/E ActiveX控件的元素，一般会使用&lt;/span&gt;
        &lt;span style="color: #008000"&gt;// DIV元素，如果您在上一步改变了HTML元素的ID，&lt;/span&gt;
        &lt;span style="color: #008000"&gt;// 您在这里也必须相应的改变。&lt;/span&gt;
        "&lt;span style="color: #8b0000"&gt;agControl1Host&lt;/span&gt;",
       &lt;span style="color: #008000"&gt;// WPF/E ActiveX控件的ID&lt;/span&gt;
       "&lt;font color="#8b0000"&gt;ag6&lt;/font&gt;", 
       &lt;span style="color: #008000"&gt;// 控件宽度&lt;/span&gt;
        "&lt;span style="color: #8b0000"&gt;300px&lt;/span&gt;", 
       &lt;span style="color: #008000"&gt;// 控件高度&lt;/span&gt;
        "&lt;span style="color: #8b0000"&gt;300px&lt;/span&gt;", 
       &lt;span style="color: #008000"&gt;// 控件的背景色&lt;/span&gt;
        "&lt;span style="color: #8b0000"&gt;#D6D6D6&lt;/span&gt;", 
       &lt;span style="color: #008000"&gt;// 源元素（存放XAML内容的Script标签）&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;, 
       &lt;span style="color: #008000"&gt;// 存放WPF/E内容的XAML文件的URI&lt;/span&gt;
        "&lt;span style="color: #8b0000"&gt;myxaml.xaml&lt;/span&gt;", 
       &lt;span style="color: #008000"&gt;// 是否是无窗的&lt;/span&gt;
        "&lt;span style="color: #8b0000"&gt;false&lt;/span&gt;", 
       &lt;span style="color: #008000"&gt;// 最大帧率（Frame Rate）&lt;/span&gt;
        "&lt;span style="color: #8b0000"&gt;30&lt;/span&gt;",
       &lt;span style="color: #008000"&gt;// 处理错误的Handler，&lt;/span&gt;
        &lt;span style="color: #008000"&gt;// 您能够将其设为一个方法的引用。&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;null&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: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;您可以在创建了ActiveX控件之后使用下面的代码，这使您能在以后不必再次获得ActiveX控件了。&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #008000"&gt;// 方便起见，为WPF/E的ActiveX控件创建一个全局变量&lt;/span&gt;
&lt;span style="color: #008000"&gt;// 它能让我们调用findName方法。&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;var&lt;/span&gt; ag6 = &lt;span style="color: #0000ff"&gt;document&lt;/span&gt;.getElementById("&lt;span style="color: #8b0000"&gt;ag6&lt;/span&gt;");&lt;/pre&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;&lt;a name="dynamicallycreating"&gt;&lt;/a&gt;
&lt;p style="font-size: 14pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;动态创建WPF/E对象&lt;/strong&gt;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;您可以使用&lt;strong&gt;createFromXaml&lt;/strong&gt;方法使用JavaScript来创建一个新的WPF/E对象。下面的示例在&lt;strong&gt;Canvas&lt;/strong&gt;对象被鼠标左键被点击时，创建并添加了一个新的&lt;strong&gt;Ellipse&lt;/strong&gt;对象。&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Canvas&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"300"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"300"&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"http://schemas.microsoft.com/client/2007"&lt;/span&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;span style="color: #ff0000"&gt;Background&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Transparent"&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;MouseLeftButtonDown&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"javascript:createEllipse"&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: #ff0000"&gt;Text&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"click for circle"&lt;/span&gt;  &lt;span style="color: #ff0000"&gt;FontSize&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"40"&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;Canvas&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;function&lt;/span&gt; createEllipse(sender, args) {
    &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; agControl = &lt;span style="color: #0000ff"&gt;document&lt;/span&gt;.getElementById("&lt;span style="color: #8b0000"&gt;ag7&lt;/span&gt;");
    &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; e = agControl.createFromXaml(
        '&amp;lt;Ellipse Height="&lt;span style="color: #8b0000"&gt;200&lt;/span&gt;" Width="&lt;span style="color: #8b0000"&gt;200&lt;/span&gt;" Fill="&lt;span style="color: #8b0000"&gt;Blue&lt;/span&gt;"/&amp;gt;');
    &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; canvas = sender;
    canvas.children.Add(e);
}&lt;/pre&gt;
&lt;div class="agHost" id="agHost7"&gt;&lt;/div&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;a class="agButton" href="javascript:start('agHost7', 'agButton7', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/scripting-create.html');"&gt;重新开始&lt;/a&gt;&lt;a class="agButton" id="agButton7" href="javascript:turn('agHost7', 'agButton7', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/scripting-create.html');"&gt;查看内容&lt;/a&gt;&lt;/p&gt;
&lt;script language="javascript"&gt;
start('agHost7', 'agButton7', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/scripting-create.html');
&lt;/script&gt;

&lt;p style="font-size: 10pt; font-family: verdana"&gt;请注意，JavaScript需要您将字符串放在同一行中，除非您用+连接多个字符串。还要注意的是在这里XAML单引号和双引号的使用：使用单引号来表示JavaScript字符串，在XAML字符串中使用双引号。&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;&lt;a name="controllinganimations"&gt;&lt;/a&gt;
&lt;p style="font-size: 14pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;交互地控制动画&lt;/strong&gt;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;您可以使用Event Handler来控制&lt;a href="http://blog.zhaojie.me/2006/12/wpfe-ctp-quick-start-part-9.html" target="_blank"&gt;动画&lt;/a&gt;。将您希望控制的Storyboard给定一个名字，这样您就可以使用它的begin、stop、pause和resume方法来交互式地控制动画。&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Storyboard&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;"animation"&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;Storyboard&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;TargetName&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"e1"&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;Storyboard&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;TargetProperty&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"(Canvas.Left)"&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;BeginTime&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"1"&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;DoubleAnimation&lt;/span&gt; &lt;span style="color: #ff0000"&gt;RepeatBehavior&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Forever"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;To&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"300"&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;Storyboard&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;function&lt;/span&gt; animation_stop(sender, args) {
    sender.findName("&lt;span style="color: #8b0000"&gt;animation&lt;/span&gt;").&lt;span style="color: #0000ff"&gt;stop&lt;/span&gt;();
}

&lt;span style="color: #0000ff"&gt;function&lt;/span&gt; animation_pause(sender, args) {
    sender.findName("&lt;span style="color: #8b0000"&gt;animation&lt;/span&gt;").pause();
}

&lt;span style="color: #0000ff"&gt;function&lt;/span&gt; animation_begin(sender, args) {
    sender.findName("&lt;span style="color: #8b0000"&gt;animation&lt;/span&gt;").begin();
}&lt;/pre&gt;
&lt;div class="agHost" id="agHost8"&gt;&lt;/div&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;a class="agButton" href="javascript:start('agHost8', 'agButton8', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/scripting-animations.html');"&gt;重新开始&lt;/a&gt;&lt;a class="agButton" id="agButton8" href="javascript:turn('agHost8', 'agButton8', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/scripting-animations.html');"&gt;查看内容&lt;/a&gt;&lt;/p&gt;
&lt;script language="javascript"&gt;
start('agHost8', 'agButton8', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/scripting-animations.html');
&lt;/script&gt; &lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&amp;nbsp;&lt;/p&gt;
&lt;a name=whatsnext&gt;&lt;/a&gt;
&lt;p style="FONT-SIZE: 14pt; COLOR: #888888; FONT-FAMILY: verdana"&gt;&lt;strong&gt;下面该做什么呢？&lt;/strong&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;在下一部分&amp;#8220;&lt;a href="http://blog.zhaojie.me/2006/12/wpfe-ctp-quick-start-part-11.html" target=_blank&gt;示例控件&lt;/a&gt;&amp;#8221;中，您会看到几个例子，展示了如何使用WPF/E来创建交互式的控件。&lt;/p&gt;</description>
      <comments>http://blog.zhaojie.me/2006/12/wpfe-ctp-quick-start-part-10.html#comments</comments>
      <pubDate>Mon, 18 Dec 2006 07:56:00 GMT</pubDate>
      <lastBuildDate>Mon, 18 Dec 2006 07:56:00 GMT</lastBuildDate>
    </item>
    <item>
      <author>jeffz@live.com (老赵)</author>
      <category domain="http://blog.zhaojie.me/front-end/">前端表现</category>
      <category domain="http://blog.zhaojie.me/translation/">翻译引进</category>
      <title>WPF/E CTP Quick Start - 第九部分：动画（翻译）</title>
      <link>http://blog.zhaojie.me/2006/12/wpfe-ctp-quick-start-part-9.html</link>
      <guid>http://blog.zhaojie.me/2006/12/wpfe-ctp-quick-start-part-9.html</guid>
      <description>&lt;link href="http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/cnblogs/QuickStart.css" type="text/css" rel="stylesheet"&gt; &lt;script src="http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/cnblogs/QuickStart.js" type="text/javascript"&gt;&lt;/script&gt;  &lt;div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 5px; font-size: 10pt; padding-bottom: 5px; border-left: #cccccc 1px solid; padding-top: 5px; border-bottom: #cccccc 1px solid; font-family: verdana"&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;WPF/E能够让您使用标记来定义动画。这篇QuickStart介绍了WPF/E的动画特性，并且带领您创建您的第一个WPF/E动画。&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;这篇QuickStart包含了如下部分：&lt;/p&gt; &lt;ul&gt; &lt;li class="WpfeQS"&gt;&lt;a href="#walkthrough"&gt;演练：为一个对象添加动画效果&lt;/a&gt;  &lt;ul&gt; &lt;li class="WpfeQS"&gt;&lt;a href="#step1"&gt;第一步：寻找对象&lt;/a&gt;  &lt;li class="WpfeQS"&gt;&lt;a href="#step2"&gt;第二步：创建一个EventTrigger&lt;/a&gt;  &lt;li class="WpfeQS"&gt;&lt;a href="#step3"&gt;第三步：创建一个Storyboard和一个动画&lt;/a&gt;&lt;/il&gt;&lt;/li&gt;&lt;/ul&gt; &lt;li class="WpfeQS"&gt;&lt;a href="#otheranimationtypes"&gt;其它类型的动画&lt;/a&gt;  &lt;li class="WpfeQS"&gt;&lt;a href="#timelineproperties"&gt;Timeline的属性&lt;/a&gt;  &lt;li class="WpfeQS"&gt;&lt;a href="#fromtobyanimations"&gt;指定动画变换的值&lt;/a&gt;  &lt;li class="WpfeQS"&gt;&lt;a href="#multipleanimations"&gt;在同一个对象上添加多个动画&lt;/a&gt;  &lt;li class="WpfeQS"&gt;&lt;a href="#whatsnext"&gt;下面该做什么呢？&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;&lt;a name="walkthrough"&gt;&lt;/a&gt; &lt;p style="font-size: 14pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;演练：为一个对象添加动画效果&lt;/strong&gt;&lt;/p&gt;&lt;a name="step1"&gt;&lt;/a&gt; &lt;p style="font-size: 11pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;第一步：寻找对象&lt;/strong&gt;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;首先，您需要一个对象，可以把动画效果添加之上。让我们先使用一个&lt;strong&gt;Ellipse&lt;/strong&gt;。下面的例子创建了一个&lt;strong&gt;Ellipse&lt;/strong&gt;并将它填充成黑色。&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Canvas&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"http://schemas.microsoft.com/client/2007"&lt;/span&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;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;Ellipse&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;"ellipse"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"20"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"20"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Left&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"30"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"30"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;Fill&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"black"&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;Canvas&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;div class="agHost" id="agHost0"&gt;&lt;/div&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;a class="agButton" href="javascript:start('agHost0', 'agButton0', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/animation-ellipse.html');"&gt;重新开始&lt;/a&gt;&lt;a class="agButton" id="agButton0" href="javascript:turn('agHost0', 'agButton0', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/animation-ellipse.html');"&gt;查看内容&lt;/a&gt;&lt;/p&gt;
&lt;script language="javascript"&gt;
start('agHost0', 'agButton0', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/animation-ellipse.html');
&lt;/script&gt;

&lt;p style="font-size: 10pt; font-family: verdana"&gt;请注意，这个Ellipse有一个名字：&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: courier new"&gt;x:Name="ellipse"&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;这个Ellipse需要有一个名字，这样它才能够被添加动画。现在您可以有一个用于动画的对象了，下一步则是添加一个用于开始动画的&lt;strong&gt;EventTrigger&lt;/strong&gt;。&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;&lt;a name="step2"&gt;&lt;/a&gt;
&lt;p style="font-size: 11pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;第二步：创建一个EventTrigger&lt;/strong&gt;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;strong&gt;EventTrigger&lt;/strong&gt;会在被它被触发时执行一个动作。从它的名字可以看出，触发它的是一个事件，一个由它的&lt;strong&gt;RoutedEvent&lt;/strong&gt;属性指定的事件。因为您希望这个&lt;strong&gt;EventTrigger&lt;/strong&gt;开始一个动画，那么使用一个&lt;strong&gt;BeginStoryBoard&lt;/strong&gt;对象作为它的动作。&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;您也需要决定是由哪个事件来触发这个动画。在这里非常简单，因为&lt;strong&gt;EventTrigger&lt;/strong&gt;只支持一个事件，&lt;strong&gt;Loaded&lt;/strong&gt;事件，因此我们将&lt;strong&gt;RoutedEvent&lt;/strong&gt;属性设为Canvas.Loaded（最终我们会使用别的东西来触发这个动画）。这样，当&lt;strong&gt;Canvas&lt;/strong&gt;加载时我们的动画就会被开启。下面是到此为止的标记。&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Canvas&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"http://schemas.microsoft.com/client/2007"&lt;/span&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;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;Canvas.Triggers&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;EventTrigger&lt;/span&gt; &lt;span style="color: #ff0000"&gt;RoutedEvent&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Canvas.Loaded"&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;EventTrigger.Actions&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;BeginStoryboard&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
                    
                    &lt;span style="color: #008000"&gt;&amp;lt;!-- Insert Storyboard here. --&amp;gt;&lt;/span&gt;
                &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;BeginStoryboard&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;EventTrigger.Actions&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;EventTrigger&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;Canvas.Triggers&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;Ellipse&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;"ellipse"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"20"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"20"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Left&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"30"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"30"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;Fill&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"black"&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;Canvas&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;div class="agHost" id="agHost1"&gt;&lt;/div&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;a class="agButton" href="javascript:start('agHost1', 'agButton1', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/animation-triggers.html');"&gt;重新开始&lt;/a&gt;&lt;a class="agButton" id="agButton1" href="javascript:turn('agHost1', 'agButton1', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/animation-triggers.html');"&gt;查看内容&lt;/a&gt;&lt;/p&gt;
&lt;script language="javascript"&gt;
start('agHost1', 'agButton1', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/animation-triggers.html');
&lt;/script&gt;

&lt;p style="font-size: 10pt; font-family: verdana"&gt;现在，您已经为创建一个&lt;strong&gt;Storyboard&lt;/strong&gt;和动画做好准备了。&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;&lt;a name="step3"&gt;&lt;/a&gt;
&lt;p style="font-size: 11pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;第三步：创建一个Storyboard和一个动画&lt;/strong&gt;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;一个&lt;strong&gt;Storyboard&lt;/strong&gt;可以用于描述和控制一个或多个动画。在这个例子里，我们只用了一个动画。在WPF/E中，您通过把动画应用到对象的属性上来添加动画效果。使用一个&lt;strong&gt;DoubleAnimation&lt;/strong&gt;把一个动画效果运用在&lt;strong&gt;Ellipse&lt;/strong&gt;的&lt;strong&gt;Canvas.Left&lt;/strong&gt;属性上。您使用了&lt;strong&gt;DoubleAnimation&lt;/strong&gt;因为这个被操作的属性，&lt;strong&gt;Canvas.Left&lt;/strong&gt;，是一个&lt;strong&gt;Double&lt;/strong&gt;类型（一个双精度浮点数）的属性。&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;为了使动画生效，需要为它指定一个目标名称（Storyboard.TargetName="ellipse"）、一个目标属性（Storyboard.TargetProperty="(Canvas.Left)"）、一个变换的值（To="300"）和一个&lt;strong&gt;Duration&lt;/strong&gt;（Duration="0:0:1"）。这个&lt;strong&gt;Duration&lt;/strong&gt;属性指定了动画效果从它的起始值到结束值的变化所用的时间长度。0:0:1表示这个&lt;strong&gt;Duration&lt;/strong&gt;为1秒钟。&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Canvas&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"http://schemas.microsoft.com/client/2007"&lt;/span&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;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;Canvas.Triggers&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;EventTrigger&lt;/span&gt; &lt;span style="color: #ff0000"&gt;RoutedEvent&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Canvas.Loaded"&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;EventTrigger.Actions&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;BeginStoryboard&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;Storyboard&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;DoubleAnimation&lt;/span&gt; 
                            &lt;span style="color: #ff0000"&gt;Storyboard&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;TargetName&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"ellipse"&lt;/span&gt;
                            &lt;span style="color: #ff0000"&gt;Storyboard&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;TargetProperty&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"(Canvas.Left)"&lt;/span&gt;
                            &lt;span style="color: #ff0000"&gt;To&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"300"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Duration&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"0:0:1"&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;Storyboard&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;BeginStoryboard&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;EventTrigger.Actions&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;EventTrigger&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;Canvas.Triggers&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;Ellipse&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;"ellipse"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"20"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"20"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Left&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"30"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"30"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;Fill&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"black"&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;Canvas&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;div class="agHost" id="agHost2"&gt;&lt;/div&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;a class="agButton" href="javascript:start('agHost2', 'agButton2', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/animation-double.html');"&gt;重新开始&lt;/a&gt;&lt;a class="agButton" id="agButton2" href="javascript:turn('agHost2', 'agButton2', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/animation-double.html');"&gt;查看内容&lt;/a&gt;&lt;/p&gt;
&lt;script language="javascript"&gt;
start('agHost2', 'agButton2', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/animation-double.html');
&lt;/script&gt;

&lt;p style="font-size: 10pt; font-family: verdana"&gt;您使用了&lt;strong&gt;DoubleAnimation&lt;/strong&gt;因为这个被操作的属性，&lt;strong&gt;Canvas.Left&lt;/strong&gt;，是一个&lt;strong&gt;Double&lt;/strong&gt;类型（一个双精度浮点数）的属性。&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;恭喜！您刚才创建了您的第一个WPF/E动画。如果您希望对WPF/E动画系统了解更多，请继续阅读下面的内容。&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;&lt;a name="otheranimationtypes"&gt;&lt;/a&gt;
&lt;p style="font-size: 14pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;其它类型的动画&lt;/strong&gt;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;WPF/E还支持颜色的动画（&lt;strong&gt;ColorAnimation&lt;/strong&gt;）和点的动画效果（&lt;strong&gt;PointAnimation&lt;/strong&gt;）。当您对颜色添加动画效果时，请记住一个颜色和&lt;strong&gt;SolidColorBrush&lt;/strong&gt;的区别。当您为一个形状的&lt;strong&gt;Stroke&lt;/strong&gt;和&lt;strong&gt;Fill&lt;/strong&gt;属性指定一个颜色名或者十六进制值时，WPF/E会将其转换为使用&lt;strong&gt;SolidColorBrush&lt;/strong&gt;的方式。当您要为一个形状的&lt;strong&gt;Stroke&lt;/strong&gt;或&lt;strong&gt;Fill&lt;/strong&gt;添加动画时，您需要操作设置该属性的&lt;strong&gt;SolidColorBrush&lt;/strong&gt;对象的&lt;strong&gt;Color&lt;/strong&gt;。通常，当您要使用一个动画操作一个包含画刷的属性时，最好是使用复杂的语法来声明那个画刷，而不是使用一个颜色名或者十六进制值，这样您就可以为它添加一个名字了。&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;下面的例子为两个Ellipse添加了动画效果。第一个Ellipse的属性使用一个&lt;strong&gt;SolidColorBrush&lt;/strong&gt;显式设置了Fill属性。在例子里为&lt;strong&gt;SolidColorBrush&lt;/strong&gt;提供了一个名字，并操作了它的&lt;strong&gt;Color&lt;/strong&gt;属性。第二个动画就有些复杂了，因为第二个Ellipse的&lt;strong&gt;Fill&lt;/strong&gt;属性被设置为一个颜色名。当这个标记被执行时，系统会创建一个&lt;strong&gt;SolidColorBursh&lt;/strong&gt;，我们只能间接地为属性添加动画。&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Canvas&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"http://schemas.microsoft.com/client/2007"&lt;/span&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;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;Canvas.Triggers&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;EventTrigger&lt;/span&gt; &lt;span style="color: #ff0000"&gt;RoutedEvent&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Canvas.Loaded"&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;EventTrigger.Actions&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;BeginStoryboard&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;Storyboard&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;ColorAnimation&lt;/span&gt; 
                            &lt;span style="color: #ff0000"&gt;Storyboard&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;TargetName&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"e1_brush"&lt;/span&gt;
                            &lt;span style="color: #ff0000"&gt;Storyboard&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;TargetProperty&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Color"&lt;/span&gt;
                            &lt;span style="color: #ff0000"&gt;From&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Red"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;To&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Blue"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Duration&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"0:0: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;ColorAnimation&lt;/span&gt; 
                            &lt;span style="color: #ff0000"&gt;Storyboard&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;TargetName&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"e2"&lt;/span&gt;
                            &lt;span style="color: #ff0000"&gt;Storyboard&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;TargetProperty&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"(Fill).(Color)"&lt;/span&gt;
                            &lt;span style="color: #ff0000"&gt;From&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Red"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;To&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Blue"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Duration&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"0:0: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;Storyboard&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;BeginStoryboard&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;EventTrigger.Actions&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;EventTrigger&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;Canvas.Triggers&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;Ellipse&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Fill&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Black"&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: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"100"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Left&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"30"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"30"&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;Ellipse.Fill&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;SolidColorBrush&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;"e1_brush"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Color&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"black"&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;Ellipse.Fill&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;Ellipse&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;Ellipse&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;"e2"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Fill&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Black"&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: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"100"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Left&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"30"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"130"&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;Canvas&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;div class="agHost" id="agHost3"&gt;&lt;/div&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;a class="agButton" href="javascript:start('agHost3', 'agButton3', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/animation-point-color.html');"&gt;重新开始&lt;/a&gt;&lt;a class="agButton" id="agButton3" href="javascript:turn('agHost3', 'agButton3', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/animation-point-color.html');"&gt;查看内容&lt;/a&gt;&lt;/p&gt;
&lt;script language="javascript"&gt;
start('agHost3', 'agButton3', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/animation-point-color.html');
&lt;/script&gt;

&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;&lt;a name="timelineproperties"&gt;&lt;/a&gt;
&lt;p style="font-size: 14pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;Timeline的属性&lt;/strong&gt;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;strong&gt;Storyboard&lt;/strong&gt;和&lt;strong&gt;DoubleAnimation&lt;/strong&gt;都是&lt;strong&gt;Timeline&lt;/strong&gt;类型的对象。Timeline有许多有用的属性：&lt;/p&gt;
&lt;ul&gt;
&lt;li class="WpfeQS"&gt;&lt;strong&gt;Storyboard.TargetName&lt;/strong&gt;：您操作的对象的名称。如果您不指定一个&lt;strong&gt;Storyboard.TargetName&lt;/strong&gt;的值，Timeline会使用它父Timeline的&lt;strong&gt;Storyboard.TargetName&lt;/strong&gt;。如果您不不指定任何父Timeline的&lt;strong&gt;Storyboard.TargetName&lt;/strong&gt;属性，Timeline则会找到使用&lt;strong&gt;EventTrigger&lt;/strong&gt;来启动它的那个对象。 
&lt;li class="WpfeQS"&gt;&lt;strong&gt;Storyboard.TargetProperty&lt;/strong&gt;：您操作的属性。如果您不指定&lt;strong&gt;Storyboard.TargetProperty&lt;/strong&gt;，Timeline会使用它父Timeline的&lt;strong&gt;Storyboard.TargetProperty&lt;/strong&gt;。这个属性所使用的语法由它操作的属性类型决定： 
&lt;ul&gt;
&lt;li class="WpfeQS"&gt;指定附加属性时所用的语法："&lt;em&gt;(ownerType.propertyName)&lt;/em&gt;"。例如："(Canvas.Top)"指定了&lt;strong&gt;Canvas.Top&lt;/strong&gt;属性。 
&lt;li class="WpfeQS"&gt;指定其它类型属性时所用的语法："&lt;em&gt;proeprtyName&lt;/em&gt;"。例如："Opacity"指定了&lt;strong&gt;Opacity&lt;/strong&gt;属性。&lt;/li&gt;&lt;/ul&gt;
&lt;li class="WpfeQS"&gt;&lt;strong&gt;BeginTime&lt;/strong&gt;：Timeline开始的时间。请注意您在使用的语法，因为在这里默认的单位是&amp;#8220;天&amp;#8221;（简单地将该属性设为2，则表示&lt;strong&gt;BeginTime&lt;/strong&gt;为2天！）。使用下面的语法来指定小时，分钟和秒：&amp;#8220;&lt;em&gt;小时:分钟:秒&lt;/em&gt;&amp;#8221;。例如，&amp;#8220;0:0:2&amp;#8221;将&lt;strong&gt;BeginTime&lt;/strong&gt;设为2秒（0小时，0分钟，2秒）。如果您不指定&lt;strong&gt;BeginTime&lt;/strong&gt;，这个属性的值将默认为0秒。 
&lt;li class="WpfeQS"&gt;&lt;strong&gt;Duration&lt;/strong&gt;：Timeline执行一次所需的时间长度。对于一个动画来说，这表示它从起始值进行到结束值所用的时间长度。&lt;strong&gt;Duration&lt;/strong&gt;属性使用与&lt;strong&gt;BeginTime&lt;/strong&gt;相同的语法。再强调一下，请注意不要在您想表示&amp;#8220;秒&amp;#8221;的时候却设成了&amp;#8220;小时&amp;#8221;！&lt;strong&gt;Duration&lt;/strong&gt;能够被设为两个特殊的值：&amp;#8220;Forever&amp;#8221;和&amp;#8220;Automatic&amp;#8221;。该属性的默认值为&amp;#8220;Automatic&amp;#8221;。如果您想了解有关这两个特殊值的详细信息，请参考WPF/E SDK中的&lt;strong&gt;Duration&lt;/strong&gt;相关章节。 
&lt;li class="WpfeQS"&gt;&lt;strong&gt;FillBehavior&lt;/strong&gt;：指定了Timeline会停止之后会做什么。这个属性可以使用两个值：Stop或HoldEnd。&amp;#8220;Stop&amp;#8221;会再Timeline结束时将被操作的属性设为它的起始值；&amp;#8220;HoldEnd&amp;#8221;说明被操作的属性将再结束时保持最后的值不变。该属性默认值为&amp;#8220;HoldEnd&amp;#8221;。 
&lt;li class="WpfeQS"&gt;&lt;strong&gt;RepeatBehavior&lt;/strong&gt;：说明Timeline在重复的次数。这个属性能够被设为三种类型的值：重复次数，一个时间段，以及一个特殊值&amp;#8220;Forever&amp;#8221;。 
&lt;ul&gt;
&lt;li class="WpfeQS"&gt;&amp;#8220;Forever&amp;#8221;使Timeline不断地重复。 
&lt;li class="WpfeQS"&gt;一个时间段表示Timeline运行的时间长度。例如，将一个&lt;strong&gt;Duration&lt;/strong&gt;为2.5秒的动画的&lt;strong&gt;RepeatBehavior&lt;/strong&gt;设为&amp;#8220;0:0:5&amp;#8221;会使动画重复两次。 
&lt;li class="WpfeQS"&gt;重复次数指定了Timeline运行的次数。您使用下面的语法来指定重复次数：&lt;em&gt;重复次数&lt;/em&gt;&lt;strong&gt;x&lt;/strong&gt;。例如，&amp;#8220;4x&amp;#8221;表示Timeline重复四次。&lt;/li&gt;&lt;/ul&gt;该属性默认值为&amp;#8220;1x&amp;#8221;，表示时间线只会执行一次。&lt;/li&gt;&lt;/ul&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;下面的例子展示了这些Timeline的属性。&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Storyboard&lt;/span&gt; 
    &lt;span style="color: #ff0000"&gt;Storyboard&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;TargetName&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"e1"&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;Storyboard&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;TargetProperty&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"(Canvas.Left)"&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;BeginTime&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"0:0:1"&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;DoubleAnimation&lt;/span&gt; &lt;span style="color: #ff0000"&gt;To&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"300"&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;DoubleAnimation&lt;/span&gt; &lt;span style="color: #ff0000"&gt;To&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"300"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Storyboard&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;TargetName&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"e2"&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;DoubleAnimation&lt;/span&gt; &lt;span style="color: #ff0000"&gt;To&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"80"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Storyboard&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;TargetName&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"e3"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;Storyboard&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;TargetProperty&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Width"&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;DoubleAnimation&lt;/span&gt; &lt;span style="color: #ff0000"&gt;From&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"200"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;To&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"300"&lt;/span&gt; 
        &lt;span style="color: #ff0000"&gt;Storyboard&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;TargetName&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"e4"&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;DoubleAnimation&lt;/span&gt; &lt;span style="color: #ff0000"&gt;To&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"300"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Duration&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"0:0:5.3"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;Storyboard&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;TargetName&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"e5"&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;DoubleAnimation&lt;/span&gt; &lt;span style="color: #ff0000"&gt;FillBehavior&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"HoldEnd"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;To&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"200"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;Storyboard&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;TargetName&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"e6"&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;DoubleAnimation&lt;/span&gt; &lt;span style="color: #ff0000"&gt;FillBehavior&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Stop"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;To&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"200"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;Storyboard&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;TargetName&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"e7"&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;DoubleAnimation&lt;/span&gt; &lt;span style="color: #ff0000"&gt;RepeatBehavior&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Forever"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;To&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"300"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;Storyboard&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;TargetName&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"e8"&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;Storyboard&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;div class="agHost" id="agHost4"&gt;&lt;/div&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;a class="agButton" href="javascript:start('agHost4', 'agButton4', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/animation-timelines.html');"&gt;重新开始&lt;/a&gt;&lt;a class="agButton" id="agButton4" href="javascript:turn('agHost4', 'agButton4', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/animation-timelines.html');"&gt;查看内容&lt;/a&gt;&lt;/p&gt;
&lt;script language="javascript"&gt;
start('agHost4', 'agButton4', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/animation-timelines.html');
&lt;/script&gt;

&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;&lt;a name="multipleanimations"&gt;&lt;/a&gt;
&lt;p style="font-size: 14pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;指定动画变换的值&lt;/strong&gt;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;strong&gt;DoubleAnimation&lt;/strong&gt;，&lt;strong&gt;ColorAnimation&lt;/strong&gt;和&lt;strong&gt;PointAnimation&lt;/strong&gt;都有&lt;strong&gt;From&lt;/strong&gt;和&lt;strong&gt;To&lt;/strong&gt;两个属性，用于指定被操作属性的起始值和结束值。如果没有制动&lt;strong&gt;From&lt;/strong&gt;属性的值，起始值则为被操作属性的当前值。此外您可以使用&lt;strong&gt;By&lt;/strong&gt;属性来设定偏移量的大小，而不是使用&lt;strong&gt;To&lt;/strong&gt;属性来设置属性的结束值。&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;&lt;a name="fromtobyanimations"&gt;&lt;/a&gt;
&lt;p style="font-size: 14pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;在同一个对象上添加多个动画&lt;/strong&gt;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;您可以使用多个动画操作同一个对象的同一个属性。如果您想让让动画依次执行，那么可以将动画的&lt;strong&gt;BeginTime&lt;/strong&gt;和&lt;strong&gt;Duration&lt;/strong&gt;设为合适的值。下面的示例将两个动画应用到了同一个属性上，第二个动画将在第一个动画结束以后开始。&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Storyboard&lt;/span&gt; 
    &lt;span style="color: #ff0000"&gt;Storyboard&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;TargetName&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"e1"&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;Storyboard&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;TargetProperty&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"(Canvas.Left)"&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;DoubleAnimation&lt;/span&gt; &lt;span style="color: #ff0000"&gt;BeginTime&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"0"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Duration&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"0:0:2"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;To&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"250"&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;DoubleAnimation&lt;/span&gt; &lt;span style="color: #ff0000"&gt;BeginTime&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"0:0:2"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Duration&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"0:0:2"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;To&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"20"&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;Storyboard&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;div class="agHost" id="agHost5"&gt;&lt;/div&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;a class="agButton" href="javascript:start('agHost5', 'agButton5', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/animation-multiple.html');"&gt;重新开始&lt;/a&gt;&lt;a class="agButton" id="agButton5" href="javascript:turn('agHost5', 'agButton5', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/animation-multiple.html');"&gt;查看内容&lt;/a&gt;&lt;/p&gt;
&lt;script language="javascript"&gt;
start('agHost5', 'agButton5', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/animation-multiple.html');
&lt;/script&gt;

&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;&lt;a name="whatsnext"&gt;&lt;/a&gt;
&lt;p style="font-size: 14pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;下面该做什么呢？&lt;/strong&gt;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;在下一部分&amp;#8220;&lt;a href="http://blog.zhaojie.me/2006/12/wpfe-ctp-quick-start-part-8.html" target="_blank"&gt;脚本和鼠标事件&lt;/a&gt;&amp;#8221;中，您会了解如何使用JavaScript代码来添加交互内容。&lt;/p&gt;</description>
      <comments>http://blog.zhaojie.me/2006/12/wpfe-ctp-quick-start-part-9.html#comments</comments>
      <pubDate>Thu, 14 Dec 2006 14:49:00 GMT</pubDate>
      <lastBuildDate>Thu, 14 Dec 2006 14:49:00 GMT</lastBuildDate>
    </item>
    <item>
      <author>jeffz@live.com (老赵)</author>
      <category domain="http://blog.zhaojie.me/speech/">培训演讲</category>
      <category domain="http://blog.zhaojie.me/translation/">翻译引进</category>
      <category domain="http://blog.zhaojie.me/practice/">实践优化</category>
      <category domain="http://blog.zhaojie.me/asp-net/">ASP.NET</category>
      <category domain="http://blog.zhaojie.me/front-end/">前端表现</category>
      <title>讲座展示：TechEd Europe DEV 411 - AJAX Patterns with ASP.NET AJAX（3）</title>
      <link>http://blog.zhaojie.me/2006/12/lecture--teched-europe-dev411-3.html</link>
      <guid>http://blog.zhaojie.me/2006/12/lecture--teched-europe-dev411-3.html</guid>
      <description>&lt;p&gt;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;这次我选择的讲座内容，是最近在TechEd 2006 Europe中Andre Snanbria和Jeff Prosise的讲座&amp;#8220;AJAX Pattern with ASP.NET AJAX&amp;#8221;。Jeff Prosise是Wintellect的Co-Founder，Andre Sanabria是ASP.NET AJAX Team的Lead Program Manager。在MSDN's Showtime上已经有了&lt;a href="http://www.microsoft.com/emea/msdnshowtime/sessionh.aspx?videoid=331" target="_blank"&gt;这个讲座的完整视频&lt;/a&gt;，而我在早些时候给Andre Sanabria写了封Email，一星期后他给我寄来了这个讲座的PPT和Demo，大家可以&lt;a href="http://files.cnblogs.com/JeffreyZhao/TechEd_DEV411.zip" target="_blank"&gt;点击这里&lt;/a&gt;下载。&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;这次讲座的主要内容是讲述了使用ASP.NET AJAX开发AJAX应用的最佳实践，在这次讲座里，会对建立轻量级的客户端控件的方法进行深入，讲述了如何优化脚本代码，并提出了如何避免AJAX开发中常见的问题。&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;本篇文章是这次讲座展示的第三篇，使用了一个例子来观察UpdatePanel的工作方式，并通过几个步骤对这个例子进行优化。&lt;/p&gt; &lt;p style="font-size: 14pt; font-family: verdana"&gt;&lt;strong&gt;讲座内容&lt;/strong&gt;&lt;/p&gt; &lt;table cellspacing="5"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt;&lt;a href="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV411AJAXPatternsw.NETAJAX3_13EC/DEV411_15%5B2%5D.jpg" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="180" src="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV411AJAXPatternsw.NETAJAX3_13EC/DEV411_15_thumb.jpg" width="200" border="0"&gt;&lt;/a&gt; &lt;/td&gt; &lt;td&gt;&lt;a href="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV411AJAXPatternsw.NETAJAX3_13EC/DEV411_16%5B2%5D.jpg" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="180" src="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV411AJAXPatternsw.NETAJAX3_13EC/DEV411_16_thumb.jpg" width="200" border="0"&gt;&lt;/a&gt; &lt;/td&gt; &lt;td&gt;&lt;a href="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV和411AJAXPatternsw.NETAJAX3_13EC/DEV411_17%5B2%5D.jpg" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="180" src="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV411AJAXPatternsw.NETAJAX3_13EC/DEV411_17_thumb.jpg" width="200" border="0"&gt;&lt;/a&gt; &lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;strong&gt;Andre：&lt;/strong&gt;我先从展示没有UpdatePanel时的体验开始（~/Optimization/0.SimpleForm.aspx）。这是个简单的页面（上图左，请注意Back按钮无法使用），我们有几个相册供用户选择，然后我们将为它们添加Tag。现在我们没有使用UpdatePanel，当选择了某一项时，您会发现发生了一个完整的页面刷新（上图中，我把Back按钮可以使用了）。因为现在在我的本地机器上演示，因此这个刷新非常迅速。但是在互联网上就不会像本地那么快了，带宽会非常小。您可以发现，当我点击页面上每个单选按钮后，页面都会有完整的刷新（上图右，Back按钮的列表多了几项）。&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;strong&gt;Andre：&lt;/strong&gt;我们现在来看一下该如何解决这个问题。我们解决这个问题的方法只是将UpdatePanel添加到页面上。正如Jeff刚才提到的那样，我们在刚才的应用里使用了许多UpdatePanel。现在这个也是展示UpdatePanel的不错的例子（~/Optimization/1.PartialRendering.aspx）。&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;strong&gt;Andre：&lt;/strong&gt;我们首先先使用UpdatePanel包含一个服务器端的控件&amp;#8220;Panel&amp;#8221;（如下）：&lt;/p&gt; &lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="color: #800000"&gt;UpdatePanel&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;ID&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"contentUpdatePanel"&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;ContentTemplate&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: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="color: #800000"&gt;Panel&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;ID&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"contentPanel"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;style&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"padding: 10px"&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;ContentTemplate&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;Triggers&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: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="color: #800000"&gt;AsyncPostBackTrigger&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ControlID&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"albumList"&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;Triggers&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: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="color: #800000"&gt;UpdatePanel&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt; 
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;strong&gt;Andre：&lt;/strong&gt;然后我们使用UpdatePanel将一些CheckBox控件包含起来，我们那些Tag都是CheckBox（如下）：&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="color: #800000"&gt;UpdatePanel&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;ID&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"tagsListUpdatePanel"&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;ContentTemplate&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: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="color: #800000"&gt;CheckBoxList&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;ID&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"tagsList"&lt;/span&gt;
            &lt;span style="color: #ff0000"&gt;AutoPostBack&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"TRUE"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Enabled&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"false"&lt;/span&gt;
            &lt;span style="color: #ff0000"&gt;RepeatColumns&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"3"&lt;/span&gt;
            &lt;span style="color: #ff0000"&gt;OnSelectedIndexChanged&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"OnTagsSelectedIndexChanged"&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: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="color: #800000"&gt;ListItem&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Nature&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="color: #800000"&gt;ListItem&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: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="color: #800000"&gt;ListItem&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Landscapes&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="color: #800000"&gt;ListItem&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: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="color: #800000"&gt;ListItem&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Cityscapes&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="color: #800000"&gt;ListItem&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: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="color: #800000"&gt;ListItem&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Conference Trips&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="color: #800000"&gt;ListItem&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: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="color: #800000"&gt;ListItem&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Microsoft&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="color: #800000"&gt;ListItem&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: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="color: #800000"&gt;CheckBoxList&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;ContentTemplate&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: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="color: #800000"&gt;UpdatePanel&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt; 
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;strong&gt;Andre：&lt;/strong&gt;我们这里还有一个UpdatePanel（如下）：&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="color: #800000"&gt;UpdatePanel&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;ID&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"tagsUpdatePanel"&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;ContentTemplate&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: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="color: #800000"&gt;Label&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;ID&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"tagsLabel"&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;ContentTemplate&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: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="color: #800000"&gt;UpdatePanel&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt; 
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;strong&gt;Andre：&lt;/strong&gt;我们先来看一下现在的用户体验（老赵：这里就省略了），再来观察数据在客户端和服务器端之间是如何交换的。&lt;/p&gt;
&lt;table cellspacing="5"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV411AJAXPatternsw.NETAJAX3_13EC/DEV411_18%5B2%5D.jpg" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="165" src="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV411AJAXPatternsw.NETAJAX3_13EC/DEV411_18_thumb.jpg" width="200" border="0"&gt;&lt;/a&gt; &lt;/td&gt;
&lt;td&gt;&lt;a href="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV411AJAXPatternsw.NETAJAX3_13EC/DEV411_19%5B2%5D.jpg" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="165" src="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV411AJAXPatternsw.NETAJAX3_13EC/DEV411_19_thumb.jpg" width="200" border="0"&gt;&lt;/a&gt; &lt;/td&gt;
&lt;td&gt;&lt;a href="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV411AJAXPatternsw.NETAJAX3_13EC/DEV411_20%5B2%5D.jpg" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="165" src="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV411AJAXPatternsw.NETAJAX3_13EC/DEV411_20_thumb.jpg" width="200" border="0"&gt;&lt;/a&gt; &lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;strong&gt;Andre：&lt;/strong&gt;我们先打开一个工具——&lt;a href="http://www.nikhilk.net/WebDevHelperHTTPTracingUpdates.aspx" target="_blank"&gt;Web Development Helper&lt;/a&gt;，然后打开Logging开关。当我们点击某个Tagging时，这个小工具记录了从我的浏览器发出的Request和Server回复的内容（上图左）。因此我们就可以清楚地看到当我们选中一个CheckBox时，一个新的Request就发送到服务器端了。那么我们现在就来仔细看一下到底在这里发生了什么（上图中）。&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;strong&gt;Andre：&lt;/strong&gt;首先，一个请求放送到当前的页面。然后我们可以发现一个新的Header被添加到了请求中，它的名称是&amp;#8220;x-microsoftajax&amp;#8221;，值为&amp;#8220;Delta=true&amp;#8221;。这表示客户端告诉服务器端，现在的是一个异步的请求，需要对页面上的部分内容进行刷新。如果看一下部分刷新的实现的话，可以发现我们会查找Header，如果有上面的信息，则表示我们必须进行特别的步骤了，就是Jeff刚才提到的那些步骤。当然，这只是第一步。&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;strong&gt;Andre：&lt;/strong&gt;第二步我想展示给大家看的则是到底发送了那些内容。大部分人没有意识到的是，当UpdatePanel在工作时，整张页面被发送到了服务器端。就像Jeff说过，我们会将我们需要的所有信息，例如ViewState发送到服务器端。我们来看一下发送的内容（上图右）。发送了ScriptManager，ViewState内容等等，这是所有被发送到服务器端的内容。&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;a href="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV411AJAXPatternsw.NETAJAX3_13EC/DEV411_21%5B1%5D.jpg" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="198" src="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV411AJAXPatternsw.NETAJAX3_13EC/DEV411_21.jpg" width="240" border="0"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;strong&gt;Andre：&lt;/strong&gt;现在还有一个问题，服务器端到底返回了什么。我们可以从&amp;#8220;Response Content&amp;#8221;看到（上图）。这里有UpdatePanel的ID，我们也可以猜到，它返回了UpdatePanel里所有的HTML内容，在这里是个DIV，这就是我们会用来替换的内容。然后还有第二个UpdatePanel和第三个UpdatePanel。然后我们会将所有的ViewState发送到客户端。就像Jeff说过的，我们需要在Roundtrip时需要包含ViewState的原因是为了传输我们在客户端作了什么改变，在服务器端又作了什么改变。我们需要使用最新的数据来重建整个控件树，这就是我们需要ViewState数据的原因。&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;a href="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV411AJAXPatternsw.NETAJAX3_13EC/DEV411_22%5B1%5D.jpg" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="198" src="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV411AJAXPatternsw.NETAJAX3_13EC/DEV411_22.jpg" width="240" border="0"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;strong&gt;Andre：&lt;/strong&gt;下面就是Jeff提到过的一个最佳实践。我打开这个工具的目的是要让大家知道，每次我们点击CheckBox的时候发生了什么（上图）。每次我们点击CheckBox时，我们就会去服务器端请求数据，然后将页面进行刷新。我们该如何解决这个问题？这个问题其实有个比较容易的解决方法。（Andre不小心关闭了Visual Studio）呃&amp;#8230;&amp;#8230;这个解决方案并不是关闭Visual Studio，我们再来重新看一下（~/Optimization/2.OptimizeFrequency.aspx），我们在这里把CheckBoxList的AutoPostBack属性设为False（如下）：&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="color: #800000"&gt;CheckBoxList&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;ID&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"tagsList"&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;AutoPostBack&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"false"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Enabled&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"false"&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;RepeatColumns&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"3"&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: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="color: #800000"&gt;ListItem&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Nature&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="color: #800000"&gt;ListItem&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: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="color: #800000"&gt;ListItem&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Landscapes&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="color: #800000"&gt;ListItem&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: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="color: #800000"&gt;ListItem&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Cityscapes&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="color: #800000"&gt;ListItem&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: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="color: #800000"&gt;ListItem&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Conference Trips&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="color: #800000"&gt;ListItem&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: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="color: #800000"&gt;ListItem&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Microsoft&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="color: #800000"&gt;ListItem&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: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="color: #800000"&gt;CheckBoxList&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt; 
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;strong&gt;Andre：&lt;/strong&gt;这里的想法就是，我们不让每次CheckBox被选中或取消时就发送一次请求，我们只在我们准备好的情况下发送数据。我们再看一下页面（老赵：这里的截图就省略了），当我们选中一个像册时会发送一个请求。每次但我们点击CheckBox时，我们不会给服务器端发送数据。不过当我们点击Update按钮时，一个请求就出现了。这里的关键就在于，即使我们能够很快地与服务器端交互，我们也要仔细考虑一下，我们是否真的必要把AutoPoskBack打开，让控件自动地与服务器端交互，因为这意味着页面上所有的数据将向服务器端进行一个来回。&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;a href="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV411AJAXPatternsw.NETAJAX3_13EC/DEV411_23%5B1%5D.jpg" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="185" src="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV411AJAXPatternsw.NETAJAX3_13EC/DEV411_23.jpg" width="240" border="0"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;strong&gt;Andre：&lt;/strong&gt;这里还有一些比较有趣的事情，我想展示一下刚才发生了什么。我们依旧回到刚才的&amp;#8220;Response Content&amp;#8221;，这就是从服务器端发回的内容，但是我们在这里使用&amp;#8220;Partial Rendering&amp;#8221;视图（上图）。这里发生的事情是，有个UpdatePanel被更新了，在每次请求之后，我们会更新所有的3个UpdatePanel，我们在这里使用UpdatePanel的默认设置，UpdateMode为Always。这样，无论向服务器端请求的内容是什么，所有的UpdatePanel都会同时进行刷新。这里的问题就在于，我们可能不需要重新生成所有的UpdatePanel，我们需要的是简单地选择几个需要更新的UpdatePanel。这里就使用到UpdatePanel的一个属性，就是&amp;#8220;Conditional Rendering&amp;#8221;——噢，对不起，是&amp;#8220;UpdateMode&amp;#8221;。让我来告诉您我到底在说什么（~/Optimization/3.OptimizeBandwidth.aspx）。&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;strong&gt;Andre：&lt;/strong&gt;在这里我将UpdatePanel的UpdateMode属性设为了&amp;#8220;Conditional&amp;#8221;（老赵：这部分代码就不粘贴了）。现在的状况就变成了，UpdatePanel不必在每次请求时都进行更新，而是只有在特定情况下才重新生成它的内容。这些情况可能是我们通过UpdatePanel内部的控件进行了更新或者调用UpdatePanel的Update方法。第二种情况则是通过了UpdatePanel的Trigger，当一个控件被作为UpdatePanel的Trigger时，则表示当这个控件发起PostBack之后，UpdatePanel将被更新。&lt;/p&gt;
&lt;table cellspacing="5"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV411AJAXPatternsw.NETAJAX3_13EC/DEV411_24%5B1%5D.jpg" atomicselection="true"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="206" src="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV411AJAXPatternsw.NETAJAX3_13EC/DEV411_24.jpg" width="240" border="0"&gt;&lt;/a&gt; &lt;/td&gt;
&lt;td&gt;&lt;a href="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV411AJAXPatternsw.NETAJAX3_13EC/DEV411_25%5B1%5D.jpg" atomicselection="true"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="206" src="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV411AJAXPatternsw.NETAJAX3_13EC/DEV411_25.jpg" width="240" border="0"&gt;&lt;/a&gt; &lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;strong&gt;Andre：&lt;/strong&gt;我们再来看一下，当我们点击Update按钮之后，可以发现Reponse的内容变得多小（上图左），当我们查看更新的UpdatePanel时，可以发现现在只有一个UpdatePanel被更新了（上图右）！从我们的最佳实践方面来说，我们不仅从数据传输着手，也考虑到了页面加载方面的问题。我们在这里将UpdatePanel的默认设置改成了条件生成（Conditional Rendering）。&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;（未完待续）&lt;/p&gt;</description>
      <comments>http://blog.zhaojie.me/2006/12/lecture--teched-europe-dev411-3.html#comments</comments>
      <pubDate>Tue, 12 Dec 2006 19:30:00 GMT</pubDate>
      <lastBuildDate>Tue, 12 Dec 2006 19:30:00 GMT</lastBuildDate>
    </item>
    <item>
      <author>jeffz@live.com (老赵)</author>
      <category domain="http://blog.zhaojie.me/front-end/">前端表现</category>
      <category domain="http://blog.zhaojie.me/translation/">翻译引进</category>
      <title>WPF/E CTP Quick Start - 第八部分：媒体（翻译）</title>
      <link>http://blog.zhaojie.me/2006/12/wpfe-ctp-quick-start-part-8.html</link>
      <guid>http://blog.zhaojie.me/2006/12/wpfe-ctp-quick-start-part-8.html</guid>
      <description>&lt;link href="http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/cnblogs/QuickStart.css" type="text/css" rel="stylesheet"&gt; &lt;script src="http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/cnblogs/QuickStart.js" type="text/javascript"&gt;&lt;/script&gt;  &lt;div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 5px; font-size: 10pt; padding-bottom: 5px; border-left: #cccccc 1px solid; padding-top: 5px; border-bottom: #cccccc 1px solid; font-family: verdana"&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;WPF/E提供了MediaElement对象，可以让您在页面中播放WMV（Windows Media Video）和WMA（Windows Media Audio）文件。&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;这篇文档包含了以下部分：&lt;/p&gt; &lt;ul&gt; &lt;li class="WpfeQS"&gt;&lt;a href="#addmedia"&gt;在页面中添加媒体信息&lt;/a&gt;  &lt;li class="WpfeQS"&gt;&lt;a href="#usefulprops"&gt;有用的MediaElement属性&lt;/a&gt;  &lt;li class="WpfeQS"&gt;&lt;a href="#interactive"&gt;交互式地控制媒体的播放&lt;/a&gt;&amp;nbsp;  &lt;li class="WpfeQS"&gt;&lt;a href="#whatsnext"&gt;下面该做什么呢？&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;&lt;a name="addmedia"&gt;&lt;/a&gt; &lt;p style="font-size: 14pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;在页面中添加媒体信息&lt;/strong&gt;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;如果需要在页面中添加媒体信息，您需要创建一个&lt;strong&gt;MediaElement&lt;/strong&gt;元素，并将它的&lt;strong&gt;Source&lt;/strong&gt;属性指向您的媒体文件。下面则是一个示例：&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Canvas&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"http://schemas.microsoft.com/client/2007"&lt;/span&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;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;MediaElement&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Source&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"xbox.wmv"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"300"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"300"&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;Canvas&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;div class="agHost" id="agHost0"&gt;&lt;/div&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;a class="agButton" href="javascript:start('agHost0', 'agButton0', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/media-simple.html');"&gt;重新开始&lt;/a&gt;&lt;a class="agButton" id="agButton0" href="javascript:turn('agHost0', 'agButton0', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/media-simple.html');"&gt;查看内容&lt;/a&gt;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;就像其它&lt;strong&gt;UIElement&lt;/strong&gt;对象一样，您可以在&lt;strong&gt;MediaElement&lt;/strong&gt;对象之上绘制图形。下面的示例将在上一个例子的基础上，将一个&lt;strong&gt;Ellipse&lt;/strong&gt;添加到&lt;strong&gt;MediaElement&lt;/strong&gt;元素之上。&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Canvas&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"300"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"300"&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"http://schemas.microsoft.com/client/2007"&lt;/span&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;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;MediaElement&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Source&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"xbox.wmv"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"300"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"300"&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;Ellipse&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"200"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"200"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Left&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"30"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"30"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;Stroke&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Black"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;StrokeThickness&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"10"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Fill&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"SlateBlue"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;Opacity&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"0.6"&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;Canvas&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;div class="agHost" id="agHost1"&gt;&lt;/div&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;a class="agButton" href="javascript:start('agHost1', 'agButton1', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/media-composition.html');"&gt;重新开始&lt;/a&gt;&lt;a class="agButton" id="agButton1" href="javascript:turn('agHost1', 'agButton1', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/media-composition.html');"&gt;查看内容&lt;/a&gt;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;&lt;a name="usefulprops"&gt;&lt;/a&gt;
&lt;p style="font-size: 14pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;有用的MediaElement属性&lt;/strong&gt;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;MediaElement对象除了它作为一个UIElement对象所具有的属性，例如Opacity和Clip之外，还有一些额外的属性。MediaElement提供了一些媒体专有的属性：&lt;/p&gt;
&lt;ul&gt;
&lt;li class="WpfeQS"&gt;&lt;strong&gt;Stretch&lt;/strong&gt;：指定了一个视频是如何缩放以填充&lt;strong&gt;MediaElement&lt;/strong&gt;元素的。它可能的值有None、Uniform、UniformToFill和Fill。它的默认值为Fill。请参考WPF/E的SDK中关于&lt;strong&gt;Stetch&lt;/strong&gt;属性的部分，以获得更多信息。 
&lt;li class="WpfeQS"&gt;&lt;strong&gt;IsMuted&lt;/strong&gt;：指定了&lt;strong&gt;MediaElement&lt;/strong&gt;是否静音，把它设为True就能使&lt;strong&gt;MediaElement&lt;/strong&gt;静音，它的默认值为False。 
&lt;li class="WpfeQS"&gt;&lt;strong&gt;Volume&lt;/strong&gt;：使用0到1之间的值指定&lt;strong&gt;MediaElement&lt;/strong&gt;的音量，1表示最响。它的默认值为0.5。&lt;/li&gt;&lt;/ul&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;请参考WPF/E的SDK以得到更多&lt;strong&gt;MediaElement&lt;/strong&gt;的属性信息。&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;&lt;a name="interactive"&gt;&lt;/a&gt;
&lt;p style="font-size: 14pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;交互式地控制媒体的播放&lt;/strong&gt;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;您可以使用&lt;strong&gt;play&lt;/strong&gt;、&lt;strong&gt;pause&lt;/strong&gt;和&lt;strong&gt;stop&lt;/strong&gt;等方法交互式地控制媒体的播放。下面的示例使用了&lt;strong&gt;play&lt;/strong&gt;、&lt;strong&gt;pause&lt;/strong&gt;和&lt;strong&gt;stop&lt;/strong&gt;方法来交互式地控制媒体的播放。&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Canvas&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"300"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"300"&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"http://schemas.microsoft.com/client/2007"&lt;/span&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;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;MediaElement&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;"media"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Source&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"xbox.wmv"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"300"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"300"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;

    &lt;span style="color: #008000"&gt;&amp;lt;!-- Stops media playback.--&amp;gt;&lt;/span&gt;        
    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Canvas&lt;/span&gt; &lt;span style="color: #ff0000"&gt;MouseLeftButtonDown&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"javascript:media_stop"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Left&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"20"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"260"&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;Rectangle&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Stroke&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Black"&lt;/span&gt; 
             &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"40"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"40"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;RadiusX&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"5"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;RadiusY&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;Rectangle.Fill&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;RadialGradientBrush&lt;/span&gt; &lt;span style="color: #ff0000"&gt;GradientOrigin&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"0.75,0.25"&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;GradientStop&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Color&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Orange"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Offset&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"0.0"&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;GradientStop&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Color&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Red"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Offset&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"1.0"&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;RadialGradientBrush&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;Rectangle.Fill&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;Rectangle&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: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Left&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"5"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"5"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;stop&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;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Canvas&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;

    &lt;span style="color: #008000"&gt;&amp;lt;!-- Pauses media playback. --&amp;gt;&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Canvas&lt;/span&gt; &lt;span style="color: #ff0000"&gt;MouseLeftButtonDown&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"javascript:media_pause"&lt;/span&gt; 
         &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Left&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"70"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"260"&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;Rectangle&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Stroke&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Black"&lt;/span&gt; 
             &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"40"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"50"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;RadiusX&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"5"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;RadiusY&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;Rectangle.Fill&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;RadialGradientBrush&lt;/span&gt; &lt;span style="color: #ff0000"&gt;GradientOrigin&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"0.75,0.25"&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;GradientStop&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Color&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Yellow"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Offset&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"0.0"&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;GradientStop&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Color&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Orange"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Offset&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"1.0"&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;RadialGradientBrush&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;Rectangle.Fill&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;Rectangle&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: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Left&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"5"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"5"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;pause&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;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Canvas&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;

    &lt;span style="color: #008000"&gt;&amp;lt;!-- Begins media playback. --&amp;gt;&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Canvas&lt;/span&gt; &lt;span style="color: #ff0000"&gt;MouseLeftButtonDown&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"javascript:media_begin"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Left&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"130"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"260"&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;Rectangle&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Stroke&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Black"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;RadiusX&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"5"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;RadiusY&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"5"&lt;/span&gt;
             &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"40"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"50"&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;Rectangle.Fill&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;RadialGradientBrush&lt;/span&gt; &lt;span style="color: #ff0000"&gt;GradientOrigin&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"0.75,0.25"&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;GradientStop&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Color&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"LimeGreen"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Offset&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"0.0"&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;GradientStop&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Color&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Green"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Offset&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"1.0"&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;RadialGradientBrush&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;Rectangle.Fill&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;Rectangle&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: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Left&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"5"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"5"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;play&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;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Canvas&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;Canvas&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;function&lt;/span&gt; media_stop(sender, args) {
    sender.findName("&lt;span style="color: #8b0000"&gt;media&lt;/span&gt;").&lt;span style="color: #0000ff"&gt;stop&lt;/span&gt;();
}

&lt;span style="color: #0000ff"&gt;function&lt;/span&gt; media_pause(sender, args) {
    sender.findName("&lt;span style="color: #8b0000"&gt;media&lt;/span&gt;").pause();
}

&lt;span style="color: #0000ff"&gt;function&lt;/span&gt; media_begin(sender, args) {
    sender.findName("&lt;span style="color: #8b0000"&gt;media&lt;/span&gt;").play();
}&lt;/pre&gt;
&lt;div class="agHost" id="agHost2"&gt;&lt;/div&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;a class="agButton" href="javascript:start('agHost2', 'agButton2', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/media-scripting.html');"&gt;重新开始&lt;/a&gt;&lt;a class="agButton" id="agButton2" href="javascript:turn('agHost2', 'agButton2', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/media-scripting.html');"&gt;查看内容&lt;/a&gt;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;&lt;a name="whatsnext"&gt;&lt;/a&gt;
&lt;p style="font-size: 14pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;下面该做什么呢？&lt;/strong&gt;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;在下一部分&amp;#8220;&lt;a href="http://blog.zhaojie.me/2006/12/wpfe-ctp-quick-start-part-9.html" target="_blank"&gt;动画&lt;/a&gt;&amp;#8221;中，您会了解如何使用标记来定义动画，以及&lt;strong&gt;EventTrigger&lt;/strong&gt;和&lt;strong&gt;Storyboard&lt;/strong&gt;对象的使用方式。&lt;/p&gt;</description>
      <comments>http://blog.zhaojie.me/2006/12/wpfe-ctp-quick-start-part-8.html#comments</comments>
      <pubDate>Mon, 11 Dec 2006 21:26:00 GMT</pubDate>
      <lastBuildDate>Mon, 11 Dec 2006 21:26:00 GMT</lastBuildDate>
    </item>
    <item>
      <author>jeffz@live.com (老赵)</author>
      <category domain="http://blog.zhaojie.me/front-end/">前端表现</category>
      <category domain="http://blog.zhaojie.me/translation/">翻译引进</category>
      <title>WPF/E CTP Quick Start - 第七部分：文本（翻译）</title>
      <link>http://blog.zhaojie.me/2006/12/wpfe-ctp-quick-start-part-7.html</link>
      <guid>http://blog.zhaojie.me/2006/12/wpfe-ctp-quick-start-part-7.html</guid>
      <description>&lt;link href="http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/cnblogs/QuickStart.css" type="text/css" rel="stylesheet"&gt; &lt;script src="http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/cnblogs/QuickStart.js" type="text/javascript"&gt;&lt;/script&gt;  &lt;div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 5px; font-size: 10pt; padding-bottom: 5px; border-left: #cccccc 1px solid; padding-top: 5px; border-bottom: #cccccc 1px solid; font-family: verdana"&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;strong&gt;TextBlock&lt;/strong&gt;元素能使您在WPF/E内容中添加文本。这篇文档描述了使用&lt;strong&gt;TextBlock&lt;/strong&gt;元素的方式。&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;这篇文档包含了以下部分：&lt;/p&gt; &lt;ul&gt; &lt;li class="WpfeQS"&gt;&lt;a href="#thetextblockelement"&gt;TextBlock元素&lt;/a&gt;&amp;nbsp;  &lt;li class="WpfeQS"&gt;&lt;a href="#commontextblockproperties"&gt;常用TextBlock属性&lt;/a&gt;&amp;nbsp;  &lt;li class="WpfeQS"&gt;&lt;a href="#therunelement"&gt;Run元素&lt;/a&gt;&amp;nbsp;  &lt;li class="WpfeQS"&gt;&lt;a href="#specifyingmultiplefonts"&gt;指定多种字体&lt;/a&gt;&amp;nbsp;  &lt;li class="WpfeQS"&gt;&lt;a href="#whatsnext"&gt;下面该做什么呢？&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;&lt;a name="thetextblockelement"&gt;&lt;/a&gt; &lt;p style="font-size: 14pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;TextBlock元素&lt;/strong&gt;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;如果您想为WPF/E控件添加文本的话，则需要创建一个&lt;strong&gt;TextBlock&lt;/strong&gt;元素，并把文本内容添加在&amp;lt;TextBlock&amp;gt;标签之间。下面的示例使用了一个&lt;strong&gt;TextBlock&lt;/strong&gt;用于显示一些文本。&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Canvas&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"http://schemas.microsoft.com/client/2007"&lt;/span&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;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;hello world!&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;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Canvas&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;div class="agHost" id="agHost0"&gt;&lt;/div&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;a class="agButton" href="javascript:start('agHost0', 'agButton0', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/text-simple.html');"&gt;重新开始&lt;/a&gt;&lt;a class="agButton" id="agButton0" href="javascript:turn('agHost0', 'agButton0', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/text-simple.html');"&gt;查看内容&lt;/a&gt;&lt;/p&gt;
&lt;script language="javascript"&gt;
start('agHost0', 'agButton0', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/text-simple.html');
&lt;/script&gt;

&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;&lt;a name="commontextblockproperties"&gt;&lt;/a&gt;
&lt;p style="font-size: 14pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;常用TextBlock属性&lt;/strong&gt;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;除了作为&lt;strong&gt;UIElement&lt;/strong&gt;所具有的属性，例如&lt;strong&gt;Clip&lt;/strong&gt;和&lt;strong&gt;Opacity&lt;/strong&gt;之外，&lt;strong&gt;TextBlock&lt;/strong&gt;元素还提供了更多的属性，包括以下几个：&lt;/p&gt;
&lt;ul&gt;
&lt;li class="WpfeQS"&gt;&lt;strong&gt;FontSize&lt;/strong&gt;：字体颜色，以&amp;#8220;points&amp;#8221;作为单位。 
&lt;li class="WpfeQS"&gt;&lt;strong&gt;FontStyle&lt;/strong&gt;：字体样式，可选项为Normal、Italic和Oblique。 
&lt;li class="WpfeQS"&gt;&lt;strong&gt;FontWeight&lt;/strong&gt;：字体分量。可选项为Thin、ExtraLight、Light、Normal、Medium、SemiBold、Bold、ExtraBold、Black和ExtraBlack。 
&lt;li class="WpfeQS"&gt;&lt;strong&gt;FontFamily&lt;/strong&gt;：字体的名称。 
&lt;li class="WpfeQS"&gt;&lt;strong&gt;Forground&lt;/strong&gt;：用于填充TextBlock内部的Brush。您可以使用实心颜色，渐变或者一幅图片来填充。您可以参考&amp;#8220;&lt;a href="http://blog.zhaojie.me/2006/12/wpfe-ctp-quick-start-part-4.html" target="_blank"&gt;绘图与填充&lt;/a&gt;&amp;#8221;以获得更多信息。&lt;/li&gt;&lt;/ul&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;下面的例子展示了这些属性的使用效果：&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Canvas&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"http://schemas.microsoft.com/client/2007"&lt;/span&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;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: #ff0000"&gt;FontSize&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"40"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;FontFamily&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Georgia"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;FontStyle&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Italic"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;FontWeight&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Bold"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"20"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Left&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"20"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;

        Hello world!

        &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;TextBlock.Foreground&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;LinearGradientBrush&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;GradientStop&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Color&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"SlateBlue"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Offset&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"0.0"&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;GradientStop&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Color&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Black"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Offset&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"1.0"&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;LinearGradientBrush&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.Foreground&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;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Canvas&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;div class="agHost" id="agHost1"&gt;&lt;/div&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;a class="agButton" href="javascript:start('agHost1', 'agButton1', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/text-properties.html');"&gt;重新开始&lt;/a&gt;&lt;a class="agButton" id="agButton1" href="javascript:turn('agHost1', 'agButton1', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/text-properties.html');"&gt;查看内容&lt;/a&gt;&lt;/p&gt;
&lt;script language="javascript"&gt;
start('agHost1', 'agButton1', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/text-properties.html');
&lt;/script&gt;

&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;&lt;a name="therunelement"&gt;&lt;/a&gt;
&lt;p style="font-size: 14pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;Run元素&lt;/strong&gt;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;您可以在同一个&lt;strong&gt;TextBlock&lt;/strong&gt;内使用&lt;strong&gt;Run&lt;/strong&gt;元素来混合多种字体。&lt;strong&gt;Run&lt;/strong&gt;具有和&lt;strong&gt;TextBlock&lt;/strong&gt;相同的字体属性，尽管它不能使用&lt;strong&gt;Canvas.Left&lt;/strong&gt;和&lt;strong&gt;Canvas.Top&lt;/strong&gt;属性来定位。下面的示例使用了一个&lt;strong&gt;Run&lt;/strong&gt;元素来改变&lt;strong&gt;TextBlock&lt;/strong&gt;内一部分文字的大小。&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Canvas&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"http://schemas.microsoft.com/client/2007"&lt;/span&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;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;
        Hello &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Run&lt;/span&gt; &lt;span style="color: #ff0000"&gt;FontSize&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"30"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;world&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Run&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;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Canvas&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;div class="agHost" id="agHost2"&gt;&lt;/div&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;a class="agButton" href="javascript:start('agHost2', 'agButton2', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/text-formatted.html');"&gt;重新开始&lt;/a&gt;&lt;a class="agButton" id="agButton2" href="javascript:turn('agHost2', 'agButton2', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/text-formatted.html');"&gt;查看内容&lt;/a&gt;&lt;/p&gt;
&lt;script language="javascript"&gt;
start('agHost2', 'agButton2', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/text-formatted.html');
&lt;/script&gt;

&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;&lt;a name="specifyingmultiplefonts"&gt;&lt;/a&gt;
&lt;p style="font-size: 14pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;指定多种字体&lt;/strong&gt;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;并不是每一台机器上都有所有的字体。&lt;strong&gt;FontFamily&lt;/strong&gt;属性支持使用多种字体，当第一种字体不存在时，将会应用之后的字体设置。而&amp;#8220;Portable User Interface&amp;#8221;字体在任何机器上都会得到支持。下面的例子展示了不同的&lt;strong&gt;FontFamily&lt;/strong&gt;设置：&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Canvas&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"http://schemas.microsoft.com/client/2007"&lt;/span&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;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: #ff0000"&gt;FontFamily&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Arial, Times New Roman"&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;FontSize&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"20"&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: #ff0000"&gt;FontFamily&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Times New Roman, Arial"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"40"&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;FontSize&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"20"&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: #ff0000"&gt;FontFamily&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Portable User Interface"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"80"&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;FontSize&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"20"&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;Canvas&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;div class="agHost" id="agHost3"&gt;&lt;/div&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;a class="agButton" href="javascript:start('agHost3', 'agButton3', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/text-fontFamilies.html');"&gt;重新开始&lt;/a&gt;&lt;a class="agButton" id="agButton3" href="javascript:turn('agHost3', 'agButton3', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/text-fontFamilies.html');"&gt;查看内容&lt;/a&gt;&lt;/p&gt;
&lt;script language="javascript"&gt;
start('agHost3', 'agButton3', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/text-fontFamilies.html');
&lt;/script&gt;

&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;&lt;a name="whatsnext"&gt;&lt;/a&gt;
&lt;p style="font-size: 14pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;下面该做什么呢？&lt;/strong&gt;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;在下一部分&amp;#8220;&lt;a href="http://blog.zhaojie.me/2006/12/wpfe-ctp-quick-start-part-8.html" target="_blank"&gt;媒体（音频和视频）&lt;/a&gt;&amp;#8221;中，您会了解&lt;strong&gt;MediaElement&lt;/strong&gt;对象的使用方式，您可以使用它来播放媒体文件。&lt;/p&gt;</description>
      <comments>http://blog.zhaojie.me/2006/12/wpfe-ctp-quick-start-part-7.html#comments</comments>
      <pubDate>Mon, 11 Dec 2006 16:51:00 GMT</pubDate>
      <lastBuildDate>Mon, 11 Dec 2006 16:51:00 GMT</lastBuildDate>
    </item>
    <item>
      <author>jeffz@live.com (老赵)</author>
      <category domain="http://blog.zhaojie.me/language/">语言编程</category>
      <category domain="http://blog.zhaojie.me/translation/">翻译引进</category>
      <title>The Problem with Programming（翻译）</title>
      <link>http://blog.zhaojie.me/2006/12/the-problem-with-programming.html</link>
      <guid>http://blog.zhaojie.me/2006/12/the-problem-with-programming.html</guid>
      <description>&lt;p style="FONT-SIZE: 12pt"&gt;&lt;strong&gt;前言：&lt;/strong&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;这是一次访谈。访谈的对象是大名鼎鼎的Bjarne Stroustrup，&amp;#8220;C++之父&amp;#8221;的称号注定他永远是大师。这次他在接受了Technology Review的采访，对于软件开发的目前状况谈了他的看法，指出了不少问题。那么这些问题是否真的如他所述？按照我个人的习惯，我始终把对于大师的&amp;#8220;尊敬&amp;#8221;和对于其言论的&amp;#8220;吸收&amp;#8221;相分离，我们不妨围绕着这次Bjarne Stroustrup的谈话内容，展开我们的讨论吧。&lt;/p&gt;
&lt;p style="FONT-SIZE: 12pt"&gt;&lt;strong&gt;原文链接：&lt;/strong&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;a title=http://www.technologyreview.com/InfoTech/17831 href="http://www.technologyreview.com/InfoTech/17831"&gt;http://www.technologyreview.com/InfoTech/17831&lt;/a&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE: 12pt"&gt;&lt;strong&gt;翻译：&lt;/strong&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;strong&gt;&lt;em&gt;　　Bjarne Stroustrup，C++编程语言的发明者，维护了他的珍宝，并且提出了大多数软件代码都存在的问题。&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;在上世纪80年代到90年代期间，&lt;a href="http://parasol.tamu.edu/people/bs/" target=_blank&gt;Bjarne Stroustrup&lt;/a&gt;设计并实现了C++，这一目前最为流行的面向对象编程语言。它的出现影响了之后其它不计其数的编程语言，包括Java。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;C++具有典型的计算机&amp;#8220;高级&amp;#8221;语言特性（保留了自然的&amp;#8220;人类&amp;#8221;语言特性），目前依旧有数百万的程序员在使用它。大量PC上的，以及如今互联网时代的系统和应用程序都由C++编写而成。虽然如此，这个语言也受到了不少争议，主要是因为它&amp;#8220;声名狼藉&amp;#8221;地难以学习与使用。另外，Stroustrup的设计也让程序员在使用C++时容易犯下非常严重的错误，虽然C++给了他们相当的自由。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;Stroustrup，曾在AT&amp;amp;T贝尔实验室担任研究员多年，如今在休斯敦附近的Texas A&amp;amp;M University的计算机科学与工程系担任教授。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;strong&gt;Technology Review&lt;/strong&gt;：为什么大多数软件都那么低劣？&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;strong&gt;Bjarne Stroustrup&lt;/strong&gt;：有些软件以任何标准来衡量都相当优秀，看看Mars Rovers，Google和Human Genome项目，多高的软件质量！五十年前，大多数人，尤其是大多数专家，会认为上面这些例子的每一个都是不可能完成的。我们科技文明的基础在于软件，所以如果软件低劣到了无以复加的地步，我们大多数人现在都应该已经死了。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;另一方面，看着现在&amp;#8220;平均水平&amp;#8221;的代码我都想哭了。程序结构低劣地骇人听闻，程序员明显没有仔细思考过它们的正确性，算法，数据结构或者可维护性。大多数人根本不读代码，他们只会看着IE浏览器发呆。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;我认为我们（就是指我们这些软件开发人员）真正的问题在于我们永远处于一种紧急状态，想尽一切办法来完成工作。我们在大多数情况下会进行反复的测试，使用了大量的&amp;#8220;暴力&amp;#8221;测试，这的确产生了&amp;#8220;微量&amp;#8221;的奇迹——不过这远远不够。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;软件开发人员越来越擅长于在不可靠部分基础上建造可靠的系统，这可是非常困难的技术。但是造成困难的原因是我们经常不知道我们究竟该如何做：我们仅仅是将一些&amp;#8220;相关&amp;#8221;的东西集中起来，最终得到了差强人意的系统。我个人更倾向于去了解一个系统什么时候会工作，以及它为什么会工作。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;strong&gt;TR&lt;/strong&gt;：那么该如何解决我们现在这种糟糕的状况？&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;strong&gt;BS&lt;/strong&gt;：理论上来说这很简单：更好的培训我们的开发人员，适用更加合适的设计方法，做出更有弹性的设计。奖励正确，稳固和安全的系统。惩罚糟糕的情况。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;不过实际上这是不可能的。人们会奖赏那些发布更快，更便宜，虽然充满Bug的软件的开发人员，因为现在人们喜欢更炫更酷的新玩意儿。他们不想遇到麻烦，他们不愿意学习一些和计算机进行交互的新方法，不喜欢将发布推迟，也不愿意为质量付额外的钱（除非很明显已经预先知道了——不过往往这种情况下还是不愿意）。只要用户的行为不真正得到改变，软件供应商也就不太可能改变。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;我们不可能把世界暂停二十年，让我们把从咖啡机到金融系统的每一样东西重新编写一遍。另一方面，想把混乱的状况理清楚已经是件代价昂贵，危险，而且沉闷的事情了。我们需要有重大的改进，而且只能按部就班地进行。它们必须从一些主要的部分入手，而且任何单独的改变都是不够的。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;有一个叫做&amp;#8220;学术烟窗&amp;#8221;的问题妨碍了这一点：太多人把某些方面当作是万能药了。更好的设计方法能够起作用，更好的规格说明技术能够起作用，更好的编程语言、更好的测试技术、更好的操作系统、更好的中间件、更好地理解应用程序域、更好地理解数据结构和算法等等，都能够起作用。例如，类型论、基于模型的开发和形式方法都能够毫无争议地在某些方面起到非常重要的作用。但是它们如果同时排斥其它的方法，每一个都会使一个大规模的项目失败。人们只能将他们知道和他们见过的东西运用到工作中去，否则他们还能怎么做呢？但是只存在极少数的人，他们的技术已经成熟到能够在需求和资源中找到平衡。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;strong&gt;TR&lt;/strong&gt;：C++的目的是让程序员能够更努力地工作，以写出更高效的代码。贝尔实验室在当时需要一种语言，它能够让一些聪明绝顶的人们用来编写代码，并将它们运行在不是非常快的电子交换系统（ESS - Electronic Switching System）上。现在已经出现了大量的软件开发人员，计算机也已经变得非常迅速了，这对于C++的瞄准点是不是有所损害呢？&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;strong&gt;BS&lt;/strong&gt;：C++并不仅仅是针对大型交换系统设计的，它面向了各种范围的应用程序。贝尔实验室是各种难以计数范围内的有趣项目的发源地，它使用了各种各样的计算机和操作系统。当然，贝尔实验室里程序员的&amp;#8220;平均水平&amp;#8221;比大多数人们概念中程序员的&amp;#8220;平均水平&amp;#8221;要高出许多，而且在那里比大部分其它的地方都更加重视软件的可靠性以及性能。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&amp;#8220;性能&amp;#8221;依旧是我感兴趣，并且大多数应用程序都还难以避免的问题：响应接口，打开和关闭应用程序。软件开发人员增加了一个又一个多余的软件抽象层次，结果大大限制了当代计算机硬件的高速运算能力。我们似乎已经遇到了硬件以线性方式提高速度的瓶颈，但是在很多情况下，我们能够从软件那里得到大量的提高。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;这意味着，C++的确成为了一个过于&amp;#8220;面向专家&amp;#8221;的语言——在培养一个普通程序员的正规教育水准已经没落的时候。但是，解决问题的办法不是以编程语言来妥协，而是应该使用各种各样的语言来培养更多的专家。有很多语言可供这些专家使用——C++是其中一个。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;strong&gt;TR&lt;/strong&gt;：请您回顾一下，在您设计C++时，有没有决定更倾向于运行时的性能而牺牲一些开发效率，安全性或软件的可靠性呢？&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;strong&gt;BS&lt;/strong&gt;：嗯，我想我没有做这个交换。我希望得到优雅而高效的代码，有时我的确做到了。这些（割裂性能和正确性，性能和开发时间的）二分法过于低劣了。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;一开始，我把C++作为一个系统程语言来设计的：我希望能够编写设备的驱动程序，嵌入式系统以及其它一些我需要直接操作硬件的程序。接下来，我希望C++能成为一个设计工具的优秀语言。这不仅需要一定的适应性和性能了，而且还要有优雅地表示接口的能力。在我看来，如果希望建造一个高端的东西，构造一个完整的应用程序，你需要先去购买，开发或者借来已经有合适抽象的类库。大多数情况下，当开发人员遇到了C++方面的问题，其真正原因是因为他们没有使用合适的类库——或者他们无法找到可用的类库。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;而其它的语言已经设法更直接地支持了开发高端的应用程序。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;这种做法的确有效，不过这种支持往往把一种语言变得特殊化。就我个人而言，我不会设计一个工具只能做那些我想做的东西——我的目标是使它变得能够适应更普通的情况。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;strong&gt;TR&lt;/strong&gt;：您对于下面的这个事实是怎么看的呢？C++既被许多开发人员指责和憎恨，与此同时却又被广泛使用？为什么它如此成功？&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;strong&gt;BS&lt;/strong&gt;：这个问题答案是：世界上有两种语言，一种是人人都抱怨的语言，另一种是没有人使用语言。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;在所有有用的系统中，使用可怕的语言编写出来的系统，比使用优雅的语言编写出来的系统要多——而且多得多。编程语言的目的是帮助人们开发好的系统，这个&amp;#8220;好&amp;#8221;会有很多种定义，我对它的简单定义是：正确，可维护并且足够迅速。从美学角度来说，一个语言首先必须考虑的是&amp;#8220;有用&amp;#8221;，它必须有能力让真实世界里的程序员拿来表示真实世界里的想法，并且足够简洁。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;C++能够成功的主要原因很简单，它能够满足它有限的设计目标：它能够非常直接并高效地表达各式各样的想法。C++设计的目的并非仅仅是让开发人员能够很好的作一件事情，或者避免人们做出被认为是&amp;#8220;错误&amp;#8221;的事情，我更关注的是它的普适性和性能。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;我能肯定，每个不喜欢C++语言的程序员都有其喜欢的语言。然而，我的一个朋友参加了一个会议，主持人让听众举手表决：一、有多少人不喜欢C++；二、有多少人使用C++写程序。第一类人的数量是第二类的两倍。一个人不喜欢他不熟悉的事物往往是被认作为偏见。同时，抱怨的人往往比支持者显得喧闹——通情达理的人会承认缺陷。我认为我所了解的C++的毛病比了解其它任何事情都要多，但是我知道如何避免它们并且知道如何使用C++的长处。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;另外，你自然不能期待被C++打败的语言的支持者们能够非常有礼貌的对待C++。软件开发并不以承认专家的地位为目标——当然我希望它最终能够这样。科学在这方面是不同的，当一个工具、技术或者理论获胜时，人们把它当作进步。在软件领域，竞争对手或者前辈的贡献并没有被广泛认可，赏识，甚至不能被理解。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;strong&gt;TR&lt;/strong&gt;：在&lt;em&gt;The Design and Evolution of C++&lt;/em&gt;中，您声称Kierkegaard影响了您的语言概念。这是在开玩笑吗？&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;strong&gt;BS&lt;/strong&gt;：的确可能显得有些自命不凡，不过我并没有开玩笑。如今关于软件开发的思考，很大部分是集中在组，团队和公司上的。经常发生的是：个人独特的天才或者技能都被完全淹没在所谓的公司&amp;#8220;文化&amp;#8221;中了。公司的实践，可能对有特殊能力或技术天赋的个人有完全的冲突。我认为这种对于技术人员的管理是一种摧残和浪费。Kierkegaard是一个&amp;#8220;个体主义&amp;#8221;的支持者，他强烈反对&amp;#8220;群众&amp;#8221;，并且对于其美学和伦理学方面行为的重要性有着一些非常严谨的讨论。我无法指着某个特别的语言特性说：&amp;#8220;看，这里受到了这个十九世纪哲学家的影响&amp;#8221;。尽管我不是特别喜欢Kierkegaard的宗教哲学，但是他是我的思想根源，让我不愿去除语言&amp;#8220;专家级别&amp;#8221;的特性，不愿废除可能被&amp;#8220;滥用&amp;#8221;的语言特性，不愿意把它限制为只是&amp;#8220;我认为有用&amp;#8221;的那种语言。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;strong&gt;TR&lt;/strong&gt;：您最后悔的是什么？&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;strong&gt;BS&lt;/strong&gt;：没有后悔！嗯，当然我想过我可能可以做的不同，而且更好。但是说真的，那时候的我是谁？1984年的Bjarne？他可能没有我现在那么有经验，但是他不会比我笨，甚至比我现在还要聪明，他对于1984年事物比我现在有着更好的理解。C++已经创造了那么多的系统，改善了我们的生活，它显著地影响了之后的语言以及系统。这些事情绝对值得骄傲。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;em&gt;　　（点击&lt;a href="http://www.technologyreview.com/InfoTech/17868/" target=_blank&gt;这里&lt;/a&gt;查看我们与Stroustrup访谈的第二部分）&lt;/em&gt;&lt;/p&gt;</description>
      <comments>http://blog.zhaojie.me/2006/12/the-problem-with-programming.html#comments</comments>
      <pubDate>Mon, 11 Dec 2006 11:21:00 GMT</pubDate>
      <lastBuildDate>Mon, 11 Dec 2006 11:21:00 GMT</lastBuildDate>
    </item>
    <item>
      <author>jeffz@live.com (老赵)</author>
      <category domain="http://blog.zhaojie.me/front-end/">前端表现</category>
      <category domain="http://blog.zhaojie.me/translation/">翻译引进</category>
      <title>WPF/E CTP Quick Start - 第六部分：图像（翻译）</title>
      <link>http://blog.zhaojie.me/2006/12/wpfe-ctp-quick-start-part-6.html</link>
      <guid>http://blog.zhaojie.me/2006/12/wpfe-ctp-quick-start-part-6.html</guid>
      <description>&lt;link href="http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/cnblogs/QuickStart.css" type="text/css" rel="stylesheet"&gt; &lt;script src="http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/cnblogs/QuickStart.js" type="text/javascript"&gt;&lt;/script&gt;  &lt;div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 5px; font-size: 10pt; padding-bottom: 5px; border-left: #cccccc 1px solid; padding-top: 5px; border-bottom: #cccccc 1px solid; font-family: verdana"&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;strong&gt;Image&lt;/strong&gt;元素能使您在WPF/E中显示位图信息。&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;这篇文档包含了以下部分：&lt;/p&gt; &lt;ul&gt; &lt;li class="WpfeQS"&gt;&lt;a href="#imageelement"&gt;Image元素&lt;/a&gt;  &lt;li class="WpfeQS"&gt;&lt;a href="#stretchproperty"&gt;Stretch属性&lt;/a&gt;  &lt;li class="WpfeQS"&gt;&lt;a href="#otherways"&gt;使用位图的其它方法&lt;/a&gt;  &lt;li class="WpfeQS"&gt;&lt;a href="#whatsnext"&gt;下面该做什么呢？&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;&lt;a name="imageelement"&gt;&lt;/a&gt; &lt;p style="font-size: 14pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;Image元素&lt;/strong&gt;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;strong&gt;Image&lt;/strong&gt;元素为您提供了一个简单的方法在WPF/E中显示JPG和PNG格式的图像。为了显示一副图像，您需要将&lt;strong&gt;Image&lt;/strong&gt;对象的&lt;strong&gt;Source&lt;/strong&gt;属性设置为图像文件。下面的例子使用了一个&lt;strong&gt;Image&lt;/strong&gt;元素来显示一幅141x131的位图图像。因为没有指定&lt;strong&gt;Image&lt;/strong&gt;元素的&lt;strong&gt;Width&lt;/strong&gt;和&lt;strong&gt;Height&lt;/strong&gt;属性，这副图将以它的原始大小显示出来。&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Canvas&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"300"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"300"&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"http://schemas.microsoft.com/client/2007"&lt;/span&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;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;Image&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Source&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"star.png"&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;Canvas&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;div class="agHost" id="agHost0"&gt;&lt;/div&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;a class="agButton" href="javascript:start('agHost0', 'agButton0', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/image-simple.html');"&gt;重新开始&lt;/a&gt;&lt;a class="agButton" id="agButton0" href="javascript:turn('agHost0', 'agButton0', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/image-simple.html');"&gt;查看内容&lt;/a&gt;&lt;/p&gt;
&lt;script language="javascript"&gt;
start('agHost0', 'agButton0', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/image-simple.html');
&lt;/script&gt;

&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;&lt;a name="stretchproperty"&gt;&lt;/a&gt;
&lt;p style="font-size: 14pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;Stretch属性&lt;/strong&gt;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;当&lt;strong&gt;Image&lt;/strong&gt;元素的大小和位图信息的大小不同时，&lt;strong&gt;Stretch&lt;/strong&gt;属性会决定这幅位图会如何进行缩放，以配合&lt;strong&gt;Image&lt;/strong&gt;元素。&lt;strong&gt;Stretch&lt;/strong&gt;元素可以使用以下值：None、Fill、Uniform、UniformToFill。下面的示例分别展示了None、Uniform和Fill的效果。&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Canvas&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"300"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"300"&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"http://schemas.microsoft.com/client/2007"&lt;/span&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;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;Image&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Source&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"star.png"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Stretch&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"None"&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: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"200"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Left&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;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Image&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Source&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"star.png"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Stretch&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Fill"&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: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"200"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"100"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Left&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;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Image&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Source&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"star.png"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Stretch&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Uniform"&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: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"200"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"200"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Left&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;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;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Left&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"5"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"0"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;None&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;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;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Left&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"5"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"100"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Fill&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;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;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Left&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"5"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"200"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Uniform&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;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Canvas&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;div class="agHost" id="agHost1"&gt;&lt;/div&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;a class="agButton" href="javascript:start('agHost1', 'agButton1', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/image-stretch.html');"&gt;重新开始&lt;/a&gt;&lt;a class="agButton" id="agButton1" href="javascript:turn('agHost1', 'agButton1', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/image-stretch.html');"&gt;查看内容&lt;/a&gt;&lt;/p&gt;
&lt;script language="javascript"&gt;
start('agHost1', 'agButton1', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/image-stretch.html');
&lt;/script&gt;

&lt;p style="font-size: 10pt; font-family: verdana"&gt;您可以查看WPF/E SDK中有关&lt;strong&gt;Stretch&lt;/strong&gt;属性的内容，以得到有关图像伸缩设置的更多信息。&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;&lt;a name="otherways"&gt;&lt;/a&gt;
&lt;p style="font-size: 14pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;使用位图的其它方法&lt;/strong&gt;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;有关如何使用&lt;strong&gt;ImageBrush&lt;/strong&gt;对象将位图作为背景的更多内容，请查看&amp;#8220;&lt;a href="http://blog.zhaojie.me/2006/12/wpfe-ctp-quick-start-part-4.html" target="_blank"&gt;绘图与填充&lt;/a&gt;&amp;#8221;。&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;&lt;a name="whatsnext"&gt;&lt;/a&gt;
&lt;p style="font-size: 14pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;下面该做什么呢？&lt;/strong&gt;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;在下一部分&amp;#8220;&lt;a href="http://blog.zhaojie.me/2006/12/wpfe-ctp-quick-start-part-7.html" target="_blank"&gt;文本&lt;/a&gt;&amp;#8221;中，您会了解&lt;strong&gt;TextBlock&lt;/strong&gt;元素的使用方式，它使您能够为WPF/E内容添加文本。&lt;iframe style="DISPLAY: none; VISIBILITY: hidden" src="http://blog.zhaojie.me/2006/12/587624.html" width=0 height=0&gt;&lt;/iframe&gt;&lt;/p&gt;</description>
      <comments>http://blog.zhaojie.me/2006/12/wpfe-ctp-quick-start-part-6.html#comments</comments>
      <pubDate>Sun, 10 Dec 2006 15:11:00 GMT</pubDate>
      <lastBuildDate>Sun, 10 Dec 2006 15:11:00 GMT</lastBuildDate>
    </item>
    <item>
      <author>jeffz@live.com (老赵)</author>
      <category domain="http://blog.zhaojie.me/front-end/">前端表现</category>
      <category domain="http://blog.zhaojie.me/translation/">翻译引进</category>
      <title>WPF/E CTP Quick Start - 第五部分：公有图形属性（翻译）</title>
      <link>http://blog.zhaojie.me/2006/12/wpfe-ctp-quick-start-part-5.html</link>
      <guid>http://blog.zhaojie.me/2006/12/wpfe-ctp-quick-start-part-5.html</guid>
      <description>&lt;link href="http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/cnblogs/QuickStart.css" type="text/css" rel="stylesheet"&gt; &lt;script src="http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/cnblogs/QuickStart.js" type="text/javascript"&gt;&lt;/script&gt;  &lt;div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 5px; font-size: 10pt; padding-bottom: 5px; border-left: #cccccc 1px solid; padding-top: 5px; border-bottom: #cccccc 1px solid; font-family: verdana"&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;一些属性能够被应用在所有的WPF/E的&lt;strong&gt;UIElement&lt;/strong&gt;对象上：&lt;strong&gt;Canvas&lt;/strong&gt;，shapes和&lt;strong&gt;TextBlock&lt;/strong&gt;。这篇文档描述了这些对象所具有的公有图形属性。&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;这篇文档包含了以下部分：&lt;/p&gt; &lt;ul&gt; &lt;li class="WpfeQS"&gt;&lt;a href="#opacity"&gt;Opacity属性&lt;/a&gt;  &lt;li class="WpfeQS"&gt;&lt;a href="#opacitymask"&gt;OpacityMask属性&lt;/a&gt;  &lt;li class="WpfeQS"&gt;&lt;a href="#clipproperty"&gt;Clip属性&lt;/a&gt;  &lt;li class="WpfeQS"&gt;&lt;a href="#rendertransform"&gt;RenderTransform属性&lt;/a&gt;  &lt;li class="WpfeQS"&gt;&lt;a href="#whatsnext"&gt;下面该做什么呢？&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;&lt;a name="opacity"&gt;&lt;/a&gt; &lt;p style="font-size: 14pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;Opacity属性&lt;/strong&gt;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;strong&gt;Opacity&lt;/strong&gt;属性能够让您控制一个&lt;strong&gt;UIElement&lt;/strong&gt;对象的alpha值或者透明的程度。您可以为&lt;strong&gt;Opacity&lt;/strong&gt;设置一个0到1之间的数，该值越接近0.0，该对象就越接近完全透明，当&lt;strong&gt;Opacity&lt;/strong&gt;属性为0时，对象就完全不可见了。默认的&lt;strong&gt;Opactiy&lt;/strong&gt;属性的值为1.0，意味着对象完全不透明。下面的例子创建了两个不同透明程度的形状。&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Canvas&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"300"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"300"&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"http://schemas.microsoft.com/client/2007"&lt;/span&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;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;Rectangle&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Opacity&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"1.0"&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: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"100"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Left&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"30"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"30"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;Stroke&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Black"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;StrokeThickness&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"10"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Fill&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"SlateBlue"&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;Rectangle&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Opacity&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"0.6"&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: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"100"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Left&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"70"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"70"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;Stroke&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Black"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;StrokeThickness&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"10"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Fill&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"SlateBlue"&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;Canvas&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;div class="agHost" id="agHost0"&gt;&lt;/div&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;a class="agButton" href="javascript:start('agHost0', 'agButton0', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/visual-opacity.html');"&gt;重新开始&lt;/a&gt;&lt;a class="agButton" id="agButton0" href="javascript:turn('agHost0', 'agButton0', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/visual-opacity.html');"&gt;查看内容&lt;/a&gt;&lt;/p&gt;
&lt;script language="javascript"&gt;
start('agHost0', 'agButton0', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/visual-opacity.html');
&lt;/script&gt;

&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;&lt;a name="opacitymask"&gt;&lt;/a&gt;
&lt;p style="font-size: 14pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;OpacityMask属性&lt;/strong&gt;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;strong&gt;OpacityMask&lt;/strong&gt;属性能够让您控制一个&lt;strong&gt;UIElement&lt;/strong&gt;不同部分的alpha值。例如，您可以使用&lt;strong&gt;OpacityMask&lt;/strong&gt;使一个元素从右往左淡入或淡出。&lt;strong&gt;OpacityMask&lt;/strong&gt;属性具有一个&lt;strong&gt;Brush&lt;/strong&gt;对象，这个画刷将元素和画刷的每一个像素的alpha通道进行映射，以确定元素上对应像素的透明结果。如果画刷的某一部分是透明的，那么元素的那一部分会变得透明。&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;您可以为&lt;strong&gt;OpacityMask&lt;/strong&gt;使用不同类型的画刷，不过&lt;strong&gt;LinearGradientBrush&lt;/strong&gt;，&lt;strong&gt;RadialGradientBrush&lt;/strong&gt;和&lt;strong&gt;ImageBrush&lt;/strong&gt;最为常用。&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;下面的示例将一个应用了&lt;strong&gt;LinearGradientBrush&lt;/strong&gt;的opacity mask作用在一个&lt;strong&gt;Rectangle&lt;/strong&gt;对象上。&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Canvas&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"300"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"300"&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"http://schemas.microsoft.com/client/2007"&lt;/span&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;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;Rectangle&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: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"100"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Left&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"30"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"30"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;Stroke&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Black"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;StrokeThickness&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"10"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Fill&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"SlateBlue"&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;Rectangle.OpacityMask&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;LinearGradientBrush&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;GradientStop&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Offset&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"0.25"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Color&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"#00000000"&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;GradientStop&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Offset&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"1"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Color&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"#FF000000"&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;LinearGradientBrush&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;Rectangle.OpacityMask&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;Rectangle&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;Canvas&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;div class="agHost" id="agHost1"&gt;&lt;/div&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;a class="agButton" href="javascript:start('agHost1', 'agButton1', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/visual-opacityMask.html');"&gt;重新开始&lt;/a&gt;&lt;a class="agButton" id="agButton1" href="javascript:turn('agHost1', 'agButton1', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/visual-opacityMask.html');"&gt;查看内容&lt;/a&gt;&lt;/p&gt;
&lt;script language="javascript"&gt;
start('agHost1', 'agButton1', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/visual-opacityMask.html');
&lt;/script&gt;

&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;&lt;a name="clipproperty"&gt;&lt;/a&gt;
&lt;p style="font-size: 14pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;Clip属性&lt;/strong&gt;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;strong&gt;Clip&lt;/strong&gt;属性能够使您有选择则绘制元素的一部分。使用&lt;strong&gt;Clip&lt;/strong&gt;属性时，您需要提供一个&lt;strong&gt;Geometry&lt;/strong&gt;对象用于描述绘制区域，任何超过绘制区域的部分都会被隐藏，或者说是&amp;#8220;被修剪（clipped）&amp;#8221;了。&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;下面的示例使用了一个&lt;strong&gt;RectangleGeometry&lt;/strong&gt;作为&lt;strong&gt;Ellipse&lt;/strong&gt;元素的&lt;strong&gt;Clip&lt;/strong&gt;属性。其结果是：只有&lt;strong&gt;Ellipse&lt;/strong&gt;在&lt;strong&gt;RectangleGeometry&lt;/strong&gt;定义的区域内的部分才被显示出来，超出&lt;strong&gt;RectangleGeometry&lt;/strong&gt;的部分则被切除了。&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Canvas&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"300"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"300"&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"http://schemas.microsoft.com/client/2007"&lt;/span&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;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;Ellipse&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"200"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"200"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Left&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"30"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"30"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;Stroke&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Black"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;StrokeThickness&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"10"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Fill&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"SlateBlue"&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;Ellipse.Clip&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;RectangleGeometry&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Rect&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"0, 0, 100, 100"&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;Ellipse.Clip&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;Ellipse&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;Canvas&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;div class="agHost" id="agHost2"&gt;&lt;/div&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;a class="agButton" href="javascript:start('agHost2', 'agButton2', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/visual-clipping.html');"&gt;重新开始&lt;/a&gt;&lt;a class="agButton" id="agButton2" href="javascript:turn('agHost2', 'agButton2', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/visual-clipping.html');"&gt;查看内容&lt;/a&gt;&lt;/p&gt;
&lt;script language="javascript"&gt;
start('agHost2', 'agButton2', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/visual-clipping.html');
&lt;/script&gt;

&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;&lt;a name="rendertransform"&gt;&lt;/a&gt;
&lt;p style="font-size: 14pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;RenderTransform属性&lt;/strong&gt;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;strong&gt;RenderTransform&lt;/strong&gt;属性让您可以使用&lt;strong&gt;Transform&lt;/strong&gt;对象对一个元素进行旋转，倾斜，缩放或移动。下面的列表描述了您可以使用在&lt;strong&gt;RenderTransform&lt;/strong&gt;属性上的不同的&lt;strong&gt;Transform&lt;/strong&gt;对象&lt;/p&gt;
&lt;ul&gt;
&lt;li class="WpfeQS"&gt;&lt;strong&gt;RotateTransform&lt;/strong&gt;：将一个对象旋转特定的角度。 
&lt;li class="WpfeQS"&gt;&lt;a href="#opacitymask"&gt;&lt;/a&gt;&lt;strong&gt;SkewTransform&lt;/strong&gt;：将一个对象相对于X轴或Y轴进行倾斜 
&lt;li class="WpfeQS"&gt;&lt;a href="#clipproperty"&gt;&lt;/a&gt;&lt;strong&gt;ScaleTransform&lt;/strong&gt;：将一个对象在水平或垂直方向进行放大或缩小。 
&lt;li class="WpfeQS"&gt;&lt;a href="#rendertransform"&gt;&lt;/a&gt;&lt;strong&gt;TranslateTransform&lt;/strong&gt;：将一个对象在水平或垂直方向进行移动。&amp;nbsp;&lt;/li&gt;&lt;/ul&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;还有另外一种变换，&lt;strong&gt;TransformGroup&lt;/strong&gt;，您可以使用它将多种变换应用在单个对象上。&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;下面的示例将&lt;strong&gt;Transform&lt;/strong&gt;对象应用在&lt;strong&gt;Rectangle&lt;/strong&gt;元素上，展示了每个&lt;strong&gt;Transform&lt;/strong&gt;对象的不同效果。&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Canvas&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"300"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"300"&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"http://schemas.microsoft.com/client/2007"&lt;/span&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;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;Rectangle&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: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"100"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Left&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"70"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"10"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;Fill&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Black"&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;Rectangle.RenderTransform&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;RotateTransform&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Angle&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"45"&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;Rectangle.RenderTransform&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;Rectangle&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;Rectangle&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: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"100"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Left&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"130"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"10"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;Fill&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"red"&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;Rectangle.RenderTransform&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;SkewTransform&lt;/span&gt; &lt;span style="color: #ff0000"&gt;AngleX&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"30"&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;Rectangle.RenderTransform&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;Rectangle&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;Rectangle&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: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"100"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Left&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"10"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"190"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;Fill&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"blue"&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;Rectangle.RenderTransform&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;ScaleTransform&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ScaleX&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"1.3"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ScaleY&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;Rectangle.RenderTransform&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;Rectangle&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;Rectangle&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: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"100"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Left&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"160"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"130"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;Fill&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Green"&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;Rectangle.RenderTransform&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;TransformGroup&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;RotateTransform&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Angle&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"45"&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;ScaleTransform&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ScaleX&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;".5"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ScaleY&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"1.2"&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;SkewTransform&lt;/span&gt; &lt;span style="color: #ff0000"&gt;AngleX&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"30"&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;TransformGroup&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;Rectangle.RenderTransform&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;Rectangle&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;Canvas&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;div class="agHost" id="agHost3"&gt;&lt;/div&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;a class="agButton" href="javascript:start('agHost3', 'agButton3', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/visual-transforms.html');"&gt;重新开始&lt;/a&gt;&lt;a class="agButton" id="agButton3" href="javascript:turn('agHost3', 'agButton3', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/visual-transforms.html');"&gt;查看内容&lt;/a&gt;&lt;/p&gt;
&lt;script language="javascript"&gt;
start('agHost3', 'agButton3', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/visual-transforms.html');
&lt;/script&gt;

&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;&lt;a name="whatsnext"&gt;&lt;/a&gt;
&lt;p style="font-size: 14pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;下面该做什么呢？&lt;/strong&gt;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;在下一部分&amp;#8220;&lt;a href="http://blog.zhaojie.me/2006/12/wpfe-ctp-quick-start-part-6.html" target="_blank"&gt;图像&lt;/a&gt;&amp;#8221;中，您会了解&lt;strong&gt;Image&lt;/strong&gt;元素的使用方式，以及您应该如何显示位图。&lt;/p&gt;</description>
      <comments>http://blog.zhaojie.me/2006/12/wpfe-ctp-quick-start-part-5.html#comments</comments>
      <pubDate>Sun, 10 Dec 2006 06:50:00 GMT</pubDate>
      <lastBuildDate>Sun, 10 Dec 2006 06:50:00 GMT</lastBuildDate>
    </item>
    <item>
      <author>jeffz@live.com (老赵)</author>
      <category domain="http://blog.zhaojie.me/front-end/">前端表现</category>
      <category domain="http://blog.zhaojie.me/translation/">翻译引进</category>
      <title>WPF/E CTP Quick Start - 第四部分：绘图与填充（翻译）</title>
      <link>http://blog.zhaojie.me/2006/12/wpfe-ctp-quick-start-part-4.html</link>
      <guid>http://blog.zhaojie.me/2006/12/wpfe-ctp-quick-start-part-4.html</guid>
      <description>&lt;link href="http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/cnblogs/QuickStart.css" type="text/css" rel="stylesheet"&gt; &lt;script src="http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/cnblogs/QuickStart.js" type="text/javascript"&gt;&lt;/script&gt;  &lt;div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 5px; font-size: 10pt; padding-bottom: 5px; border-left: #cccccc 1px solid; padding-top: 5px; border-bottom: #cccccc 1px solid; font-family: verdana"&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;WPF/E通过提供&lt;strong&gt;Ellipse&lt;/strong&gt;，&lt;strong&gt;Rectangle&lt;/strong&gt;，&lt;strong&gt;Line&lt;/strong&gt;，&lt;strong&gt;Polyline&lt;/strong&gt;，&lt;strong&gt;Polygon&lt;/strong&gt;和&lt;strong&gt;Path&lt;/strong&gt;元素以支持矢量图。同样的，这些元素也被称之为&amp;#8220;形状（Shape）&amp;#8221;元素。&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;这片文档包含了以下部分&lt;/p&gt; &lt;ul&gt; &lt;li class="WpfeQS"&gt;&lt;a href="#basicshapes"&gt;基础形状&lt;/a&gt;  &lt;li class="WpfeQS"&gt;&lt;a href="#othershapeelements"&gt;其他形状元素&lt;/a&gt;  &lt;li class="WpfeQS"&gt;&lt;a href="#paintingshapewithbrushes"&gt;使用画刷填充形状&lt;/a&gt;  &lt;li class="WpfeQS"&gt;&lt;a href="#transformingshapes"&gt;形状变换&lt;/a&gt;  &lt;li class="WpfeQS"&gt;&lt;a href="#whatsnext"&gt;下面该做什么呢？&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;&lt;a name="basicshapes"&gt;&lt;/a&gt; &lt;p style="font-size: 14pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;基础元素&lt;/strong&gt;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;WPF/E提供了三种基本形状元素：&lt;strong&gt;Ellipse&lt;/strong&gt;，&lt;strong&gt;Rectangle&lt;/strong&gt;和&lt;strong&gt;Line&lt;/strong&gt;。&lt;/p&gt; &lt;ul&gt; &lt;li class="WpfeQS"&gt;&lt;strong&gt;Ellipse&lt;/strong&gt;元素用于描述一个椭圆或者圆形。您可以通过设置它的&lt;strong&gt;Width&lt;/strong&gt;和&lt;strong&gt;Height&lt;/strong&gt;属性来分别控制它水平方向和垂直方向的直径。  &lt;li class="WpfeQS"&gt;&lt;strong&gt;Rectangle&lt;/strong&gt;元素用于描述一个长方形或者正方形，圆角或直角。你能够通过设置它&lt;strong&gt;Width&lt;/strong&gt;和&lt;strong&gt;Height&lt;/strong&gt;属性来分别控制它水平和垂直方向上的距离。您也可以通过设置&lt;strong&gt;RadiusX&lt;/strong&gt;和&lt;strong&gt;RadiusY&lt;/strong&gt;属性来控制圆角的曲率。&amp;nbsp;  &lt;li class="WpfeQS"&gt;您可以使用&lt;strong&gt;X1&lt;/strong&gt;、&lt;strong&gt;Y1&lt;/strong&gt;、&lt;strong&gt;X2&lt;/strong&gt;、&lt;strong&gt;Y2&lt;/strong&gt;属性来控制&lt;strong&gt;Line&lt;/strong&gt;元素的尺寸和位置，而不是使用&lt;strong&gt;Width&lt;/strong&gt;和&lt;strong&gt;Height&lt;/strong&gt;属性。&lt;/li&gt;&lt;/ul&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;下面的示例在&lt;strong&gt;Canvas&lt;/strong&gt;中分别绘制了一个&lt;strong&gt;Ellipse&lt;/strong&gt;，一个&lt;strong&gt;Rectangle&lt;/strong&gt;和一个&lt;strong&gt;Line&lt;/strong&gt;元素。&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Canvas&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"http://schemas.microsoft.com/client/2007"&lt;/span&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;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;Ellipse&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"200"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"200"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Left&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"30"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"30"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;Stroke&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Black"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;StrokeThickness&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"10"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Fill&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"SlateBlue"&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;Rectangle&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: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"100"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Left&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"5"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"5"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;Stroke&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Black"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;StrokeThickness&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"10"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Fill&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"SlateBlue"&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;Line&lt;/span&gt; &lt;span style="color: #ff0000"&gt;X1&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"280"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Y1&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"10"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;X2&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"10"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Y2&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"280"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;Stroke&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"black"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;StrokeThickness&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;Canvas&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;div class="agHost" id="agHost0"&gt;&lt;/div&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;a class="agButton" href="javascript:start('agHost0', 'agButton0', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/drawing-ellipseRectangleLine.html');"&gt;重新开始&lt;/a&gt;&lt;a class="agButton" id="agButton0" href="javascript:turn('agHost0', 'agButton0', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/drawing-ellipseRectangleLine.html');"&gt;查看内容&lt;/a&gt;&lt;/p&gt;
&lt;script language="javascript"&gt;
start('agHost0', 'agButton0', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/drawing-ellipseRectangleLine.html');
&lt;/script&gt;

&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;&lt;a name="othershapeelements"&gt;&lt;/a&gt;
&lt;p style="font-size: 14pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;其它形状元素&lt;/strong&gt;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;除&lt;strong&gt;Ellipse&lt;/strong&gt;，&lt;strong&gt;Line&lt;/strong&gt;和&lt;strong&gt;Rectangle&lt;/strong&gt;元素以外，WPF/E还提供了另外三种形状元素：&lt;strong&gt;Polygon&lt;/strong&gt;，&lt;strong&gt;Polyline&lt;/strong&gt;和&lt;strong&gt;Path&lt;/strong&gt;。&lt;strong&gt;Polygon&lt;/strong&gt;是一个由几条边组成的封闭形状，而&lt;strong&gt;Polyline&lt;/strong&gt;是由一系列连接线组成，可能封闭也可能没有封闭的形状。下面的例子创建了一个&lt;strong&gt;Polygon&lt;/strong&gt;和一个&lt;strong&gt;Polyline&lt;/strong&gt;。&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Canvas&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"http://schemas.microsoft.com/client/2007"&lt;/span&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;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;Polyline&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Points&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"150, 150 150, 250 250, 250 250, 150"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;Stroke&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Black"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;StrokeThickness&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"10"&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;Polygon&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Points&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"10,10 10,110 110,110 110,10"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;Stroke&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Black"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;StrokeThickness&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"10"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Fill&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"LightBlue"&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;Canvas&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;div class="agHost" id="agHost1"&gt;&lt;/div&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;a class="agButton" href="javascript:start('agHost1', 'agButton1', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/drawing-Polyline-Polygon.html');"&gt;重新开始&lt;/a&gt;&lt;a class="agButton" id="agButton1" href="javascript:turn('agHost1', 'agButton1', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/drawing-Polyline-Polygon.html');"&gt;查看内容&lt;/a&gt;&lt;/p&gt;
&lt;script language="javascript"&gt;
start('agHost1', 'agButton1', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/drawing-Polyline-Polygon.html');
&lt;/script&gt;

&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;strong&gt;Path&lt;/strong&gt;元素能够用来表示一个复杂的形状，包括曲线和弧形。当您使用&lt;strong&gt;Path&lt;/strong&gt;元素时，您需要使用一些特殊的语法来指定它&lt;strong&gt;Data&lt;/strong&gt;属性的值。下面的例子创建了三个&lt;strong&gt;Path&lt;/strong&gt;元素。&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Canvas&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"http://schemas.microsoft.com/client/2007"&lt;/span&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;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;Path&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Data&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"M0,0 L11.5,0 11.5,30 5.75,40 0,30z"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;Stroke&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Black"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Fill&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"SlateBlue"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Left&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"10"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"10"&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;Path&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Data&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"M 10,100 C 10,300 300,-200 250,100z"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;Stroke&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Red"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Fill&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Orange"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Left&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"10"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"10"&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;Path&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Data&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"M 0,200 L100,200 50,50z"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;Stroke&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Black"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Fill&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Gray"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Left&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"150"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"70"&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;Canvas&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;div class="agHost" id="agHost2"&gt;&lt;/div&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;a class="agButton" href="javascript:start('agHost2', 'agButton2', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/drawing-Path.html');"&gt;重新开始&lt;/a&gt;&lt;a class="agButton" id="agButton2" href="javascript:turn('agHost2', 'agButton2', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/drawing-Path.html');"&gt;查看内容&lt;/a&gt;&lt;/p&gt;
&lt;script language="javascript"&gt;
start('agHost2', 'agButton2', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/drawing-Path.html');
&lt;/script&gt;

&lt;p style="font-size: 10pt; font-family: verdana"&gt;您可以查看WPF/E SDK中的&lt;em&gt;Path Markup Syntax&lt;/em&gt;章节来得到关于Path标记语法的更多信息。&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;&lt;a name="paintingshapewithbrushes"&gt;&lt;/a&gt;
&lt;p style="font-size: 14pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;使用画刷填充形状&lt;/strong&gt;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;大多数的形状由两部分组成。&amp;#8220;边框（&lt;strong&gt;Stroke&lt;/strong&gt;）&amp;#8221;和&amp;#8220;填充（&lt;strong&gt;Fill&lt;/strong&gt;）&amp;#8221;，它们分别可以使用&lt;strong&gt;Stroke&lt;/strong&gt;和&lt;strong&gt;Fill&lt;/strong&gt;属性进行控制。下面的插图表示了在第一个例子里&lt;strong&gt;Rectangle&lt;/strong&gt;的&lt;strong&gt;Strok&lt;/strong&gt;和&lt;strong&gt;Fill&lt;/strong&gt;。&lt;/p&gt;&lt;img src="http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/images/strokeandfill.png"&gt; 
&lt;p style="font-size: 10pt; font-family: verdana"&gt;不过，并不是每一个形状都有&lt;strong&gt;Fill&lt;/strong&gt;和&lt;strong&gt;Stroke&lt;/strong&gt;：&lt;strong&gt;Line&lt;/strong&gt;元素只有&lt;strong&gt;Stroke&lt;/strong&gt;，设置&lt;strong&gt;Line&lt;/strong&gt;的&lt;strong&gt;Fill&lt;/strong&gt;属性不会有任何效果。&amp;nbsp;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;您可以使用画刷（Brush）设置一个形状的&lt;strong&gt;Stroke&lt;/strong&gt;和&lt;strong&gt;Fill&lt;/strong&gt;。有4种类型的画刷可供选择：&lt;/p&gt;
&lt;ul&gt;
&lt;li class="WpfeQS"&gt;&lt;strong&gt;SolidColorBrush&lt;/strong&gt; 
&lt;li class="WpfeQS"&gt;&lt;strong&gt;LinerGradientBrush&lt;/strong&gt; 
&lt;li class="WpfeQS"&gt;&lt;strong&gt;RadialGradientBrush&lt;/strong&gt; 
&lt;li class="WpfeQS"&gt;&lt;strong&gt;ImageBrush&lt;/strong&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p style="font-size: 11pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;使用SolidColorBrush填充实心颜色&lt;/strong&gt;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;为了使用实心颜色来填充一块区域，您可以使用&lt;strong&gt;SolidColorBrush&lt;/strong&gt;，XAML提供了几种创建&lt;strong&gt;SolidColorBrush&lt;/strong&gt;的方式。&lt;/p&gt;
&lt;ul&gt;
&lt;li class="WpfeQS"&gt;您可以设置Color属性为指定的颜色名，例如&amp;#8220;Black&amp;#8221;或&amp;#8220;Gray&amp;#8221; 
&lt;li class="WpfeQS"&gt;您可以设置Color属性为16进制表示的颜色，包括是否透明。您可以使用几种方式： 
&lt;ul&gt;
&lt;li class="WpfeQS"&gt;6位表示法。它的格式为&lt;em&gt;#RRGGBB&lt;/em&gt;，其中&lt;em&gt;RR&lt;/em&gt;为两位16进制数，用于描述红色所占的分量，&lt;em&gt;GG&lt;/em&gt;和&lt;em&gt;BB&lt;/em&gt;分别描述了绿色所占份量。例如：#0033FF。 
&lt;li class="WpfeQS"&gt;8位表示法。它的格式和6位表示法大致相同，唯一的区别则是使用多余的两位描述alpha值，或者说是颜色的透明程度：&lt;em&gt;#AARRGGBB&lt;/em&gt;。例如：#990033FF&lt;/li&gt;&lt;/ul&gt;
&lt;li class="WpfeQS"&gt;您可以使用创建元素的方法来显式地创建一个&lt;strong&gt;SolidColorBrush&lt;/strong&gt;并且设置它的&lt;strong&gt;Color&lt;/strong&gt;属性。&lt;/li&gt;&lt;/ul&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;下面的示例使用了多种方法将一个对象填充为黑色。&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Canvas&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"http://schemas.microsoft.com/client/2007"&lt;/span&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;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;

    &lt;span style="color: #008000"&gt;&amp;lt;!-- SolidColorBrush by color name. --&amp;gt;&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Ellipse&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"90"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"90"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Left&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"10"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"10"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;Fill&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"black"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;

    &lt;span style="color: #008000"&gt;&amp;lt;!-- SolidColorBrush by 6-digit hexadecimal notation. --&amp;gt;&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Ellipse&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"90"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"90"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Left&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"110"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"10"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;Fill&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"#000000"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;

    &lt;span style="color: #008000"&gt;&amp;lt;!-- SolidColorBrush by 8-digit hexadecimal notation. --&amp;gt;&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Ellipse&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"90"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"90"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Left&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"10"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"110"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;Fill&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"#ff000000"&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;Ellipse&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"90"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"90"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Left&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"110"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"110"&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;Ellipse.Fill&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;

            &lt;span style="color: #008000"&gt;&amp;lt;!-- SolidColorBrush by object element syntax. --&amp;gt;&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;SolidColorBrush&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Color&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Black"&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;Ellipse.Fill&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;Ellipse&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;Canvas&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;div class="agHost" id="agHost3"&gt;&lt;/div&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;a class="agButton" href="javascript:start('agHost3', 'agButton3', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/drawing-Colors.html');"&gt;重新开始&lt;/a&gt;&lt;a class="agButton" id="agButton3" href="javascript:turn('agHost3', 'agButton3', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/drawing-Colors.html');"&gt;查看内容&lt;/a&gt;&lt;/p&gt;
&lt;script language="javascript"&gt;
start('agHost3', 'agButton3', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/drawing-Colors.html');
&lt;/script&gt;

&lt;p style="font-size: 11pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;使用LinarGradientBrush和RadialGradientBrush填充梯度效果&lt;/strong&gt;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;WPF/E支持线性和放射性的梯度效果。梯度包含了一个或多个&amp;#8220;梯度逗留点（Gradients Stop）&amp;#8221;用于描述梯度变化中颜色的位置和变化。大多数的梯度只需要两个梯度逗留点，不过事实上您可以添加任意多个。&lt;/p&gt;
&lt;ul&gt;
&lt;li class="WpfeQS"&gt;&lt;strong&gt;LinearGradientBrush&lt;/strong&gt;绘制线性的梯度效果。这条线在默认情况下是从被填充对象左上角到右下角的斜线。您可以使用&lt;strong&gt;StartPoint&lt;/strong&gt;和&lt;strong&gt;EndPoint&lt;/strong&gt;属性来改变这条线的位置。 
&lt;li class="WpfeQS"&gt;&lt;strong&gt;RadialGradientBrush&lt;/strong&gt;绘制类似于圆形的梯度效果。在默认情况下，这个圆形以填充区域的中心为圆心，您可以通过设置它的&lt;strong&gt;GradientOrigin&lt;/strong&gt;，&lt;strong&gt;Center&lt;/strong&gt;，&lt;strong&gt;RadiusX&lt;/strong&gt;和&lt;strong&gt;RadiusY&lt;/strong&gt;属性来自定义梯度效果。&lt;/li&gt;&lt;/ul&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;您通过创建&lt;strong&gt;GradientStop&lt;/strong&gt;对象来添加梯度逗留点。您可以通过设置&lt;strong&gt;GradientStop&lt;/strong&gt;对象的&lt;strong&gt;Offset&lt;/strong&gt;属性为0到1之间的值，来指定它在梯度中的相对位置。您通过设置&lt;strong&gt;GradientStop&lt;/strong&gt;对象的&lt;strong&gt;Color&lt;/strong&gt;属性为颜色名或者16进制表示法来指定颜色。&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;下面的示例使用LinearGradientBrush和RadialGradientBrush来填充Rectangle对象。&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Canvas&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"http://schemas.microsoft.com/client/2007"&lt;/span&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;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
    
    &lt;span style="color: #008000"&gt;&amp;lt;!-- Linear gradients --&amp;gt;&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Rectangle&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"140"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"70"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Left&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"10"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"10"&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;Rectangle.Fill&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;LinearGradientBrush&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;GradientStop&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Color&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Yellow"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Offset&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"0.0"&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;GradientStop&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Color&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Red"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Offset&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"0.25"&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;GradientStop&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Color&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Blue"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Offset&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"0.75"&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;GradientStop&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Color&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"LimeGreen"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Offset&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"1.0"&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;LinearGradientBrush&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;Rectangle.Fill&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;Rectangle&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;Rectangle&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"140"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"70"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Left&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"155"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"10"&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;Rectangle.Fill&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;LinearGradientBrush&lt;/span&gt;    &lt;span style="color: #ff0000"&gt;StartPoint&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"0,0"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;EndPoint&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"1,0"&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;GradientStop&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Color&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Yellow"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Offset&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"0.0"&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;GradientStop&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Color&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Red"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Offset&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"0.25"&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;GradientStop&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Color&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Blue"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Offset&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"0.75"&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;GradientStop&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Color&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"LimeGreen"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Offset&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"1.0"&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;LinearGradientBrush&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;Rectangle.Fill&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;Rectangle&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
    
    &lt;span style="color: #008000"&gt;&amp;lt;!-- Radial gradients --&amp;gt;&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Rectangle&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"140"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"70"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Left&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"10"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"110"&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;Rectangle.Fill&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;RadialGradientBrush&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;GradientStop&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Color&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Yellow"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Offset&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"0.0"&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;GradientStop&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Color&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Red"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Offset&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"0.25"&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;GradientStop&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Color&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Blue"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Offset&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"0.75"&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;GradientStop&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Color&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"LimeGreen"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Offset&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"1.0"&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;RadialGradientBrush&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;Rectangle.Fill&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;Rectangle&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;Rectangle&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"140"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"70"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Left&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"155"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"110"&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;Rectangle.Fill&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;RadialGradientBrush&lt;/span&gt; &lt;span style="color: #ff0000"&gt;GradientOrigin&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"1,0"&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;GradientStop&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Color&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Yellow"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Offset&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"0.0"&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;GradientStop&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Color&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Red"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Offset&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"0.25"&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;GradientStop&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Color&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Blue"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Offset&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"0.75"&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;GradientStop&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Color&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"LimeGreen"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Offset&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"1.0"&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;RadialGradientBrush&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;Rectangle.Fill&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;Rectangle&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;Canvas&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;div class="agHost" id="agHost4"&gt;&lt;/div&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;a class="agButton" href="javascript:start('agHost4', 'agButton4', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/drawing-Gradients.html');"&gt;重新开始&lt;/a&gt;&lt;a class="agButton" id="agButton4" href="javascript:turn('agHost4', 'agButton4', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/drawing-Gradients.html');"&gt;查看内容&lt;/a&gt;&lt;/p&gt;
&lt;script language="javascript"&gt;
start('agHost4', 'agButton4', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/drawing-Gradients.html');
&lt;/script&gt;

&lt;p style="font-size: 10pt; font-family: verdana"&gt;您也可以对于一个形状的&lt;strong&gt;Stroke&lt;/strong&gt;填充梯度效果。&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;下面的插图标记了示例中第一个&lt;strong&gt;LinearGradientBrush&lt;/strong&gt;对象的每一个梯度逗留点。&lt;/p&gt;&lt;img src="http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/images/gradientstops.jpg"&gt; 
&lt;p style="font-size: 11pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;使用ImageBrush用图片填充对象&lt;/strong&gt;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;另一种类型的画刷是&lt;strong&gt;ImageBrush&lt;/strong&gt;。在默认情况下，图片为被拉伸并且填满整个形状，不过您可以使用&lt;strong&gt;Stretch&lt;/strong&gt;属性来控制拉伸图片的方式。下面的示例使用了两个&lt;strong&gt;ImageBrush&lt;/strong&gt;对象，为它们的&lt;strong&gt;Stretch&lt;/strong&gt;属性分别设置不同的值，用以填充两个&lt;strong&gt;Rectangle&lt;/strong&gt;对象。&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Canvas&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"http://schemas.microsoft.com/client/2007"&lt;/span&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;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;Rectangle&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"180"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"90"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Left&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"10"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"10"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;Stroke&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Black"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;StrokeThickness&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"1"&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;Rectangle.Fill&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;ImageBrush&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ImageSource&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"star.png"&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;Rectangle.Fill&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;Rectangle&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;Rectangle&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"180"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"90"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Left&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"110"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"10"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;Stroke&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Black"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;StrokeThickness&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"1"&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;Rectangle.Fill&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;ImageBrush&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ImageSource&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"star.png"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Stretch&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Uniform"&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;Rectangle.Fill&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;Rectangle&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;Canvas&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;div class="agHost" id="agHost5"&gt;&lt;/div&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;a class="agButton" href="javascript:start('agHost5', 'agButton5', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/drawing-ImageBrush.html');"&gt;重新开始&lt;/a&gt;&lt;a class="agButton" id="agButton5" href="javascript:turn('agHost5', 'agButton5', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/drawing-ImageBrush.html');"&gt;查看内容&lt;/a&gt;&lt;/p&gt;
&lt;script language="javascript"&gt;
start('agHost5', 'agButton5', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/drawing-ImageBrush.html');
&lt;/script&gt; 
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;&lt;a name="transformingshapes"&gt;&lt;/a&gt;
&lt;p style="font-size: 14pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;形状变换&lt;/strong&gt;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;就像所有的UI元素那样，形状元素能够通过它们的&lt;strong&gt;RenderTransform&lt;/strong&gt;属性被伸缩、旋转或者变换。&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;&lt;a name="whatsnext"&gt;&lt;/a&gt;
&lt;p style="font-size: 14pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;下面该做什么呢？&lt;/strong&gt;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;在下一部分&amp;#8220;&lt;a href="http://blog.zhaojie.me/2006/12/wpfe-ctp-quick-start-part-5.html" target="_blank"&gt;公有图形属性&lt;/a&gt;&amp;#8221;中，您将会了解到一些属性的使用方式，例如&lt;strong&gt;Opacity&lt;/strong&gt;，&lt;strong&gt;Clip&lt;/strong&gt;和&lt;strong&gt;RenderTransform&lt;/strong&gt;等。&lt;/p&gt;</description>
      <comments>http://blog.zhaojie.me/2006/12/wpfe-ctp-quick-start-part-4.html#comments</comments>
      <pubDate>Sat, 09 Dec 2006 15:23:00 GMT</pubDate>
      <lastBuildDate>Sat, 09 Dec 2006 15:23:00 GMT</lastBuildDate>
    </item>
    <item>
      <author>jeffz@live.com (老赵)</author>
      <category domain="http://blog.zhaojie.me/speech/">培训演讲</category>
      <category domain="http://blog.zhaojie.me/translation/">翻译引进</category>
      <category domain="http://blog.zhaojie.me/practice/">实践优化</category>
      <category domain="http://blog.zhaojie.me/asp-net/">ASP.NET</category>
      <category domain="http://blog.zhaojie.me/front-end/">前端表现</category>
      <title>讲座展示：TechEd Europe DEV 411 - AJAX Patterns with ASP.NET AJAX（2）</title>
      <link>http://blog.zhaojie.me/2006/12/lecture--teched-europe-dev411-2.html</link>
      <guid>http://blog.zhaojie.me/2006/12/lecture--teched-europe-dev411-2.html</guid>
      <description>&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;这次我选择的讲座内容，是最近在TechEd 2006 Europe中Andre Snanbria和Jeff Prosise的讲座&amp;#8220;AJAX Pattern with ASP.NET AJAX&amp;#8221;。Jeff Prosise是Wintellect的Co-Founder，Andre Sanabria是ASP.NET AJAX Team的Lead Program Manager。在MSDN's Showtime上已经有了&lt;a href="http://www.microsoft.com/emea/msdnshowtime/sessionh.aspx?videoid=331" target=_blank&gt;这个讲座的完整视频&lt;/a&gt;，而我在早些时候给Andre Sanabria写了封Email，一星期后他给我寄来了这个讲座的PPT和Demo，大家可以&lt;a href="http://files.cnblogs.com/JeffreyZhao/TechEd_DEV411.zip" target=_blank&gt;点击这里&lt;/a&gt;下载。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;这次讲座的主要内容是讲述了使用ASP.NET AJAX开发AJAX应用的最佳实践，在这次讲座里，会对建立轻量级的客户端控件的方法进行深入，讲述了如何优化脚本代码，并提出了如何避免AJAX开发中常见的问题。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;本篇文章是这次讲座展示的第二篇，讲述了UpdatePanel的工作方式。&lt;/p&gt;
&lt;p style="FONT-SIZE: 14pt; FONT-FAMILY: verdana"&gt;&lt;strong&gt;讲座内容&lt;/strong&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;strong&gt;&lt;a href="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV411AJAXPatternsw.NETAJAX2_BB53/DEV411_13%5B1%5D.jpg" atomicselection="true"&gt;&lt;img style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height=180 src="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV411AJAXPatternsw.NETAJAX2_BB53/DEV411_13.jpg" width=240 border=0&gt;&lt;/a&gt; &lt;/strong&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;strong&gt;Jeff：&lt;/strong&gt;很好，有很多最佳实践和合适的编程模式来简化编写AJAX应用的方式。就像Andre说的，我们现在要做的就是回头向大家一点点地展示一些我们已经实现的代码。可能它们和其它我们在这周展示给大家的有关ASP.NET AJAX的东西会有些不同，不过所有的我们做的，我们实现这些应用的方式，目的都是尽可能的做到更高的效率。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;strong&gt;Jeff：&lt;/strong&gt;那么我们现在就来考虑对于这个应用程序的进行增强的第一步，我们第一步想看的东西。我们在这个应用中使用了&amp;#8220;局部刷新&amp;#8221;的技术，事实上在刚才的照片浏览页面，用到的并不是1个，而是4个不同的UpdatePanel。你们可能已经很清楚了，UpdatePanel完全就是用来&amp;#8220;局部刷新&amp;#8221;的。用户对于页面的PostBack和它造成的页面闪烁以及视觉中心的丢失，都可以说是深恶痛绝。当我们现在谈论到AJAX最先想到的就是&amp;#8220;局部刷新&amp;#8221;，就是不进行PostBack，而是对服务器端进行轻量级的异步CallBack。带来这些美妙东西的就是XMLHttpRequest，它能使浏览器不将现有的HTML给丢弃，因此我们就避免了页面的闪烁。如果您自己写AJAX代码的话，是需要比较多的工作才能完成的。UpdatePanel的美妙之处就在于，我能够简单地将它拖动到页面上，在它内部放置一些我们需要局部刷新的元素，然后UpdatePanel就会为我们管理那些元素的各种复杂情况了，这实在是一种魔法——直到您了解了让它能够这样的工作是多么地不容易。不过这是一种交易。如果我简单地在页面上放置几个UpdatePanel，我可能无法得到我期望的结果——的确，它增强了用户体验，但是在另一方面，它也让一些不需要的数据在客户端和服务器端之间来回。不仅仅是在一个单独的请求中发送了过多的数据，也有可能超出获得我们期望的多余的数据。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;a href="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV411AJAXPatternsw.NETAJAX2_BB53/DEV411_14%5B1%5D.jpg" atomicselection="true"&gt;&lt;img style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height=180 src="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV411AJAXPatternsw.NETAJAX2_BB53/DEV411_14.jpg" width=240 border=0&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;strong&gt;Jeff：&lt;/strong&gt;在演示下一个Demo之前，我再多谈论一下UpdatePanel是如何工作的。当你把一个UpdatePanel放在页面中之后，在页面就会实例化一个类型为PageRequestManager的客户端对象。当然这些都由ScriptManager来完成这些工作了，当你把ScriptManager的EnablePartialRendering属性设为True之后，一个用于初始化PageRequestManager对象的脚本就被发送到客户端。我们把Microsoft AJAX在客户端的那部分称之为Microsoft AJAX Library。事实上，一个理解ScriptManager的好方法是从客户端的角度来看UpdatePanel。PageRequestManager做的事情就是异步地将数据传输到客户端，管理客户端与服务器端的数据交换，得到服务器端UpdatePanel输出的内容，通过改变浏览器DOM的方式将这些内容放置在客户端中。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;strong&gt;Jeff：&lt;/strong&gt;一般来说，如果一个没有UpdatePanel的页面，当我点击了页面上的一个&amp;#8220;提交&amp;#8221;按钮，页面被整个提交到了服务器端，在ASP.NET中我们称之为PostBack，因为数据通过了Post的方式传递&amp;#8220;回（Back）&amp;#8221;服务器端。不过因为有了PageRequestManager的神奇作用，这里就不会产生一个PostBack了。这时候数据就是用了XMLHttpRequest被异步地发送到了服务器端，在服务器端会产生一个round-trip，但是现在我们就不会让浏览器放弃它已经拥有的HTML了。让我来告诉您一些UpdatePanel更详细的一些秘密。大部分的人都会认为UpdatePanel会带来很高的效率——直到我们查看了客户端和服务器端交互的数据。一个传统的PostBack会将客户端所有的ViewState传递到服务器端，当然也包括所有页面上需要向服务器端Post的数据。事实上UpdatePanel的一个秘密就是：它也作了相同的事情。您可能会认为UpdatePanel并不会将ViewState以及多余的数据传回客户端，不过它的确这么做了。在这方面，一个UpdatePanel和一个传统的PostBack并没有什么区别，因此UpdatePanel并不是一种依靠避免传递ViewState而得到更高性能的方法。UpdatePanel这么做有个很重要的原因：因为在UpdatePane发送一个异步的CallBack时，您在服务器端也需要访问平时一直用到的ASP.NET的对象模型，这也意味着当一个异步的CallBack将数据发送到服务器端时，所有的控件树都会被重建，会经历一个传统的生命周期，这一切和传统PostBack的结果几乎完全相同：控件树会被重建，然后触发事件。事实上，在控件的事件被触发时有一点不同，这时候ASP.NET会意识到：&amp;#8220;嘿，这不是个传统的PostBack，这是个页面的PageRequestManager发送的异步CallBack。&amp;#8221;然后ASP.NET会让这个页面请求继续被处理，和传统PostBack相比，在服务期端处理时有很大区别的一点就是生命周期里的&amp;#8220;Render&amp;#8221;部分。传统状况下，页面会生成所有的内容，从控件树的最顶端直到控件树的最后。而UpdatePanel在这里的美妙之处就在于，它只会让UpdatePanel内部的控件被生成，在这里我们的确节省了一些消耗，因为我们在服务器端执行了较少的代码。不过这点性能的提高，可能完全被之前的消耗所抵消了，我们还是进行了一个完整的PostBack。这里我们可以是用一些方法，让我们能够尽可能高效地使用UpdatePanel。这幅图（上图）的最后，就表示了，当UpdatePanel在生成它内部控件的HTML之后将其发送到了客户端，而PageRequestManager则会处理页面内容更新的方式。在默认情况下，UpdatePanel会生成一个DIV标签，您能够将其设置为SPAN标签。PageRequestManager会设置标签的innerHTML属性，用新的内容替换了旧的内容。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;strong&gt;Jeff：&lt;/strong&gt;下面让我们再体验一下刚才的照片浏览器，让我们更清楚地了解它是如何使用UpdatePanel，我们是如何将尽可能高效地使用UpdatePanel。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;（未完待续）&lt;iframe style="DISPLAY: none; VISIBILITY: hidden" src="http://blog.zhaojie.me/2006/12/583918.html" width=0 height=0&gt;&lt;/iframe&gt;&lt;/p&gt;</description>
      <comments>http://blog.zhaojie.me/2006/12/lecture--teched-europe-dev411-2.html#comments</comments>
      <pubDate>Fri, 08 Dec 2006 07:33:00 GMT</pubDate>
      <lastBuildDate>Fri, 08 Dec 2006 07:33:00 GMT</lastBuildDate>
    </item>
    <item>
      <author>jeffz@live.com (老赵)</author>
      <category domain="http://blog.zhaojie.me/front-end/">前端表现</category>
      <category domain="http://blog.zhaojie.me/translation/">翻译引进</category>
      <title>WPF/E CTP Quick Start - 第三部分：Canvas对象（翻译）</title>
      <link>http://blog.zhaojie.me/2006/12/wpfe-ctp-quick-start-part-3.html</link>
      <guid>http://blog.zhaojie.me/2006/12/wpfe-ctp-quick-start-part-3.html</guid>
      <description>&lt;link href="http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/cnblogs/QuickStart.css" type="text/css" rel="stylesheet"&gt; &lt;script src="http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/cnblogs/QuickStart.js" type="text/javascript"&gt;&lt;/script&gt;  &lt;div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 5px; font-size: 10pt; padding-bottom: 5px; border-left: #cccccc 1px solid; padding-top: 5px; border-bottom: #cccccc 1px solid; font-family: verdana"&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;strong&gt;Canvas&lt;/strong&gt;对象是一个设计用来存放和定位各种图形和控件的对象。每一个WPF/E XAML文件都至少有一个&lt;strong&gt;Canvas&lt;/strong&gt;。这篇文当介绍了&lt;strong&gt;Canvas&lt;/strong&gt;对象，并且描述了应该如何添加，定位子对象以及改变其大小。这篇文档包含以下部分。&lt;/p&gt; &lt;ul&gt; &lt;li class="WpfeQS"&gt;&lt;a href="#addobjects"&gt;向您的Canvas里添加一个对象&lt;/a&gt;  &lt;li class="WpfeQS"&gt;&lt;a href="#positionobjects"&gt;定位一个对象&lt;/a&gt;  &lt;li class="WpfeQS"&gt;&lt;a href="#widthandheight"&gt;控制宽度和高度&lt;/a&gt;  &lt;li class="WpfeQS"&gt;&lt;a href="#nestedcanvas"&gt;嵌套的Canvas对象&lt;/a&gt;  &lt;li class="WpfeQS"&gt;&lt;a href="#whatsnext"&gt;下面该做什么呢？&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;&lt;a name="addobjects"&gt;&lt;/a&gt; &lt;p style="font-size: 14pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;向您的Canvas里添加一个对象&lt;/strong&gt;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;一个Canvas包含和定位了其它的对象。如果您希望在Canvas对象内增加一个对象，请在&amp;lt;Canvas&amp;gt;标签内添加新的元素。下面的例子为Canvas添加了一个Ellipse对象。因为Canvas是根元素，因此它包含了一些命名空间的定义。&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Canvas&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"http://schemas.microsoft.com/client/2007"&lt;/span&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;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;Ellipse&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"200"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"200"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;Stroke&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Black"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;StrokeThickness&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"10"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Fill&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"SlateBlue"&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;Canvas&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;div class="agHost" id="agHost0"&gt;&lt;/div&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;a class="agButton" href="javascript:start('agHost0', 'agButton0', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/canvas-additem.html');"&gt;重新开始&lt;/a&gt;&lt;a class="agButton" id="agButton0" href="javascript:turn('agHost0', 'agButton0', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/canvas-additem.html');"&gt;查看内容&lt;/a&gt;&lt;/p&gt;
&lt;script language="javascript"&gt;
start('agHost0', 'agButton0', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/canvas-additem.html');
&lt;/script&gt;

&lt;p style="font-size: 10pt; font-family: verdana"&gt;一个&lt;strong&gt;Canvas&lt;/strong&gt;能够包含任意数量的对象，甚至与其它的&lt;strong&gt;Canvas&lt;/strong&gt;对象。一个&lt;strong&gt;Canvas&lt;/strong&gt;的内部对象的前后顺序是由它们声明的顺序决定的。后声明的对象会显示在先声明的对象之前。&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;&lt;a name="positionobjects"&gt;&lt;/a&gt;
&lt;p style="font-size: 14pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;定位一个对象&lt;/strong&gt;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;您可以设置对象的&lt;strong&gt;Canvas.Left&lt;/strong&gt;和&lt;strong&gt;Canvas.Top&lt;/strong&gt;附加属性，以确定它在&lt;strong&gt;Canvas&lt;/strong&gt;中的位置。&lt;strong&gt;Canvas.Left&lt;/strong&gt;附加属性指定了对象与其父&lt;strong&gt;Canvas&lt;/strong&gt;左边缘的距离，而&lt;strong&gt;Canvas.Top&lt;/strong&gt;附加属性指定了子对象与它父&lt;strong&gt;Canvas&lt;/strong&gt;上边缘的距离。下面的例子将之前的Ellipse进行了移动，使其与&lt;strong&gt;Canvas&lt;/strong&gt;上边缘和左边缘都相差30像素。&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Canvas&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"http://schemas.microsoft.com/client/2007"&lt;/span&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;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;Ellipse&lt;/span&gt; 
        &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Left&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"30"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"30"&lt;/span&gt; 
        &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"200"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"200"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;Stroke&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Black"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;StrokeThickness&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"10"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Fill&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"SlateBlue"&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;Canvas&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;div class="agHost" id="agHost1"&gt;&lt;/div&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;a class="agButton" href="javascript:start('agHost1', 'agButton1', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/canvas-LeftTop.html');"&gt;重新开始&lt;/a&gt;&lt;a class="agButton" id="agButton1" href="javascript:turn('agHost1', 'agButton1', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/canvas-LeftTop.html');"&gt;查看内容&lt;/a&gt;&lt;/p&gt;
&lt;script language="javascript"&gt;
start('agHost1', 'agButton1', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/canvas-LeftTop.html');
&lt;/script&gt;

&lt;p style="font-size: 10pt; font-family: verdana"&gt;下面的示意图描述了&lt;strong&gt;Canvas&lt;/strong&gt;的坐标系统，并且在前一个例子的基础上定位了&lt;strong&gt;Ellipse&lt;/strong&gt;对象。&lt;/p&gt;&lt;img src="http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/images/canvas_left_top.png"&gt; 
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;&lt;a name="widthandheight"&gt;&lt;/a&gt;
&lt;p style="font-size: 14pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;控制宽度和高度&lt;/strong&gt;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;strong&gt;Canvas&lt;/strong&gt;, 形状，以及其它各种元素都有&lt;strong&gt;Width&lt;/strong&gt;和&lt;strong&gt;Height&lt;/strong&gt;属性，使您能够指定它们的大小。下面的例子建立了一个200像素宽和200像素高的&lt;strong&gt;Ellipase&lt;/strong&gt;对象。请注意，在这里不支持使用百分比来指定大小。&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Ellipse&lt;/span&gt; 
    &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Left&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"30"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"30"&lt;/span&gt; 
    &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"200"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"200"&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;Stroke&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Black"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;StrokeThickness&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"10"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Fill&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"SlateBlue"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;div class="agHost" id="agHost2"&gt;&lt;/div&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;a class="agButton" href="javascript:start('agHost2', 'agButton2', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/canvas-childWidthHeight.html');"&gt;重新开始&lt;/a&gt;&lt;a class="agButton" id="agButton2" href="javascript:turn('agHost2', 'agButton2', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/canvas-childWidthHeight.html');"&gt;查看内容&lt;/a&gt;&lt;/p&gt;
&lt;script language="javascript"&gt;
start('agHost2', 'agButton2', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/canvas-childWidthHeight.html');
&lt;/script&gt;

&lt;p style="font-size: 10pt; font-family: verdana"&gt;下面的例子设置了父&lt;strong&gt;Canvas&lt;/strong&gt;的&lt;strong&gt;Width&lt;/strong&gt;和&lt;strong&gt;Heigh&lt;/strong&gt;t属性，并且将它的背景设为了绿色。&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Canvas&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"http://schemas.microsoft.com/client/2007"&lt;/span&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;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"200"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"200"&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;Background&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"LimeGreen"&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;Ellipse&lt;/span&gt; 
        &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Left&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"30"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"30"&lt;/span&gt; 
        &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"200"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"200"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;Stroke&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Black"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;StrokeThickness&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"10"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Fill&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"SlateBlue"&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;Canvas&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;div class="agHost" id="agHost3"&gt;&lt;/div&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;a class="agButton" href="javascript:start('agHost3', 'agButton3', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/canvas-HeightWidth.html');"&gt;重新开始&lt;/a&gt;&lt;a class="agButton" id="agButton3" href="javascript:turn('agHost3', 'agButton3', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/canvas-HeightWidth.html');"&gt;查看内容&lt;/a&gt;&lt;/p&gt;
&lt;script language="javascript"&gt;
start('agHost3', 'agButton3', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/canvas-HeightWidth.html');
&lt;/script&gt;

&lt;p style="font-size: 10pt; font-family: verdana"&gt;当您运行这个例子时，绿色的方形就是&lt;strong&gt;Canvas&lt;/strong&gt;对象，而灰色的背景是&lt;strong&gt;ActiveX&lt;/strong&gt;控件，它并不会受&lt;strong&gt;Canvas&lt;/strong&gt;影响。请注意&lt;strong&gt;Ellipse&lt;/strong&gt;并没有被切除，它超出了&lt;strong&gt;Canvas&lt;/strong&gt;的边缘。&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;如果您不设置Width和Height属性，它们在默认情况下都是0。&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;&lt;a name="nestedcanvas"&gt;&lt;/a&gt;
&lt;p style="font-size: 14pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;嵌套的Canvas对象&lt;/strong&gt;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;Canvas能够含有其它的Canvas对象。下面的例子创建了一个包含其它两个Canvas对象的Canvas对象。&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Canvas&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"http://schemas.microsoft.com/client/2007"&lt;/span&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;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;Canvas&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"50"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"50"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Left&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"30"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"30"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;Background&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"blue"&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;Canvas&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"50"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"50"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Left&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"130"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"30"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;Background&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"red"&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;Canvas&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;div class="agHost" id="agHost4"&gt;&lt;/div&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;a class="agButton" href="javascript:start('agHost4', 'agButton4', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/canvas-nested.html');"&gt;重新开始&lt;/a&gt;&lt;a class="agButton" id="agButton4" href="javascript:turn('agHost4', 'agButton4', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/canvas-nested.html');"&gt;查看内容&lt;/a&gt;&lt;/p&gt;
&lt;script language="javascript"&gt;
start('agHost4', 'agButton4', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/canvas-nested.html');
&lt;/script&gt;

&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;&lt;a name="whatsnext"&gt;&lt;/a&gt;
&lt;p style="font-size: 14pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;下面该做什么呢？&lt;/strong&gt;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;在下一个部分&amp;#8220;&lt;a href="http://blog.zhaojie.me/2006/12/wpfe-ctp-quick-start-part-4.html"&gt;绘图和填充&lt;/a&gt;&amp;#8221;中，您会了解图形和使用画刷来绘制图形。&lt;/p&gt;</description>
      <comments>http://blog.zhaojie.me/2006/12/wpfe-ctp-quick-start-part-3.html#comments</comments>
      <pubDate>Fri, 08 Dec 2006 03:57:00 GMT</pubDate>
      <lastBuildDate>Fri, 08 Dec 2006 03:57:00 GMT</lastBuildDate>
    </item>
    <item>
      <author>jeffz@live.com (老赵)</author>
      <category domain="http://blog.zhaojie.me/front-end/">前端表现</category>
      <category domain="http://blog.zhaojie.me/translation/">翻译引进</category>
      <title>WPF/E CTP Quick Start - 第二部分：创建一个XAML文件（翻译）</title>
      <link>http://blog.zhaojie.me/2006/12/wpfe-ctp-quick-start-part-2.html</link>
      <guid>http://blog.zhaojie.me/2006/12/wpfe-ctp-quick-start-part-2.html</guid>
      <description>&lt;link href="http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/cnblogs/QuickStart.css" type="text/css" rel="stylesheet"&gt; &lt;script src="http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/cnblogs/QuickStart.js" type="text/javascript"&gt;&lt;/script&gt;  &lt;div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 5px; font-size: 10pt; padding-bottom: 5px; border-left: #cccccc 1px solid; padding-top: 5px; border-bottom: #cccccc 1px solid; font-family: verdana"&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;在前一篇文档中&amp;#8220;&lt;a href="http://blog.zhaojie.me/2006/12/wpfe-ctp-quick-start-part-1.html" target="_blank"&gt;创建一个WPF/E项目&lt;/a&gt;&amp;#8221;中，我们向HTML页面里添加了一个WPF/E控件，并且创建了一个空的XAML文件。这篇文档会向您展示如何在您的XAML文件里创建WPF/E内容。&lt;/p&gt; &lt;ul&gt; &lt;li class="WpfeQS"&gt;&lt;a href="#step1"&gt;第一步：创建一个Canvas和命名空间的声明&lt;/a&gt;  &lt;li class="WpfeQS"&gt;&lt;a href="#step2"&gt;第二步：画些东西吧！&lt;/a&gt;  &lt;li class="WpfeQS"&gt;&lt;a href="#step3"&gt;第三步：查看您的XAML内容&lt;/a&gt;  &lt;li class="WpfeQS"&gt;&lt;a href="#whatsnext"&gt;下面该做什么呢？&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;&lt;a name="step1"&gt;&lt;/a&gt; &lt;p style="font-size: 14pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;第一步：创建一个Canvas和命名空间的声明&lt;/strong&gt;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;打开myxaml.xaml这个您在上一部分&amp;#8220;&lt;a href="http://blog.zhaojie.me/2006/12/wpfe-ctp-quick-start-part-1.html" target="_blank"&gt;创建一个WPF/E项目&lt;/a&gt;&amp;#8221;所创建的XAML文件。将下面的代码复制到文件中，以创建一个&lt;strong&gt;Canvas&lt;/strong&gt;元素和WPF/E以及XAML命名空间的声明。&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Canvas&lt;/span&gt; 
    &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"http://schemas.microsoft.com/client/2007"&lt;/span&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;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;Canvas&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;每个WPF/E XAML文件都由一个包含WPF/E命名空间声明的&amp;lt;Canvas&amp;gt;标签开始，它有一个xmlns属性声明的WPF/E命名空间，以及一个xmlns:x属性声明的XAML命名空间。&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;&lt;a name="step2"&gt;&lt;/a&gt;
&lt;p style="font-size: 14pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;第二步：画些东西吧！&lt;/strong&gt;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;复制下列代码，并且将其粘贴到您的XAML文件的&amp;lt;Canvas&amp;gt;标签中，并保存文件。&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Ellipse&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"200"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"200"&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;Stroke&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Black"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;StrokeThickness&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"10"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Fill&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"SlateBlue"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;&lt;a name="step2"&gt;&lt;/a&gt;
&lt;p style="font-size: 14pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;第三步：查看您的XAML内容&lt;/strong&gt;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;如果想查看您的XAML内容，请双击您的HTML文件，您应该能够看到下面的内容：&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Canvas&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"http://schemas.microsoft.com/client/2007"&lt;/span&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;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;Ellipse&lt;/span&gt; 
        &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"200"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"200"&lt;/span&gt;
        &lt;span style="color: #ff0000"&gt;Stroke&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Black"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;StrokeThickness&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"10"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Fill&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"SlateBlue"&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;Canvas&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;div class="agHost" id="agHost0"&gt;&lt;/div&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;a class="agButton" href="javascript:start('agHost0', 'agButton0', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/canvas-additem.html');"&gt;重新开始&lt;/a&gt;&lt;a class="agButton" id="agButton0" href="javascript:turn('agHost0', 'agButton0', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/canvas-additem.html');"&gt;查看内容&lt;/a&gt;&lt;/p&gt;
&lt;script language="javascript"&gt;
start('agHost0', 'agButton0', 'http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/canvas-additem.html');
&lt;/script&gt;

&lt;p style="font-size: 10pt; font-family: verdana"&gt;请注意，如果您安装了WPF，当您双击XAML文件时，会打开WPF，而不是WPF/E。&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;恭喜！您已经创建了您的第一个WPF/E工程！&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;&lt;a name="whatsnext"&gt;&lt;/a&gt;
&lt;p style="font-size: 14pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;下面该做什么呢？&lt;/strong&gt;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;在下个话题&amp;#8220;&lt;a href="http://blog.zhaojie.me/2006/12/wpfe-ctp-quick-start-part-3.html"&gt;Canvas对象&lt;/a&gt;&amp;#8221;中，我们将更详细地描述&lt;strong&gt;Canvas&lt;/strong&gt;对象。&lt;/p&gt;</description>
      <comments>http://blog.zhaojie.me/2006/12/wpfe-ctp-quick-start-part-2.html#comments</comments>
      <pubDate>Thu, 07 Dec 2006 12:47:00 GMT</pubDate>
      <lastBuildDate>Thu, 07 Dec 2006 12:47:00 GMT</lastBuildDate>
    </item>
    <item>
      <author>jeffz@live.com (老赵)</author>
      <category domain="http://blog.zhaojie.me/front-end/">前端表现</category>
      <category domain="http://blog.zhaojie.me/translation/">翻译引进</category>
      <title>WPF/E CTP Quick Start - 第一部分：创建一个WPF/E项目（翻译）</title>
      <link>http://blog.zhaojie.me/2006/12/wpfe-ctp-quick-start-part-1.html</link>
      <guid>http://blog.zhaojie.me/2006/12/wpfe-ctp-quick-start-part-1.html</guid>
      <description>&lt;link href="http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/cnblogs/QuickStart.css" type="text/css" rel="stylesheet"&gt; &lt;div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 5px; font-size: 10pt; padding-bottom: 5px; border-left: #cccccc 1px solid; padding-top: 5px; border-bottom: #cccccc 1px solid; font-family: verdana"&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;您该如何在您的页面中添加WPF/E呢？一个典型的WPF/E项目有4个文件：一个用于存放和显示内容的HTML文件，一个aghost.js文件，一个XAML文件和一个JavaScript文件。这篇文当描述了创建一个WPF/E工程，以及向HTML添加WPF/E内容的三个步骤。这份指导包括了一下部分：&lt;/p&gt; &lt;ul&gt; &lt;li class="WpfeQS"&gt;&lt;a href="#prereqs"&gt;在您开始之前&amp;#8230;&amp;#8230;&lt;/a&gt;  &lt;li class="WpfeQS"&gt;&lt;a href="#setupaghost"&gt;第一步：建立一个aghost.js文件&lt;/a&gt;  &lt;li class="WpfeQS"&gt;&lt;a href="#createcontrol"&gt;第二步：在您的HTML文件中创建一个ActiveX控件&lt;/a&gt;  &lt;li class="WpfeQS"&gt;&lt;a href="#createcontent"&gt;第三步：创建一个表示WPF/E内容的文件&lt;/a&gt;  &lt;li class="WpfeQS"&gt;&lt;a href="#additionalcontent"&gt;添加额外的WPF/E内容&lt;/a&gt;  &lt;li class="WpfeQS"&gt;&lt;a href="#sampleproject"&gt;一个示例工程&lt;/a&gt;  &lt;li class="WpfeQS"&gt;&lt;a href="#whatsnext"&gt;下面该做什么呢？&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;&lt;a name="prereqs"&gt;&lt;/a&gt; &lt;p style="font-size: 14pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;在您开始之前&amp;#8230;&amp;#8230;&lt;/strong&gt;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;在您创建WPF/E的内容之前，您必须具有以下条件：&lt;/p&gt; &lt;ul class="WpfeQS"&gt; &lt;li class="WpfeQS"&gt;安装了WPF/E插件：如果您还没有安装，&lt;a href="http://go.microsoft.com/fwlink/?LinkID=77792&amp;amp;clcid=0x409" target="_blank"&gt;请点击此处为您的浏览器安装WPF/E插件&lt;/a&gt;。  &lt;li class="WpfeQS"&gt;一个HTML文件：您需要一个用于显示WPF/E内容的HTML文件。您可以自己创建，也可以复制&lt;a href="http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/SampleHTMLPage.html" target="_blank"&gt;这个文件&lt;/a&gt;。  &lt;li class="WpfeQS"&gt;一个文本编辑器：您需要一个文本编辑器（例如记事本）来编辑您的HTML文件。需要更多关于使用Visual Studio编辑WPF/E工程的内容，请查看&amp;#8220;&lt;a href="#" target="_blank"&gt;创建一个Visual Studio WPF/E工程&lt;/a&gt;&amp;#8221;&lt;/li&gt;&lt;/ul&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;&lt;a name="setupaghost"&gt;&lt;/a&gt; &lt;p style="font-size: 14pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;第一步：建立一个aghost.js文件&lt;/strong&gt;&lt;/p&gt; &lt;p style="font-size: 10pt; font-family: verdana"&gt;aghost.js文件是一个JavaScript辅助文件，用来使您的WPF/E内容生效，使之能在多哥平台下查看。&lt;/p&gt; &lt;ul class="WpfeQS" type="a"&gt; &lt;li class="WpfeQS"&gt;将&lt;a href="http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/aghost.js"&gt;aghost.js文件&lt;/a&gt;复制到您的HTML文件所在的目录下：右键点击&lt;a href="http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/aghost.js"&gt;aghost.js文件&lt;/a&gt;的超级链接并选择&amp;#8220;目标另存为...&amp;#8221;，将aghost.js文件存放在与您的HTML文件相同的目录下。  &lt;li class="WpfeQS"&gt;打开您的HTML文件，将下面的代码添加到页面的部分。如果您没有可以使用的HTML文件，请右键点击&lt;a href="http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/SampleHTMLPage.html"&gt;SampleHTMLPage.html&lt;/a&gt;文件的超级链接并选择&amp;#8220;目标另存为...&amp;#8221;，将SampleHTMLPage.html复制到与ashost.js文件相同的目录下。&lt;pre class="code"&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;"aghost.js"&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;script&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;现在您的HTML页面应该已经保存了如下这些基本元素：&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;!DOCTYPE html PUBLIC
    "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&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;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: #ff0000"&gt;xml&lt;/span&gt;:&lt;span style="color: #ff0000"&gt;lang&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"en"&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;head&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;title&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;A Sample HTML page&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;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;"aghost.js"&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;script&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;head&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;body&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;body&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;html&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;&lt;a name="createcontrol"&gt;&lt;/a&gt;
&lt;p style="font-size: 14pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;第二步：在您的HTML文件中创建一个ActiveX控件&lt;/strong&gt;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;为了显示WPF/E的内容，您需要在HTML文件内创建一个ActiveX控件。&lt;/p&gt;
&lt;ul&gt;
&lt;li class="WpfeQS"&gt;在您的HTML文件的&amp;lt;body&amp;gt;标签之间添加如下三行代码，以创建一个用于放置WPF/E内容的元素。&lt;pre class="code"&gt;&lt;span style="color: #008000"&gt;&amp;lt;!-- WPF/E ActiveX控件会放置在下方元素中 --&amp;gt;&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;"agControl1Host"&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;div&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;您能够改变&amp;lt;div&amp;gt;标签的ID，不过您也必须在下一步中修改创建一个agHost时所用的第一个参数。 
&lt;li class="WpfeQS"&gt;在上一步之后，添加如下的HTML和脚本代码以创建一个ActiveX控件。&lt;pre class="code"&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;language&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"javascript"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
    &lt;span style="color: #008000"&gt;// 创建一个WPF/E的ActiveX控件，这里的&lt;/span&gt;
    &lt;span style="color: #008000"&gt;// 方法使您的WPF/E的内容在这个ActiveX控件&lt;/span&gt;
    &lt;span style="color: #008000"&gt;// 被点击之前就创建完毕。&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; agHost(
       &lt;span style="color: #008000"&gt;// 用于插入WPF/E ActiveX控件的元素，一般会使用&lt;/span&gt;
        &lt;span style="color: #008000"&gt;// DIV元素，如果您在上一步改变了HTML元素的ID，&lt;/span&gt;
        &lt;span style="color: #008000"&gt;// 您在这里也必须相应的改变。&lt;/span&gt;
        "&lt;span style="color: #8b0000"&gt;agControl1Host&lt;/span&gt;",
       &lt;span style="color: #008000"&gt;// WPF/E ActiveX控件的ID&lt;/span&gt;
       "&lt;span style="color: #8b0000"&gt;agControl1&lt;/span&gt;", 
       &lt;span style="color: #008000"&gt;// 控件宽度&lt;/span&gt;
        "&lt;span style="color: #8b0000"&gt;300px&lt;/span&gt;", 
       &lt;span style="color: #008000"&gt;// 控件高度&lt;/span&gt;
        "&lt;span style="color: #8b0000"&gt;300px&lt;/span&gt;", 
       &lt;span style="color: #008000"&gt;// 控件的背景色&lt;/span&gt;
        "&lt;span style="color: #8b0000"&gt;#D6D6D6&lt;/span&gt;", 
       &lt;span style="color: #008000"&gt;// 源元素（存放XAML内容的Script标签）&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;, 
       &lt;span style="color: #008000"&gt;// 存放WPF/E内容的XAML文件的URI&lt;/span&gt;
        "&lt;span style="color: #8b0000"&gt;myxaml.xaml&lt;/span&gt;", 
       &lt;span style="color: #008000"&gt;// 是否是无窗的&lt;/span&gt;
        "&lt;span style="color: #8b0000"&gt;false&lt;/span&gt;", 
       &lt;span style="color: #008000"&gt;// 最大帧率（Frame Rate）&lt;/span&gt;
        "&lt;span style="color: #8b0000"&gt;30&lt;/span&gt;",
       &lt;span style="color: #008000"&gt;// 处理错误的Handler，&lt;/span&gt;
        &lt;span style="color: #008000"&gt;// 您能够将其设为一个方法的引用。&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;
    );

    &lt;span style="color: #008000"&gt;// 创建一个全局的WPF/E ActiveX控件的引用，&lt;/span&gt;
    &lt;span style="color: #008000"&gt;// 您能够使用它来接受已经命名的XAML元素。&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; agControl = &lt;span style="color: #0000ff"&gt;document&lt;/span&gt;.getElementById("&lt;span style="color: #8b0000"&gt;agControl1&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: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;上面的脚本包含了几个您可以自定义的参数，例如ActiveX控件的高度和宽度（您可以使用百分比作为参数），包含WPF/E内容的XAML文件的文件名，和一个表示控件是否无窗的参数。&lt;/li&gt;&lt;/ul&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;&lt;a name="createcontent"&gt;&lt;/a&gt;
&lt;p style="font-size: 14pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;第三步：创建一个表示WPF/E内容的文件&lt;/strong&gt;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;现在您的HTML文件已经配置完毕了，是时候该创建内容了。&lt;/p&gt;
&lt;ul type="a"&gt;
&lt;li class="WpfeQS"&gt;在您HTML文件所在目录里创建一个空文件，命名为&amp;#8220;myxaml.xaml&amp;#8221;。如果您改变了上一步所使用的文件名参数，那么在这里也需要相应地进行改变。 
&lt;li class="WpfeQS"&gt;（可选）如果您的WPF/E工程需要包含脚本，创建一个包含脚本的JavaScript文件，并将下面一行代码添加到您的HTML文件中，添加您在第一步创建的&amp;lt;script&amp;gt;&amp;lt;/script&amp;gt;标签之后。&lt;pre class="code"&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;"my-script.js"&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;script&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;&lt;a name="additionalcontent"&gt;&lt;/a&gt;
&lt;p style="font-size: 14pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;添加额外的WPF/E内容&lt;/strong&gt;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;如果您需要在页面上创建其它的WPF/E ActiveX控件，请重复第二步和第三步，并保证每一个ActiveX控件都有唯一的名字。&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;&lt;a name="sampleproject"&gt;&lt;/a&gt;
&lt;p style="font-size: 14pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;一个示例工程&lt;/strong&gt;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;如果您遇到了困难，或者仅仅是想知道一个简单的WPF/E工程是怎么样的，请将以下这些文件复制到您的机器中，并且打开SampleProject.html文件。&lt;/p&gt;
&lt;ul&gt;
&lt;li class="WpfeQS"&gt;&lt;a href="http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/SampleProject.html" target="_blank"&gt;SampleProject.html&lt;/a&gt; 
&lt;li class="WpfeQS"&gt;&lt;a href="#setupaghost"&gt;&lt;/a&gt;&lt;a href="http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/SampleProject.xaml" target="_blank"&gt;SampleProject.xaml&lt;/a&gt; 
&lt;li class="WpfeQS"&gt;&lt;a href="#createcontrol"&gt;&lt;/a&gt;&lt;a href="http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/SampleProject.js" target="_blank"&gt;SampleProject.js&lt;/a&gt; 
&lt;li class="WpfeQS"&gt;&lt;a href="#"&gt;&lt;/a&gt;&lt;a href="http://downloads.cnblogs.com/thcjp/JeffreyZhao/WpfeQuickStart/samples/aghost.js" target="_blank"&gt;aghost.js&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;&lt;a name="whatsnext"&gt;&lt;/a&gt;
&lt;p style="font-size: 14pt; color: #888888; font-family: verdana"&gt;&lt;strong&gt;下面该做什么呢？&lt;/strong&gt;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;在下一部分&amp;#8220;&lt;a href="http://blog.zhaojie.me/2006/12/wpfe-ctp-quick-start-part-2.html"&gt;创建一个XAML文件&lt;/a&gt;&amp;#8221;中，我们将学习应该如何为您的XAML文件添加内容。&lt;/p&gt;</description>
      <comments>http://blog.zhaojie.me/2006/12/wpfe-ctp-quick-start-part-1.html#comments</comments>
      <pubDate>Wed, 06 Dec 2006 16:46:00 GMT</pubDate>
      <lastBuildDate>Wed, 06 Dec 2006 16:46:00 GMT</lastBuildDate>
    </item>
    <item>
      <author>jeffz@live.com (老赵)</author>
      <category domain="http://blog.zhaojie.me/speech/">培训演讲</category>
      <category domain="http://blog.zhaojie.me/translation/">翻译引进</category>
      <category domain="http://blog.zhaojie.me/practice/">实践优化</category>
      <category domain="http://blog.zhaojie.me/asp-net/">ASP.NET</category>
      <category domain="http://blog.zhaojie.me/front-end/">前端表现</category>
      <title>讲座展示：TechEd Europe DEV 411 - AJAX Patterns with ASP.NET AJAX（1）</title>
      <link>http://blog.zhaojie.me/2006/12/lecture--teched-europe-dev411-1.html</link>
      <guid>http://blog.zhaojie.me/2006/12/lecture--teched-europe-dev411-1.html</guid>
      <description>&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;这次我选择的讲座内容，是最近在TechEd 2006 Europe中Andre Snanbria和Jeff Prosise的讲座&amp;#8220;AJAX Pattern with ASP.NET AJAX&amp;#8221;。Jeff Prosise是Wintellect的Co-Founder，Andre Sanabria是ASP.NET AJAX Team的Lead Program Manager。在MSDN's Showtime上已经有了&lt;a href="http://www.microsoft.com/emea/msdnshowtime/sessionh.aspx?videoid=331" target=_blank&gt;这个讲座的完整视频&lt;/a&gt;，而我在早些时候给Andre Sanabria写了封Email，一星期后他给我寄来了这个讲座的PPT和Demo，大家可以&lt;a href="http://files.cnblogs.com/JeffreyZhao/TechEd_DEV411.zip" target=_blank&gt;点击这里&lt;/a&gt;下载。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;这次讲座的主要内容是讲述了使用ASP.NET AJAX开发AJAX应用的最佳实践，在这次讲座里，会对建立轻量级的客户端控件的方法进行深入，讲述了如何优化脚本代码，并提出了如何避免AJAX开发中常见的问题。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;本篇文章是这次讲座展示的第一篇，讲述了这次讲座的内容概要，并浏览了第一个示例的各个功能。&lt;/p&gt;
&lt;p style="FONT-SIZE: 14pt; FONT-FAMILY: verdana"&gt;&lt;strong&gt;讲座内容&lt;/strong&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;（老赵：在下面的内容里，我将使用&amp;#8220;&lt;strong&gt;Jeff：&lt;/strong&gt;&amp;#8221;来表示Jeff Prosise的话，使用&amp;#8220;&lt;strong&gt;Andre：&lt;/strong&gt;&amp;#8221;来表示Andre Snanbria的话。）&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;a href="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV411AJAXPatternsw.NETAJAX1_AE7D/DEV411_1%5B1%5D.jpg" atomicselection="true"&gt;&lt;img style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height=180 src="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV411AJAXPatternsw.NETAJAX1_AE7D/DEV411_1.jpg" width=240 border=0&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;strong&gt;Jeff：&lt;/strong&gt;我们现在在这里有些激动人心的东西将会展现给你。在这之前我先说一下，可能大家原本在这里想见到&lt;a href="http://www.nikhilk.net/" target=_blank&gt;Nikhil Kothari&lt;/a&gt;（老赵：Nikhil是ASP.NET的架构师，业界非常著名的专家，相信大家多多少少都会读过他的书或文章），不过我不是Nikhil Kothari，我是Jeff Prosise。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;strong&gt;Andre：&lt;/strong&gt;我也不是Nikhil Kothari，我是Andre Snanbria。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;strong&gt;Jeff：&lt;/strong&gt;Andre是ASP.NET AJAX Team的Program Manager——事实上是Lead Program Manager之一，我是来帮他提水的（Andre笑），我在这里只是帮助他展示和搭建很多优秀的玩意儿。不幸的是，Nikhil在这次会议开始之前得了很严重的病，他虽然很想来参加这次会议，但是他的医生根本不允许他上飞机。然而，这个部分是这次我们最重要的内容之一，我们非常希望将这次的内容告诉大家，因此由Andre和我来作这次演讲。这些都是非常优秀的内容，那么我们先来快速地看一下我们这次会讲得内容。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;a href="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV411AJAXPatternsw.NETAJAX1_AE7D/DEV411_2%5B1%5D.jpg" atomicselection="true"&gt;&lt;img style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height=180 src="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV411AJAXPatternsw.NETAJAX1_AE7D/DEV411_2.jpg" width=240 border=0&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;strong&gt;Jeff：&lt;/strong&gt;你们一定已经发现了在这次会议周围停着许多车，尤其是关于Web开发——讲解ASP.NET AJAX的会议。你们一定也已经听说过了ASP.NET AJAX，它是ASP.NET平台上又一个非常优秀的产品，因为它提供了一个框架，能够展现AJAX神奇的一面。我们能够完全通过ASP.NET来开发AJAX站点。如果您已经听过今天在这之前的讲座，您会知道ASP.NET AJAX分为两部分：它有着与ASP.NET紧密结合的服务器部分，也有与服务器端无关的客户端脚本。因此您完全可以将它与其它的服务器技术一起使用，例如PHP或CodeFusion。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;strong&gt;Jeff：&lt;/strong&gt;这个星期有过几次关于ASP.NET AJAX的讲座，我们已经展示了它魔术般的非常酷的特性，例如UpdatePanel或者客户端访问Web Service等等。不过我们想，也应该带给大家一些有关&amp;#8220;最佳实践&amp;#8221;的内容，有关您应该使用的模式，有关如何不仅仅是使用ASP.NET AJAX，而是尽可能地挖掘它，更有效地使用它。例如，不知道您是否了解UpdatePanel的神奇之处？如果您在页面上放置几个UpdatePanel，然后关注在这些AJAX功能背后客户端和服务器端是如何交换数据的话，您可能就会不那么兴奋了。虽然UpdatePanel是一个神奇的控件，它有自己的过人之处，但是它在使用时并不是那么的高效，在服务器端的性能也不是那么高，我们不能只关注于与它能够轻易使用AJAX魔法这个特点。今天我们会讲的话题之一，就是如何合理地使用，并且如何比您现在更加高效地使用UpdatePanel。我们也会谈一下您是如何使用ASP.NET AJAX从客户端访问服务器端Web Services的，您可能已经知道这些内容，因为它在这周别的讲座中也被提到过。然后，我们不如换个角度去看这个问题，我们要部分刷新的话，我们首先会想到UpdatePanel，我们也能够通过Web Services的异步访问然后进行页面的部分刷新，而且这样您可以得到远比使用UpdatePane要高的性能。我们已经准备了几个合适的场景来观察这个问题。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;strong&gt;Jeff：&lt;/strong&gt;还有一个我们要解决的问题就是，大家一直提到的&amp;#8220;后退&amp;#8221;按钮，大家经常会问&amp;#8220;那么后退按钮该怎么办&amp;#8221;？&amp;#8220;后退按钮&amp;#8221;的问题从AJAX诞生不久就出现了，不是吗？我们在这里会展示一个解决它的办法，我们会向你们展示一个小小的控件，当然我们也提供了它所有的源代码，您可以使用这个控件，修改它的一些代码。这个控件能够把我们的逻辑视图和浏览器的&amp;#8220;历史&amp;#8221;结合在一起或者说进行交互，因此当用户点击后退按钮时，会自动向服务器端异步地请求数据，我们能够根据这些信息提供对应的逻辑视图，因此&amp;#8220;后退&amp;#8221;和&amp;#8220;前进&amp;#8221;按钮就能够工作了！它甚至也解决了AJAX的书签（Bookmark）问题。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;strong&gt;Jeff：&lt;/strong&gt;我们也会谈论一些有趣的有关ASP.NET AJAX有趣的话题。例如您是否知道，当你在页面里放置了一个UpdatePanel之后，在客户端会有个对象——PageRequestManager——来管理客户端与服务器端的交互，同时这个PageRequestManager会触发一系列的事件，它构成了客户端页面的一个生命周期。我们如果响应其中的一些事件，就能够增强UpdatePanel部分刷新的特性，这是使用别的方法很难实现的功能。我们也会向大家展示一些别的内容，例如不仅仅是使用ASP.NET AJAX，还有如何将它用的更好。我们希望在使用ASP.NET AJAX时尽可能的高效，所以我们也会谈论一些&amp;#8220;最佳实践&amp;#8221;。Andre，是吗？&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;strong&gt;Andre：&lt;/strong&gt;没错。我们准备在演示中展示很多很棒的东西，这次我们会有许许多多的演示。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;a href="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV411AJAXPatternsw.NETAJAX1_AE7D/DEV411_3%5B1%5D.jpg" atomicselection="true"&gt;&lt;img style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height=180 src="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV411AJAXPatternsw.NETAJAX1_AE7D/DEV411_3.jpg" width=240 border=0&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;strong&gt;Jeff：&lt;/strong&gt;这就是我们下面要讲的内容的一个快速预览，我刚才已经说了很多相关的内容了。现在我们要做的就是看一下我们下面这个示例，Andre要为你们展示一个照片浏览的应用程序，它用了很多ASP.NET AJAX里很酷的玩意儿。不过更重要的是，它展示了一些我们正在讲述的最佳实践和模式。他首先会带你们把这个应用程序浏览一遍，从外部看看这个应用到底是什么样的。当您熟悉了这个应用之后，我们将仔细观察这个页面的某些特定的部分，看看我们是如何做到这些的，我们为什么使用这个方式来实现。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;a href="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV411AJAXPatternsw.NETAJAX1_AE7D/DEV411_4%5B1%5D.jpg" atomicselection="true"&gt;&lt;img style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height=180 src="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV411AJAXPatternsw.NETAJAX1_AE7D/DEV411_4.jpg" width=240 border=0&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;strong&gt;Andre：&lt;/strong&gt;Nikhil和我谈到事情之一，就是他要展示现在AJAX技术非常酷的一面。这是个网站——如果你们认识Nikhil的话，会知道他非常喜爱漂亮的图片，这里是它在前几个月在他进行AJAX讲座时所到过的地方拍摄下来的照片。现在我会先将这个站点浏览一遍，看看我们是如何在这个应用中使用AJAX技术的。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;
&lt;table cellSpacing=5&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;a href="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV411AJAXPatternsw.NETAJAX1_AE7D/DEV411_5%5B9%5D.jpg" atomicselection="true"&gt;&lt;img style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height=173 src="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV411AJAXPatternsw.NETAJAX1_AE7D/DEV411_5_thumb%5B5%5D.jpg" width=200 border=0&gt;&lt;/a&gt; &lt;/td&gt;
            &lt;td&gt;&lt;a href="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV411AJAXPatternsw.NETAJAX1_AE7D/DEV411_6%5B5%5D.jpg" atomicselection="true"&gt;&lt;img style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height=173 src="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV411AJAXPatternsw.NETAJAX1_AE7D/DEV411_6_thumb%5B1%5D.jpg" width=200 border=0&gt;&lt;/a&gt; &lt;/td&gt;
            &lt;td&gt;&lt;a href="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV411AJAXPatternsw.NETAJAX1_AE7D/DEV411_7%5B5%5D.jpg" atomicselection="true"&gt;&lt;img style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height=173 src="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV411AJAXPatternsw.NETAJAX1_AE7D/DEV411_7_thumb%5B1%5D.jpg" width=200 border=0&gt;&lt;/a&gt; &lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;strong&gt;Andre：&lt;/strong&gt;首先，这里非常酷的一点是，我们把鼠标移到缩略图上，可以发现有一副图片预览出现在缩略图的上方（上图左一）。而当我们点击这幅图片时，我们可以看到会有动画效果表示图片正在加载（上图左二），最后图片会以淡入的方式显示出来（上图左三）。这些都使用了AJAX。当我在图片之间切换时都回产生这些效果。从这个场景的角度来说，最重要的功能是使用了UpdatePanel和UpdateProgess帮助您省去了许多工作。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;a href="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV411AJAXPatternsw.NETAJAX1_AE7D/DEV411_8%5B1%5D.jpg" atomicselection="true"&gt;&lt;img style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height=208 src="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV411AJAXPatternsw.NETAJAX1_AE7D/DEV411_8.jpg" width=240 border=0&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;strong&gt;Andre：&lt;/strong&gt;在选中图片的右边有一个照相机（上图），点击它会出现当前图片的详细信息。从这个场景的角度来说，我们在点击这个照相机之后，发送了一个Web Service请求去获取数据，并且在获得这些数据之后简单地使用window.alert显示信息。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;
&lt;table cellSpacing=5&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;a href="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV411AJAXPatternsw.NETAJAX1_AE7D/DEV411_9%5B1%5D.jpg" atomicselection="true"&gt;&lt;img style="BORDER-RIGHT: 0px; BORDER-TOP: 0px; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px" height=208 src="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV411AJAXPatternsw.NETAJAX1_AE7D/DEV411_9.jpg" width=240 border=0&gt;&lt;/a&gt; &lt;/td&gt;
            &lt;td&gt;&lt;a href="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV411AJAXPatternsw.NETAJAX1_AE7D/DEV411_10%5B1%5D.jpg" atomicselection="true"&gt;&lt;img style="BORDER-RIGHT: 0px; BORDER-TOP: 0px; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px" height=208 src="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV411AJAXPatternsw.NETAJAX1_AE7D/DEV411_10.jpg" width=240 border=0&gt;&lt;/a&gt; &lt;/td&gt;
        &lt;/tr&gt;
        &lt;tbody&gt;
        &lt;/tbody&gt;
    &lt;/table&gt;
    &lt;/p&gt;
    &lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;strong&gt;Andre：&lt;/strong&gt;下面要展示的是站点的另一部分功能，在这里我们能够点击右上角的按钮来回切换UI（如上图），所有这些都是完全在客户端进行的。这里用来了一个一会儿我们谈到的概念：&amp;#8220;Behavior&amp;#8221;。我们所做的就是简单地改变页面的颜色，改变客户端的属性。另外可以发现，当我关掉这个浏览器并重新打开这个页面之后，页面会自动识别，并且将页面很快的切换到刚才的颜色（老赵：大家可以从Demo中自己感受一下，其实Nikhil的Blog也有这个功能）。从技术角度来说，我们是将页面的颜色信息使用某种方式保存在客户端，而不是服务器端，这也是我们在这里使用AJAX的方式。&lt;/p&gt;
    &lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;a href="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV411AJAXPatternsw.NETAJAX1_AE7D/DEV411_11%5B1%5D.jpg" atomicselection="true"&gt;&lt;img style="BORDER-RIGHT: 0px; BORDER-TOP: 0px; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px" height=208 src="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV411AJAXPatternsw.NETAJAX1_AE7D/DEV411_11.jpg" width=240 border=0&gt;&lt;/a&gt; &lt;/p&gt;
    &lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;strong&gt;Andre：&lt;/strong&gt;在前几天晚上我和Nikhil进行了一段谈话，我们可以在这里尝试着回复一段内容。Nikhil的Blog有一个功能，在发文时能够阻止发送带有大量URL的内容，以避免有人发布垃圾广告。当我们&amp;#8220;企图&amp;#8221;发布带有大量URL的信息之后，会出现一个提示&amp;#8220;This comment appeared to contain spam&amp;#8221;（如上图）。这里我们使用到了一个服务器端异步验证的技术，它发送一个Web Service访问用来验证这段文本是否合法，然后才将信息发送到服务器端进行更新。&lt;/p&gt;
    &lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;a href="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV411AJAXPatternsw.NETAJAX1_AE7D/DEV411_12%5B1%5D.jpg" atomicselection="true"&gt;&lt;img style="BORDER-RIGHT: 0px; BORDER-TOP: 0px; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px" height=208 src="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV411AJAXPatternsw.NETAJAX1_AE7D/DEV411_12.jpg" width=240 border=0&gt;&lt;/a&gt; &lt;/p&gt;
    &lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;strong&gt;Andre：&lt;/strong&gt;这里还有一个功能，当我把鼠标移到大图片上的时候，大图片顶部会显示出这幅图片的名字等信息（如上图），这也是AJAX技术强大的体现。这就是我们展示的例子，下面会将这个应用分成各个小部分，逐一完成，让大家知道我们是如何做到这些的。&lt;/p&gt;
    &lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;iframe style="DISPLAY: none; VISIBILITY: hidden" src="http://blog.zhaojie.me/2006/12/581642.html" width=0 height=0&gt;&lt;/iframe&gt;&lt;/p&gt;
    &lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;（未完待续）&lt;/p&gt;</description>
      <comments>http://blog.zhaojie.me/2006/12/lecture--teched-europe-dev411-1.html#comments</comments>
      <pubDate>Mon, 04 Dec 2006 12:07:00 GMT</pubDate>
      <lastBuildDate>Mon, 04 Dec 2006 12:07:00 GMT</lastBuildDate>
    </item>
    <item>
      <author>jeffz@live.com (老赵)</author>
      <category domain="http://blog.zhaojie.me/translation/">翻译引进</category>
      <category domain="http://blog.zhaojie.me/front-end/">前端表现</category>
      <title>文章推荐：ASP.NET AJAX Under the Hood Secrets及其他</title>
      <link>http://blog.zhaojie.me/2006/12/article-suggestion--aspnet-ajax-under-the-hood-secrets-and-others.html</link>
      <guid>http://blog.zhaojie.me/2006/12/article-suggestion--aspnet-ajax-under-the-hood-secrets-and-others.html</guid>
      <description>&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;虽然平时也经常阅读网上的各种资料，但是却始终不太有推荐文章的习惯。不过这次，可能因为受到了&lt;a href="http://dflying.cnblogs.com/" target=_blank&gt;Dflying Chen&lt;/a&gt;和&lt;a href="http://cathsfz.cnblogs.com/" target=_blank&gt;Cat Chen&lt;/a&gt;两位的影响，也可能是因为这篇文章受到了ASP.NET之父&lt;a href="http://weblogs.asp.net/scottgu/default.aspx" target=_blank&gt;Scott Guthrie&lt;/a&gt;的钦点，于是我也有了向大家推荐这篇文章的兴致，还有冲动。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;ScottGu今天在他的Blog上发了&lt;a href="http://weblogs.asp.net/scottgu/archive/2006/12/03/asp-net-ajax-under-the-hood-secrets-by-pageflakes-com-creator.aspx" target=_blank&gt;一篇新的文章&lt;/a&gt;，提到了PageFlakes.com网站，以及它的核心架构师&lt;a href="http://msmvps.com/blogs/omar/Default.aspx" target=_blank&gt;Omar Al Zabir&lt;/a&gt;。当然最重要的还是Omar的文章：《&lt;a href="http://www.codeproject.com/Ajax/aspnetajaxtips.asp" target=_blank&gt;ASP.NET AJAX Under the Hood Secrets&lt;/a&gt;》，虽然可能一些已经深入了解ASP.NET AJAX以及Web开发的朋友们会对这篇文章里提到的内容已经比较多的了解，但是我想对于大多数的朋友来说，这篇文章会给我们的ASP.NET AJAX使用，以及Web开发带来一些启示。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;这片文章主要关注于ASP.NET AJAX中经常会使用到，却不太被人关注的一些功能细节，以及需要避免的一些问题。例如&amp;#8220;Batch calls are not always faster&amp;#8221;等，也提到了浏览器的一些特性以及限制，例如&amp;#8220;Browsers do not respond when more than two calls are in queue&amp;#8221;，可以说这些都是开发ASP.NET AJAX乃至Web开发所必需了解的内容。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;文章中也提到了一些ASP.NET AJAX在使用时的一些技巧，例如在Web Service访问时利用Cache来提高效率，而且这可不是像之前CTP的官方文档上提到的简单方法那样&amp;#8220;普通&amp;#8221;，它是个真正经过挖掘与实践之后得到的结论。其余部分的也提到了客户端Function.createDelegate方法的使用（这个方法我一直很喜欢，呵呵），以及在访问Web Services时HTTP GET与HTTP POST直接的对比。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;这篇文章的确是一篇有关ASP.NET AJAX技术不多得的佳作。以下是它的内容提纲：&lt;/p&gt;
&lt;ol&gt;
    &lt;li&gt;
    &lt;div style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;Introduction&lt;/div&gt;
    &lt;li&gt;
    &lt;div style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;Why use ASP.NET AJAX&lt;/div&gt;
    &lt;li&gt;
    &lt;div style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;Batch calls are not always faster&lt;/div&gt;
    &lt;li&gt;
    &lt;div style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;Bad calls make good calls timeout&lt;/div&gt;
    &lt;li&gt;
    &lt;div style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;Browsers allow two calls at a time and don't expect any order&lt;/div&gt;
    &lt;li&gt;
    &lt;div style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;Browsers do not respond when more than two calls are in queue&lt;/div&gt;
    &lt;li&gt;
    &lt;div style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;Caching web service response on the browser and saving bandwidth significantly&lt;/div&gt;
    &lt;li&gt;
    &lt;div style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;When 'this' is not really 'this'&lt;/div&gt;
    &lt;li&gt;
    &lt;div style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;HTTP POST is slower than HTTP GET but it is default in ASP.NET AJAX&lt;/div&gt;
    &lt;li&gt;
    &lt;div style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;Conclusion&lt;/div&gt;
    &lt;/li&gt;
&lt;/ol&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;不过，我产生推荐这篇文章&amp;#8220;冲动&amp;#8221;其实还有别的原因。那就是因为，我很喜欢Omar在文章里的作风。所以我也一并推荐&lt;a href="http://msmvps.com/blogs/omar/" target=_blank&gt;他的Blog&lt;/a&gt;。他的文章很有意思，例如在《How to become a really experienced developer overnight》中，他对于别人的这种&amp;#8220;问题&amp;#8221;的答案是&amp;#8220;Work&amp;nbsp;18 hours per day, 7 days a week, 360 days a year for 13 years&amp;#8221;。嗨，这个很合我的胃口，想做优秀的程序员没有捷径，不下苦功难以成事。还有他在《&lt;a href="http://msmvps.com/blogs/omar/archive/2006/11/04/MVP-Award.aspx" target=_blank&gt;MVP Award&lt;/a&gt;》一文中的那句：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;You say, "Huh, big deal, I can write such simple artlcles everyday". Then read this:&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;a href="http://msdn.microsoft.com/library/en-us/dnwinforms/html/stickout.asp?frame=true" target=_blank&gt;StickOut - .NET 2.0, VSTS, Outlook Addin, MS Word/Excel integration&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;始终认为，作为一个技术人员不能自满，但是一定要有自信，要对于自己的工作体现出一定的&amp;#8220;傲气&amp;#8221;，要对自己的&amp;#8220;产出&amp;#8221;报有信心和热情。这种自信和热情能够让人在这个缤纷变化的IT世界里面能够找到自己的目标，坚持自己的理念。因此我一直不太喜欢看到程序员抱怨自己&amp;#8220;悲惨史&amp;#8221;，或者对于程序员的前途抱有被悲观的命运。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;真的不喜欢，不如化&amp;#8220;抱怨/哀怨&amp;#8221;为&amp;#8220;动力&amp;#8221;，找到目标然后努力。&lt;/p&gt;&lt;iframe style="DISPLAY: none; VISIBILITY: hidden" src="http://blog.zhaojie.me/2006/11/578023.html" width=0 height=0&gt;&lt;/iframe&gt;</description>
      <comments>http://blog.zhaojie.me/2006/12/article-suggestion--aspnet-ajax-under-the-hood-secrets-and-others.html#comments</comments>
      <pubDate>Mon, 04 Dec 2006 06:53:00 GMT</pubDate>
      <lastBuildDate>Mon, 04 Dec 2006 06:53:00 GMT</lastBuildDate>
    </item>
    <item>
      <author>jeffz@live.com (老赵)</author>
      <category domain="http://blog.zhaojie.me/translation/">翻译引进</category>
      <category domain="http://blog.zhaojie.me/practice/">实践优化</category>
      <title>FAQ - 什么是软件工厂？（翻译）</title>
      <link>http://blog.zhaojie.me/2006/11/faq--what-is-software-factory.html</link>
      <guid>http://blog.zhaojie.me/2006/11/faq--what-is-software-factory.html</guid>
      <description>&lt;p style="FONT-SIZE: 14pt; FONT-FAMILY: verdana"&gt;&lt;strong&gt;前言&lt;/strong&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;Microsoft Patterns &amp;amp; Practices已经提供了不少&amp;#8220;软件工厂（Software Factory）&amp;#8221;，例如&lt;a href="http://go.microsoft.com/fwlink/?linkid=63928&amp;amp;clcid=0x409" target=_blank&gt;Smart Client Software Factory&lt;/a&gt;，&lt;a href="http://go.microsoft.com/fwlink/?linkid=67205&amp;amp;clcid=0x409" target=_blank&gt;Web Service Software Factory&lt;/a&gt;和&lt;a href="http://msdn.microsoft.com/mobileclientfactory" target=_blank&gt;Mobile Client Software Factory&lt;/a&gt;。而在CodePlex上也已经有了Microsoft P &amp;amp; P Team正在开发的下一代产品：&lt;a href="http://www.codeplex.com/wiki/view.aspx?projectname=websf" target=_blank&gt;Web Client Software Factory&lt;/a&gt;。这是一个非常有价值，非常值得关注的项目，目前正在以Weekly Drop的形式发布，按照计划将会在年底发布。在&lt;a href="http://terrylee.cnblogs.com/" target=_blank&gt;Terry Lee&lt;/a&gt;和我都曾经对它进行过介绍。&lt;iframe style="DISPLAY: none; VISIBILITY: hidden" src="http://blog.zhaojie.me/2006/11/566402.html" width=0 height=0&gt;&lt;/iframe&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;那么什么是&amp;#8220;软件工厂&amp;#8221;呢？它的作用又是什么呢？&lt;a href="http://blogs.msdn.com/jezzsa/default.aspx" target=_blank&gt;Jezz Santos&lt;/a&gt;在写了数篇有关这方面非常精彩的文章，他本人已经同意我将其文章进行翻译。我将陆续将它们翻译成中文，帮助大家和我自己理解一些概念。&lt;br&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE: 14pt; FONT-FAMILY: verdana"&gt;&lt;strong&gt;原文信息&lt;/strong&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;原文《&lt;a href="http://blogs.msdn.com/jezzsa/archive/2006/11/03/q-a-what-is-a-software-factory.aspx" target=_blank&gt;FAQ - What is a Software Factory?&lt;/a&gt;》公布在&lt;a href="http://blogs.msdn.com/jezzsa/default.aspx" target=_blank&gt;Jezz Santos&lt;/a&gt;的博客上，版权归作者所有。&lt;br&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="FONT-SIZE: 14pt; FONT-FAMILY: verdana"&gt;&lt;strong&gt;正文翻译&lt;/strong&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;什么是&amp;#8220;软件工厂&amp;#8221;？这个问题经常能够引发下面的疑问：&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;strong&gt;如何给出软件工厂的定义？&lt;/strong&gt;紧接着考虑下面的问题：&lt;strong&gt;我创建了一个命令行程序/一个指导性的包（Package）/一段脚本用于生成一些有用的组件&lt;/strong&gt; - 请您作出选择，它们也是软件工厂吗？&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;想用三言两语就给出清楚定义还真不是一件容易的事情。&lt;/p&gt;
&lt;p style="FONT-SIZE: 11pt; FONT-FAMILY: verdana"&gt;&lt;strong&gt;背景&lt;/strong&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;事实上这并不是个足够完整的问题，大多数人也正有这样的疑问，而且他们正在通过一些已经做好的东西或者重新去理解它们的区别，来设法搞清楚自己是否已经有了一个&amp;#8220;工厂&amp;#8221;或者&amp;#8220;工厂&amp;#8221;对他们来说还是个新事物。&lt;/p&gt;
&lt;p style="FONT-SIZE: 11pt; FONT-FAMILY: verdana"&gt;&lt;strong&gt;解答&lt;/strong&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;让我们先从&amp;#8220;软件工厂&amp;#8221;的官方定义开始谈起，然后我会尝试着使用更简单的词汇来解释它，并且使用一些示例来给出这些定义的衍生，希望能帮助您理解这些。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;您能在&lt;a href="http://msdn.microsoft.com/vstudio/teamsystem/workshop/sf/whatis.aspx" target=_blank&gt;这里&lt;/a&gt;找到一个官方而泛泛的定义，但是我想从&lt;a href="http://blogs.msdn.com/jackgr" target=_blank&gt;Jack&lt;/a&gt;和&lt;a href="http://blogs.msdn.com/keith_short" target=_blank&gt;Keth&lt;/a&gt;的那本有关&lt;a href="http://www.amazon.com/exec/obidos/tg/detail/-/0471202843/qid=1081956906/sr=1-1/ref=sr_1_1/104-7563553-2887105?v=glance%26amp;s=books" target=_blank&gt;软件工厂的书&lt;/a&gt;中所使用的那段短小些的定义开始。您也能够在&lt;a href="http://jeffreyzhao.cnblogs.com/"&gt;我们的术语表&lt;/a&gt;中找到另一些定义。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&amp;#8220;&lt;strong&gt;软件工厂&lt;/strong&gt;是使用一个基于软件工厂模式（Software Factory Schema）的软件工厂模版（Software Factory Template）来配置外部工具，过程和内容的一条产品线。通过适配（Adapting），装配（Assembling）和配置一些框架化的组件，能够自动化地对一个典型架构的产品进行开发和维护变化的工作。&amp;#8221;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;呃&amp;#8230;&amp;#8230;好吧（&amp;#8220;咕嘟&amp;#8221;——咽了一下口水），这是一个学院派定义，我们来将它进行一点小小的延伸：首先，&amp;#8220;软件工厂&amp;#8221;的基本元素是一条使用一系列的工具（比如编辑器，代码模版，领域专用语言，命令行工具等等）创建出来的&amp;#8220;产品线&amp;#8221;。这些工具会是用一个被称为&amp;#8220;工厂模版&amp;#8221;的东西来配置普遍适用的，能够扩展的开发工具（就像Visual Studio）。工厂模版实际上只是&amp;#8220;工厂规范&amp;#8221;的一个物理实现（例如，一个工厂模版包含了工具，指导和这些工具创建和配置一些东西的蓝本）。接着，则会通过组装一些必须的组件，把这些工厂创建出来的不同产品的开发和维护过程进行自动化操作——理想情况下，这个过程会复用那些作为产品基础而存在的框架。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&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;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&amp;#8220;框架&amp;#8221;也是非常重要的东西，因为有了它，您就已经在&amp;#8220;为产品线上的产品定义变量&amp;#8221;这个过程中迈出了一大步，大多数的工作它已经帮你完成了。请记住，您不应该为一个您还没有解决的方案创建一个工厂，因此，创建一个工厂最基本的前提是：您已经有了对一些解决方案进行自动化操作的资本。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;strong&gt;&lt;em&gt;［当Visual Studio团队发布了一些能够帮助您自定义软件工厂的工具，那么微软对于这些术语的定义会变得更为具体，而且我猜想，如果要完全符合这个具体的工厂模版，您只能使用被微软认可的软件工厂。但是就目前来说，您任何可以使用当前的工具和一些您自己的&amp;#8220;创新&amp;#8221;来创建符合上述定义的软件工厂。］&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;strong&gt;&lt;u&gt;产品&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;让我们先从&lt;strong&gt;产品&lt;/strong&gt;谈起，首先搞清楚一点：一个产品是一个特定的工厂创建的产物。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&amp;#8220;一个&lt;strong&gt;产品&lt;/strong&gt;是一个工厂&lt;u&gt;生产线&lt;/u&gt;的最终产物&amp;#8221;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;千万不要将&amp;#8220;生产线（production line）&amp;#8221;和&amp;#8220;产品线（product line）&amp;#8221;混淆起来。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;现在，一个产品并不需要真正的完成，结束，包装成一个像&amp;#8220;Microsoft Word&amp;#8221;这样的东西，虽然可能大多数人听到&amp;#8220;产品&amp;#8221;这个词的第一反应是这个。这个单词的含义只是描述一个工厂的产出。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;例如，一个汽车引擎制造商生产出了汽车引擎，这就是它的&amp;#8220;产品&amp;#8221;，然后把引擎卖给其它的工厂，让它们将这些引擎组装进一辆汽车。一个汽车引擎依旧属于一个引擎工厂的&amp;#8220;产品&amp;#8221;。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;所以，所有的工厂会建造一个有用的产品，这个产品可能会被组装进入一个更大的产品，当然也有可能不会。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;工厂会为这个产品定义一个模型，这就是这个产品的&amp;#8220;模式（schema）&amp;#8221;，它包含了产品的各个部分和它们的变量。这个模型为用户提供了一个独立创建，配置或者维护产品各部分的方法。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;strong&gt;&lt;u&gt;工厂模式（Factory Schema）与工厂模版（Factory Template）&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;我们已经花了不少功夫定义了&lt;a href="http://jeffreyzhao.cnblogs.com/" target=_blank&gt;工厂模式（Factory Schema）&lt;/a&gt;，所以我不打算在这里再完全重复一遍。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;不过我们在这里这么说已经足够了：&amp;#8220;工厂模式&amp;#8221;是产品（和它的变量）以及它的各种配置的蓝图——也就是工厂产物的蓝图。它不只定义了工厂该建造那些东西，也包括建造这些东西方式，建造时所用的&amp;#8220;零件&amp;#8221;，以及在建造时所使用的工具。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;顺便提一下，&amp;#8220;&lt;a href="http://jeffreyzhao.cnblogs.com/" target=_blank&gt;工厂模版（Factory Template）&lt;/a&gt;&amp;#8221;则是指工具、运行时、文档和框架等其它作为您的工厂的的组成部分一起发布的那些东西——例如一起打包在一个MSI安装文件中。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;strong&gt;&lt;u&gt;产品线&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;那么现在就谈一下&lt;strong&gt;产品线&lt;/strong&gt;——这到底是什么？这可不是指&amp;#8220;生产线&amp;#8221;。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;strong&gt;产品线&lt;/strong&gt;，由工厂产物的&lt;strong&gt;变量&lt;/strong&gt;组成。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;好，为了真正对开发有用，工厂需要能够创建产品的多个实例（我们把其中的一个叫做一个&amp;#8220;产品变量&amp;#8221;）。更准确的说，一个产品&amp;#8220;变量&amp;#8221;就是每一个您生产出的&lt;u&gt;实例&lt;/u&gt;，而不是产品的实际&lt;u&gt;类型&lt;/u&gt;。一个工厂能够定义多种产品的&amp;#8220;类型&amp;#8221;（每一个对应了产品的一个可变的方面）。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;因此，您的产品线定义了您工厂的&lt;strong&gt;解决方案领域&lt;/strong&gt;。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;em&gt;［您能够在&lt;/em&gt;&lt;a href="http://jeffreyzhao.cnblogs.com/" target=_blank&gt;&lt;em&gt;这里&lt;/em&gt;&lt;/a&gt;&lt;em&gt;得到有关一个产品可变性以及其变量（是什么？应该如何使用？）更深入的讨论。］&lt;/em&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;那么，您的&lt;strong&gt;一个命令行程序/一个指导性的包（Package）/一段脚本&lt;/strong&gt;是一个软件工厂吗？&lt;/p&gt;</description>
      <comments>http://blog.zhaojie.me/2006/11/faq--what-is-software-factory.html#comments</comments>
      <pubDate>Fri, 24 Nov 2006 16:03:00 GMT</pubDate>
      <lastBuildDate>Fri, 24 Nov 2006 16:03:00 GMT</lastBuildDate>
    </item>
    <item>
      <author>jeffz@live.com (老赵)</author>
      <category domain="http://blog.zhaojie.me/speech/">培训演讲</category>
      <category domain="http://blog.zhaojie.me/translation/">翻译引进</category>
      <category domain="http://blog.zhaojie.me/asp-net/">ASP.NET</category>
      <category domain="http://blog.zhaojie.me/front-end/">前端表现</category>
      <title>讲座展示：TechEd Europe DEV344 - ASP.NET AJAX Control Toolkit（下）</title>
      <link>http://blog.zhaojie.me/2006/11/lecture-teched-europe-dev344-3.html</link>
      <guid>http://blog.zhaojie.me/2006/11/lecture-teched-europe-dev344-3.html</guid>
      <description>&lt;p style="font-size: 16pt"&gt;&lt;strong&gt;讲座内容&lt;/strong&gt;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;这次我选择的讲座内容是最近在TechEd 2006 Europe中Shawn Burke的讲座&amp;#8220;ASP.NET AJAX Control Toolkit Unleashed: Creating Rich Client-Side Controls and Components&amp;#8221;。Shawn Burke是微软.NET Developer Platform总监。这个讲座的PPT和演示代码的下载地址已经由他本人&lt;a href="http://blogs.msdn.com/sburke/archive/2006/11/07/teched-talk-demos.aspx" target="_blank"&gt;公布在他的Blog上&lt;/a&gt;（&lt;a href="http://files.cnblogs.com/JeffreyZhao/TechEd_Dev344.zip"&gt;本地下载&lt;/a&gt;）。另外，在MSDN's Showtime上也已经有了&lt;a href="http://www.microsoft.com/emea/msdnshowtime/sessionl.aspx?videoid=320" target="_blank"&gt;这个讲座的完整视频&lt;/a&gt;。&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;此次讲座的内容主要是对于ASP.NET AJAX Control Toolkit进行简单的介绍，展示了Extender控件是如何帮助ASP.NET开发人员简单地将丰富的用户体验集成到他们的Web应用程序中。在这次讲座里将看到应该如何在您的应用中使用ASP.NET AJAX Control Toolkit中的组件，并且了解开发人员是如何方便地开发一个APS.NET AJAX Extender的。&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;此次讲座分为两部分：&amp;#8220;ASP.NET AJAX Control Toolkit介绍和使用&amp;#8221;以及&amp;#8220;开发一个Extender控件&amp;#8221;。本文将对于该讲座的第二部分进行讲述，并且对其第二个演示的剩余部分进行分析。&lt;/p&gt;
&lt;p style="FONT-SIZE: 16pt"&gt;&lt;strong&gt;讲座演示&lt;/strong&gt;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;font color="#ff0000"&gt;请注意，在Shawn提供的压缩包内有三个空文件夹：Demo_Base、Demo_Step_2和Demo_Step_3，现在它们在演示时也是有内容的，我已经根据讲座视频设法将它们恢复到了演示时的样子，请&lt;a href="http://files.cnblogs.com/JeffreyZhao/TechEd_Dev344_DemoExt.zip"&gt;点击这里&lt;/a&gt;下载。&lt;/font&gt;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="font-size: 12pt; font-family: verdana"&gt;Step 2：Consuming other behaviors / Handling events / Coding Client-Side Logic&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;我们可以发现，Extender在客户端生成了代码，能够构造Behavior对象，也正确设置了Behavior的属性。在大多数情况下，下面要做就是可能会使用Toolkit中其他一些组件的功能。这也是我们在早期版本Toolkit中的一个挑战：如何才能使各种组件能够组合使用？结合各种组件的功能能够使UI变得更加有趣，我们也能获得更灵活的控制能力。实现这个功能的一个难点就是，这些组件都是JavaScript。每个组件都有自己的JavaScript文件，他们会被编译在程序集中。在使用Extender时，Tookit会知道应该使用哪些JavaScript文件，并将它们引入到页面中。&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;那么我们该如何引入别的Component的JavaScript文件呢？如果确定它们的脚本被正确加载了？在服务器端有一个CustomAttribute：&lt;font color="#ff0000"&gt;RequiredScriptAttribute&lt;/font&gt;。它的作用就是告诉服务器：&amp;#8220;嘿，你们必须在我加载之前加载到页面中&amp;#8221;，这样在客户端就能出现能够正确运行的脚本类库了。在客户端，我们能够使用&lt;font color="#ff0000"&gt;$create&lt;/font&gt;方法创建一个组件。我们一会儿就来看一下应该如何使用。&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;现在我们会使用另外两个组件，它们原本定义在Atlas中，但是在ASP.NET Beta版本中被移除了。不过它们被转移到了开源的Toolkit中，这样开发人员就能继续使用它们了。他们就是HoverExtender和PopupExtender。我们先在客户端Behavor的构造函数中添加这两个组件和一些其它的变量声明。如下：&lt;/p&gt;
&lt;pre class="code"&gt;FontSize.FontSizeBehavior = &lt;span style="color: #0000ff"&gt;function&lt;/span&gt;(element) {
    ...
&lt;span style="color: #008000"&gt;    // the behaviors we create&lt;/span&gt;
&lt;span style="color: #008000"&gt;    //&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;    this&lt;/span&gt;._popupBehavior = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;
&lt;span style="color: #0000ff"&gt;    this&lt;/span&gt;._hoverBehavior = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;
&lt;span style="color: #008000"&gt;    // Handler delegates&lt;/span&gt;
&lt;span style="color: #008000"&gt;    //&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;    this&lt;/span&gt;._hoverHandler = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;
&lt;span style="color: #0000ff"&gt;    this&lt;/span&gt;._unhoverHandler = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;
&lt;span style="color: #0000ff"&gt;    this&lt;/span&gt;._incrementHandler = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;
&lt;span style="color: #0000ff"&gt;    this&lt;/span&gt;._decrementHandler = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;
&lt;span style="color: #008000"&gt;    // state bits&lt;/span&gt;
&lt;span style="color: #008000"&gt;    //&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;    this&lt;/span&gt;._fontSize = 0;
&lt;span style="color: #0000ff"&gt;    this&lt;/span&gt;._popupVisible = &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;;
&lt;span style="color: #0000ff"&gt;    this&lt;/span&gt;._fontUnit = "&lt;span style="color: #8b0000"&gt;px&lt;/span&gt;";
}&lt;/pre&gt; 
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;然后我们需要在Initialize方法中使用这两个Behavior。首先我们使用HoverBehavior，添加如下代码：&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color: #008000"&gt;// setup the hover behavior&lt;/span&gt;
&lt;span style="color: #008000"&gt;//&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._hoverCssClass &amp;amp;&amp;amp; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._sizePanelElement) {
&lt;span style="color: #0000ff"&gt;    this&lt;/span&gt;._hoverHandler = &lt;span style="color: #0000ff"&gt;Function&lt;/span&gt;.createDelegate(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._onTargetHover);
&lt;span style="color: #0000ff"&gt;    this&lt;/span&gt;._unhoverHandler = &lt;span style="color: #0000ff"&gt;Function&lt;/span&gt;.createDelegate(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._onTargetUnhover);
&lt;span style="color: #0000ff"&gt;    this&lt;/span&gt;._hoverBehavior = $create(&lt;br&gt;        AjaxControlToolkit.HoverBehavior,&lt;br&gt;        {unhoverDelay:200, hoverElement: &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._sizePanelElement},&lt;br&gt;        &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.get_element());&lt;br&gt;
&lt;span style="color: #0000ff"&gt;    this&lt;/span&gt;._hoverBehavior.add_hover(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._hoverHandler);
&lt;span style="color: #0000ff"&gt;    this&lt;/span&gt;._hoverBehavior.add_unhover(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._unhoverHandler);
}&lt;/pre&gt; 
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;HoverBehavior的hover事件会在鼠标移到某个元素上被触发，我们可以使用它在UI上显示一个良好的鼠标移进／移出效果。首先我们会建立两个用于触发事件的handler：_hoverHandler和_unhoverHandler。然后使用$create方法创建一个HoverBehavior并且与当前Behavior的元素绑定起来。$create方法会使ASP.NET AJAX跟踪这个对象，例如可以在合适的时候销毁它。在$create的第二个参数中会指定一些属性，unhoverDelay表示鼠标移开在多少毫秒后会触发unhover事件，hoverElement指定了另一个对象，以避免在移动到这个元素后unhover事件被触发。最后一个参数就是Behavior需要绑定的元素，通过get_element方法可以获得当前的元素，比如在使用WatermarkExtender时就会得到那个文本框，这里就是我们希望改变字体大小的Panel。最后将handler注册给hover和unhover事件。&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;接着我们使用PopupBehavior，代码如下：&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color: #008000"&gt;// setup the popup behavior&lt;/span&gt;
&lt;span style="color: #008000"&gt;//&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._sizePanelElement) {
&lt;span style="color: #0000ff"&gt;    this&lt;/span&gt;._popupBehavior = $create(&lt;br&gt;        AjaxControlToolkit.PopupBehavior,
        {id:  &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.get_id() + "&lt;span style="color: #8b0000"&gt;_Popup&lt;/span&gt;", &lt;span style="color: #008000"&gt;// make the ID derive from our ID for uniqueness&lt;/span&gt;
        positioningMode: AjaxControlToolkit.PositioningMode.TopRight,
        parentElement: &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.get_element()},
&lt;span style="color: #0000ff"&gt;        null&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._sizePanelElement);
}&lt;/pre&gt; 
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;PopupBehavior的作用是帮助我们显示和隐藏某个UI。这里的代码和上面的比较相似，我们通过当前的Panel的客户端ID来获得PopupBehavior的ID，这样保证了这个ID的唯一性。positioningMode指定了元素在弹出时相对于parentElement的位置。&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;然后我们增加一些我们需要的Handler。代码如下：&lt;/p&gt;
&lt;pre class="code"&gt;_onTargetHover : &lt;span style="color: #0000ff"&gt;function&lt;/span&gt;(eventArgs) {
&lt;span style="color: #0000ff"&gt;    var&lt;/span&gt; e = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.get_element();
    Sys.UI.DomElement.addCssClass(e, &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._hoverCssClass);
&lt;span style="color: #0000ff"&gt;    if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._popupBehavior &amp;amp;&amp;amp; !&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._popupVisible) {
&lt;span style="color: #0000ff"&gt;        this&lt;/span&gt;._popupVisible = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;;
&lt;span style="color: #008000"&gt;        // call show to make the the popup visible&lt;/span&gt;
&lt;span style="color: #008000"&gt;        //         &lt;/span&gt;
&lt;span style="color: #0000ff"&gt;        this&lt;/span&gt;._popupBehavior.show();
    }
},
_onTargetUnhover : &lt;span style="color: #0000ff"&gt;function&lt;/span&gt;(eventArgs) {
&lt;span style="color: #0000ff"&gt;    var&lt;/span&gt; e = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.get_element();
    Sys.UI.DomElement.removeCssClass(e, &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._hoverCssClass);
&lt;span style="color: #0000ff"&gt;    if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._popupBehavior &amp;amp;&amp;amp; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._popupVisible) {
&lt;span style="color: #0000ff"&gt;        this&lt;/span&gt;._popupVisible = &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;;
&lt;span style="color: #0000ff"&gt;        this&lt;/span&gt;._popupBehavior.hide();
    }
},&lt;/pre&gt; 
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;在Hover事件被触发时，也就是用户将鼠标移动到了Panel上，我们会调用PopupBehavior的show方法，用以显示它的UI。在Unhover事件触发时，则调用hide方法使UI隐藏。&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;我们现在编译代码，然后刷新页面。哎，出错了。如图：&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="172" src="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV344.NETAJAXControlToolkit_93BC/TechEd2006DEV344_13%5B8%5D.jpg" width="410" border="0"&gt; &lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;这里出错的原因是因为HoverBehavior没有定义。因此我会回到Extender的代码，添加RequiredScriptAttribute：&lt;/p&gt;
&lt;pre class="code"&gt;[Designer(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(FontSizeDesigner))]
[ClientScriptResource("&lt;span style="color: #8b0000"&gt;FontSize.FontSizeBehavior&lt;/span&gt;", "&lt;span style="color: #8b0000"&gt;FontSize.FontSizeBehavior.js&lt;/span&gt;")]
[TargetControlType(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(Control))]
[RequiredScript(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(PopupExtender))]
[RequiredScript(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(HoverExtender))]
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; FontSizeExtender : ExtenderControlBase
{
    ...
}&lt;/pre&gt; 
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;在这里我们传入PopupExtender和HoverExtender的类型，这使Toolkit在使用当前Behavior时保证了PopupBehavior和HoverBehavior的脚本已经被加载了。我们重新编译代码，打开页面。没有发现异常。&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;当我们将鼠标移动至上方的Panel时，可以发现含有按钮的Panel显示在了右上角。如图：&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&lt;a href="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV344.NETAJAXControlToolkit_93BC/TechEd2006DEV344_14%5B1%5D.jpg" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="177" src="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV344.NETAJAXControlToolkit_93BC/TechEd2006DEV344_14.jpg" width="240" border="0"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;可以发现，当我们把鼠标移动到右上角的按钮时，它们也不会消失，这个就是HoverBehavior的hoverElement属性的作用。当鼠标移到其它地方时，右上角的按钮就消失了。而PopupBehavior的作用就是显示和隐藏制定的元素。&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;现在我们需要来处理按钮的功能了。我们回到Behavior的代码，首先在initialize方法内添加一些简单的代码。如下：&lt;/p&gt;
&lt;pre class="code"&gt;initialize : &lt;span style="color: #0000ff"&gt;function&lt;/span&gt;() {
    FontSize.FontSizeBehavior.callBaseMethod(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;, 'initialize');
    ...
    
    &lt;span style="color: #008000"&gt;// set up our handlers for the +/- behavior&lt;/span&gt;
    &lt;span style="color: #008000"&gt;//&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._incrementElement) {
        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._incrementHandler = &lt;span style="color: #0000ff"&gt;Function&lt;/span&gt;.createDelegate(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._onIncrementFontSize);
        $addHandler(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._incrementElement, "&lt;span style="color: #8b0000"&gt;click&lt;/span&gt;", &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._incrementHandler);
    }
    
    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._decrementElement) {
        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._decrementHandler = &lt;span style="color: #0000ff"&gt;Function&lt;/span&gt;.createDelegate(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._onDecrementFontSize);
        $addHandler(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._decrementElement, "&lt;span style="color: #8b0000"&gt;click&lt;/span&gt;", &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._decrementHandler);
    }    
},&lt;/pre&gt; 
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;就像我们之前所提到的那样，ASP.NET AJAX为了跨浏览器，提供了一些方法让我们进行统一的操作。在这里，我们使用了$addHandler方法，它为任意浏览器中都提供了相同的注册客户端事件功能。比如我们使用了$addHandler方法为增大字体的按钮注册了click事件。如果您写JavaScript代码的话，使用的是&amp;#8220;onclick&amp;#8221;，请注意这里只是&amp;#8220;click&amp;#8221;，因为ASP.NET AJAX需要在多个浏览器中工作。$addHandler方法的第一个参数则是需要为它添加事件的HTML元素，在这里就是&amp;#8220;增大&amp;#8221;按钮。最后一个则是我们需要注册给click事件的方法。&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;接着我们需要添加一些方法。首先我们在这里要添加的是一个辅助方法_setFontSize，如下：&lt;/p&gt;
&lt;pre class="code"&gt;_setFontSize : &lt;span style="color: #0000ff"&gt;function&lt;/span&gt;(size) {
    &lt;span style="color: #008000"&gt;// helper function for setting the font size&lt;/span&gt;
    &lt;span style="color: #008000"&gt;//&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._fontSize = size;
    
    &lt;span style="color: #008000"&gt;// append the units.&lt;/span&gt;
    &lt;span style="color: #008000"&gt;//&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.get_element().style.fontSize = size + &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._fontUnit;
},&lt;/pre&gt; 
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;由于用户可能以不同的单位来设置字体，例如px或者pt，因此我们提供了_fontUnit。在这里get_element()方法获得了当前Behavior所在的元素，也就是需要改变字体大小的Panel。然后就以最普通不过的方法设置其字体。&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;然后我们再定义增大和减小字体的方法，如下：&lt;/p&gt;
&lt;pre class="code"&gt;_onDecrementFontSize : &lt;span style="color: #0000ff"&gt;function&lt;/span&gt;(eventArgs) {
    &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; fontSize = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._getCurrentFontSize();
    
    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (fontSize &amp;gt; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.get_MinFontSize()) {
        fontSize -= &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._fontSizeIncrement;
    }
    &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._setFontSize(fontSize);
    eventArgs.preventDefault();
},
_onIncrementFontSize : &lt;span style="color: #0000ff"&gt;function&lt;/span&gt;(eventArgs) {
    &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; fontSize = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._getCurrentFontSize();
    
    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (fontSize &amp;lt; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.get_MaxFontSize()) {
        fontSize += &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._fontSizeIncrement;
    }        
    &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._setFontSize(fontSize);
    eventArgs.preventDefault();
},&lt;/pre&gt; 
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;这是两个非常简单的Handler，在点击两个按钮时会调用它们。在这两个方法里，首先使用_getCurrentFontSize方法得到当前的字体大小，然后改变目标元素的字体大小。需要注意的是，我们这里还调用了eventArgs的preventDefault方法。这里又带来了一个跨浏览器的问题。如何在跨浏览器的情况下组织一个事件被继续传播（propagation）？例如我们需要在相应一个Label的click事件后阻止默认的响应方式。在IE您会使用&amp;#8220;return false&amp;#8221;这样的作法，而在FireFox里您则会使用&amp;#8220;e.returnValue = false&amp;#8221;，而使用ASP.NET AJAX话您只需要使用同一种方法。&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;下面则是_getCurrentFontSize方法。这是一个巧妙的方法，可以用来&amp;#8220;测量&amp;#8221;出某个元素当前字体大小，在这里就是当前Panel的文字大小。如下（代码较长，就不完整贴出了，朋友们可以看一下附件里的代码）：&lt;/p&gt;
&lt;pre class="code"&gt;_getCurrentFontSize : &lt;span style="color: #0000ff"&gt;function&lt;/span&gt;() {
    &lt;span style="color: #008000"&gt;// this function figures out the current font size of the element.&lt;/span&gt;
    &lt;span style="color: #008000"&gt;//&lt;/span&gt;
    
    ...    
    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._fontSize;        
},&lt;/pre&gt; 
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;然后就需要为页面上其它的Panel添加相应的UI和Extender了。如下：&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #c71585"&gt;fontSize&lt;/span&gt;:&lt;span style="color: #800000"&gt;FontSizeExtender&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ID&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"FontSizeExtender1"&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;SizePanelControlID&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"extenderUI1"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;TargetControlID&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"pnlLeftColumn"&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;DecreaseSizeControlID&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"btnDec1"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;IncreaseSizeControlID&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"btnInc1"&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;PanelHoverCssClass&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"panelHover"&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: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="color: #800000"&gt;Panel&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ID&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"extenderUI1"&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;CssClass&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"popup"&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: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="color: #800000"&gt;Button&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ID&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"btnDec1"&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;Text&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"-"&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: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="color: #800000"&gt;Button&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ID&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"btnInc1"&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;Text&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"+"&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: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="color: #800000"&gt;Panel&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: #c71585"&gt;fontSize&lt;/span&gt;:&lt;span style="color: #800000"&gt;FontSizeExtender&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ID&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"FontSizeExtender2"&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;SizePanelControlID&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"extenderUI2"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;TargetControlID&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"pnlMiddleColumn"&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;DecreaseSizeControlID&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"btnDec2"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;IncreaseSizeControlID&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"btnInc2"&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;PanelHoverCssClass&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"panelHover"&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: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="color: #800000"&gt;Panel&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ID&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"extenderUI2"&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;CssClass&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"popup"&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: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="color: #800000"&gt;Button&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ID&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"btnDec2"&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;Text&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"-"&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: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="color: #800000"&gt;Button&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ID&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"btnInc2"&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;Text&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"+"&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: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="color: #800000"&gt;Panel&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: #c71585"&gt;fontSize&lt;/span&gt;:&lt;span style="color: #800000"&gt;FontSizeExtender&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ID&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"FontSizeExtender3"&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;SizePanelControlID&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"extenderUI3"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;TargetControlID&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"pnlRightColumn"&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;DecreaseSizeControlID&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"btnDec3"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;IncreaseSizeControlID&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"btnInc3"&lt;/span&gt;
    &lt;span style="color: #ff0000"&gt;PanelHoverCssClass&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"panelHover"&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: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="color: #800000"&gt;Panel&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ID&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"extenderUI3"&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;CssClass&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"popup"&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: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="color: #800000"&gt;Button&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ID&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"btnDec3"&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;Text&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"-"&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: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="color: #800000"&gt;Button&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ID&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"btnInc3"&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;Text&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"+"&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: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="color: #800000"&gt;Panel&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt; 
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;编译，重新打开页面。可以发现，现在点击增大／减小按钮字体已经能够变化了（大家可以打开Demo_Step_3的页面察看一下效果）。可能大家会想一个问题，能不能在Panel之间共享一组控制按钮？在这里是不行的，因为一组按钮会被绑定多个Behavior，在click被触发时也会调用多个事件，这样您会发现所有的Panel字体一起变大或者变小了。所以我们在页面中使用了重复的按钮。&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="font-size: 12pt; font-family: verdana"&gt;Step 3：Saving Client State&amp;nbsp;/ Adding Animation Support&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;可能大家已经发现了，在页面右下方有一个按钮，当我们点击这个按钮时，页面进行了一个PostBack。这里有个问题，页面上字体大小的改变在PostBack之后失效了，我们需要解决这个问题。&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;ASP.NET AJAX Control Toolkit提供了一系列的高级特性，其中一点就是提供了Client State机制可以在服务器端和客户端保存和传递状态。另外就像我之前提到的，Toolkit中提供了一套非常灵活的动画效果。我们来看一下应该如何使用它们。&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;如果要使用Client State机制，在服务器端我们要为Extender添加一个构造函数，将EnableClientState属性设为true。如下：&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; FontSizeExtender() {
    EnableClientState = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;;
}&lt;/pre&gt; 
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;然后需要添加客户端的脚本，您可以直接使用辅助方法，在客户端_setFontSize方法里添加如下代码：&lt;/p&gt;
&lt;pre class="code"&gt;_setFontSize : function(size) {
    &lt;span style="color: #008000"&gt;// helper function for setting the font size&lt;/span&gt;
    ...
    
    &lt;span style="color: #008000"&gt;// set the clientState&lt;/span&gt;
    &lt;span style="color: #008000"&gt;//&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.set_ClientState(size + "&lt;span style="color: #8b0000"&gt;:&lt;/span&gt;" + &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._fontUnit);
},&lt;/pre&gt; 
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;您可以使用set_ClientState方法设置一个字符串，在页面PostBack之后在服务器端就可以得到这个值。更加重要的是，在PostBack之后，服务器段也会重新设置ClientState的值。在这里我们设定ClientState的值为当前的字体大小+冒号+当前使用的单位。&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;当然，我们还必须保证在组件被构造时我们能够重新取回这个值。我们在客户端initialize方法内添加如下代码：&lt;/p&gt;
&lt;pre class="code"&gt;initialize : &lt;span style="color: #0000ff"&gt;function&lt;/span&gt;() {
    FontSize.FontSizeBehavior.callBaseMethod(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;, 'initialize');
    ...
    
    &lt;span style="color: #008000"&gt;// check client state&lt;/span&gt;
    &lt;span style="color: #008000"&gt;//&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; clientState = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.get_ClientState();
    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (clientState) {
        &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; stateItems = clientState.split("&lt;span style="color: #8b0000"&gt;:&lt;/span&gt;");
        
        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (stateItems.&lt;span style="color: #0000ff"&gt;length&lt;/span&gt;) {                
            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._fontUnit = stateItems[1];
            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._setFontSize(&lt;span style="color: #0000ff"&gt;parseInt&lt;/span&gt;(stateItems[0]));
        }
    }
},&lt;/pre&gt; 
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;通过另外一个辅助方法get_ClientState我们可以得到ClientState的值。由于initialize方法会在组件被初始化时被调用，因此组件会在一开始重新获得字体大小和单位等状态。这就是我们在PostBack之间保存字体状态的方法。&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;编译，重新打开页面，点击按钮改变某个Panel的字体大小。再点击下方按钮，可以发现在PostBack之后字体大小被正确恢复了。&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;最后我们来为UI的显示和隐藏添加动画效果，首先修改_onTargetHover方法。如下：&lt;/p&gt;
&lt;pre class="code"&gt;_onTargetHover : &lt;span style="color: #0000ff"&gt;function&lt;/span&gt;(eventArgs) {
    &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; e = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.get_element();
    
    Sys.UI.DomElement.addCssClass(e, &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._hoverCssClass);
    
    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._popupBehavior &amp;amp;&amp;amp; !&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._popupVisible) {
        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._popupVisible = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;;
        
        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._stopAnimations();
        
        &lt;span style="color: #008000"&gt;// call show to make the the popup visible&lt;/span&gt;
        &lt;span style="color: #008000"&gt;//         &lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._popupBehavior.show();
        
        &lt;span style="color: #008000"&gt;// now animate it's opacity&lt;/span&gt;
        &lt;span style="color: #008000"&gt;//&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; anim = $create(
            AjaxControlToolkit.Animation.FadeInAnimation,
            {target: &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._sizePanelElement,
            duration: .25, minimumOpacity: 0, maximumOpacity:.75});
        
        &lt;span style="color: #008000"&gt;// we cache the running animation so we can cancel it if we need to hide.&lt;/span&gt;
        &lt;span style="color: #008000"&gt;//&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._sizePanelElement._runningAnimation = anim;    
         
        &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; handler = &lt;span style="color: #0000ff"&gt;Function&lt;/span&gt;.createDelegate(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;,
            &lt;span style="color: #0000ff"&gt;function&lt;/span&gt;() {
                &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._sizePanelElement._runningAnimation = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;
            });
         
        anim.add_ended(handler);
            
        anim.play();
    }
},&lt;/pre&gt; 
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;动画效果也是组件，也能够通过$create方法创建。同样我们还需要修改_onTargetUnhover方法，如下：&lt;/p&gt;
&lt;pre class="code"&gt;_onTargetUnhover : &lt;span style="color: #0000ff"&gt;function&lt;/span&gt;(eventArgs) {
    &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; e = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.get_element();
    Sys.UI.DomElement.removeCssClass(e, &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._hoverCssClass);
    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._popupBehavior &amp;amp;&amp;amp; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._popupVisible) {
        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._popupVisible = &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;; 
        &lt;span style="color: #008000"&gt;// make sure another animation isn't already running.&lt;/span&gt;
        &lt;span style="color: #008000"&gt;//&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._stopAnimations();
        &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; anim = $create(
            AjaxControlToolkit.Animation.FadeOutAnimation,
            {target: &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._sizePanelElement, duration: .15,
            minimumOpacity: 0, maximumOpacity:.75});
        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._sizePanelElement._runningAnimation = anim;
         
        &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; handler = &lt;span style="color: #0000ff"&gt;Function&lt;/span&gt;.createDelegate(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;,
            &lt;span style="color: #0000ff"&gt;function&lt;/span&gt;() {
                &lt;span style="color: #008000"&gt;// clear out our state.&lt;/span&gt;
                &lt;span style="color: #008000"&gt;//&lt;/span&gt;
                &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._sizePanelElement._runningAnimation = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;
                &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._popupVisible = &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;;
                &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._popupBehavior.hide();
            });
         
        anim.add_ended(handler);
         
        anim.play();
    }
},&lt;/pre&gt; 
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;我们还需要添加一个_stopAnimations方法。如下：&lt;/p&gt;
&lt;pre class="code"&gt;_stopAnimations : function() {
    &lt;span style="color: #008000"&gt;// stop any running animation&lt;/span&gt;
    &lt;span style="color: #008000"&gt;//&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._sizePanelElement &amp;amp;&amp;amp; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._sizePanelElement._runningAnimation) {
        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._sizePanelElement._runningAnimation.stop();
        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._sizePanelElement._runningAnimation = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;
    }   
},&lt;/pre&gt; 
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;自然也别忘了给服务器端的Extender添加所需的CustomAttribute：&lt;/p&gt;
&lt;pre class="code"&gt;[RequiredScript(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(AnimationScripts))]&lt;/pre&gt; 
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;编译，重新打开页面。现在可以看到，页面上的按钮的显示和隐藏就会产生美妙的淡入淡出效果了（大家可以打开页面观察一下效果）。&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;我们现在还在招募志愿的开发人员。我们计划最终会在ASP.NET AJAX Control Tookit中有超过50个组件。最终我们会把这个项目完全交付给社区，这是我们的长期计划。而且随着ASP.NET AJAX的改进，Toolkit也会相应的进步。&lt;/p&gt;
&lt;p style="font-size: 10pt; font-family: verdana"&gt;&amp;nbsp;&lt;/p&gt;</description>
      <comments>http://blog.zhaojie.me/2006/11/lecture-teched-europe-dev344-3.html#comments</comments>
      <pubDate>Sat, 18 Nov 2006 11:18:00 GMT</pubDate>
      <lastBuildDate>Sat, 18 Nov 2006 11:18:00 GMT</lastBuildDate>
    </item>
    <item>
      <author>jeffz@live.com (老赵)</author>
      <category domain="http://blog.zhaojie.me/speech/">培训演讲</category>
      <category domain="http://blog.zhaojie.me/translation/">翻译引进</category>
      <category domain="http://blog.zhaojie.me/asp-net/">ASP.NET</category>
      <category domain="http://blog.zhaojie.me/front-end/">前端表现</category>
      <title>讲座展示：TechEd Europe DEV344 - ASP.NET AJAX Control Toolkit（中）</title>
      <link>http://blog.zhaojie.me/2006/11/lecture-teched-europe-dev344-2.html</link>
      <guid>http://blog.zhaojie.me/2006/11/lecture-teched-europe-dev344-2.html</guid>
      <description>&lt;p style="FONT-SIZE: 16pt"&gt;&lt;strong&gt;讲座内容&lt;/strong&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;这次我选择的讲座内容是最近在TechEd 2006 Europe中Shawn Burke的讲座&amp;#8220;ASP.NET AJAX Control Toolkit Unleashed: Creating Rich Client-Side Controls and Components&amp;#8221;。Shawn Burke是微软.NET Developer Platform总监。这个讲座的PPT和演示代码的下载地址已经由他本人&lt;a href="http://blogs.msdn.com/sburke/archive/2006/11/07/teched-talk-demos.aspx" target=_blank&gt;公布在他的Blog上&lt;/a&gt;（&lt;a href="http://files.cnblogs.com/JeffreyZhao/TechEd_Dev344.zip"&gt;本地下载&lt;/a&gt;）。另外，在MSDN's Showtime上也已经有了&lt;a href="http://www.microsoft.com/emea/msdnshowtime/sessionl.aspx?videoid=320" target=_blank&gt;这个讲座的完整视频&lt;/a&gt;。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;此次讲座的内容主要是对于ASP.NET AJAX Control Toolkit进行简单的介绍，展示了Extender控件是如何帮助ASP.NET开发人员简单地将丰富的用户体验集成到他们的Web应用程序中。在这次讲座里将看到应该如何在您的应用中使用ASP.NET AJAX Control Toolkit中的组件，并且了解开发人员是如何方便地开发一个APS.NET AJAX Extender的。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;此次讲座分为两部分：&amp;#8220;ASP.NET AJAX Control Toolkit介绍和使用&amp;#8221;以及&amp;#8220;开发一个Extender控件&amp;#8221;。本文将对于该讲座的第二部分进行讲述，并且对其第二个演示的第一个部分进行分析。&lt;br&gt;&lt;br&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;那么现在我们来看一下如果使用ASP.NET AJAX Control Toolkit的功能进行组件开发。ASP.NET AJAX Control Toolkit对于组件开发也有相当好的支持，我们设计时就是专注于它应该如何能让AJAX组件的开发变得简单。在开发Toolkit中的组件时，大量的代码已经被填充到了一个模版中，开发人员可以专注于实现组件的功能。而对于组件开发，ASP.NET AJAX&amp;nbsp;Control Toolkit也已经提供了许多的基础功能和特性。它能使开发人员专注于使用ASP.NET AJAX技术和各种良好实践，并且能够结合ASP.NET AJAX和Toolkit来开发出强大的AJAX组件，为此也不用去接受各种各样的其它概念。使用ASP.NET AJAX Control Toolkit开发组件的另一个重要的优势就是能够得到各种各样的支持，例如论坛，社区和完全开放的源代码等等。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;在这里需要在提一下Behavior和Extender，Behavior是一个由JavaScript编写的客户端组件，它的目的是通过修改页面的HTML DOM，为客户端的元素添加一些或者修改一些功能。而Extender都是ASP.NET的组件，他将ASP.NET的控件和Behavior联系了起来，并且提供了服务器端以及设计期的支持，而Extender自己没有具有非常多的功能。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;Bahavior是使用ASP.NET AJAX Library这个JavaScript框架编写的。ASP.NET AJAX Library是一个使用JavaScript开发的面向对象框架，它有一个能够自动提供跨浏览器能力的兼容层，这样我们就不需要为了各种浏览器写一些特殊的代码。另外它有自己的一套类型系统，也提供了调用Web Service方法的类，以及一些基本的DOM操作。当然它能够进行结构化的编程，也能提供良好封装性，也就是说，它虽然还是JavaScript，依旧不是类型安全的，依旧难以调试，但是使用ASP.NET AJAX Library进行开发能够比较好的将JavaScript代码进行管理。因此使用ASP.NET AJAX Library进行客户端的JavaScript开发，能够有效地使您的站点避免出现混乱不堪的JavaScript代码。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;如果需要开发一个Toolkit组件，您可以有两种选择：一种是使用Extender+Behavior的组合方式，另一种就是开发ASP.NET AJAX-awared控件，也就是ScriptControl。那么应该如何选择以那种形式开发Toolkit组件呢？一般来说，如果所需的HTML行为比较特殊，或者对于您的站点非常有针对性，那么写一个控件并且将一个Behavior附加在上面。如果HTML的样式很普通，需要开发一个能够在一个普遍存在环境中使用的组件，那么就编写一个Extender。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;那么应该如何开发一个控件，之前提到的那些组件又是如何一起工作的呢？我们现在来对这些组件解剖一下。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;首先要编写的是一个Extender类。这是一个使用Visual Basic或C#等.NET Framework语言编写的类，我们为这两种语言都提供了模版。下面就是用于扩展一个组件最主要的服务器端代码：&lt;/p&gt;
&lt;pre class="code"&gt;[ClientScript("&lt;span style="COLOR: #8b0000"&gt;...&lt;/span&gt;")]
[TargetControlType(&lt;span style="COLOR: #0000ff"&gt;typeof&lt;/span&gt;(Control))]
&lt;span style="COLOR: #0000ff"&gt;public&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;class&lt;/span&gt; MyExtender : ExtenderControlBase
{
    [ExtenderControlProperty]
&lt;span style="COLOR: #0000ff"&gt;    public&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;string&lt;/span&gt; MyStringProp{}
    [ExtenderControlProperty]
&lt;span style="COLOR: #0000ff"&gt;    public&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;int&lt;/span&gt; MyIntProp{}
}&lt;/pre&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;上面是用于开发一个扩展的代码片断，首先我们需要定义一个继承于Toolkit里的ExtenderControlBase类的Extender类。它具有一些属性，可以使用户在服务器端通过代码来设置客户端Behavior的属性。所以在我们之前的例子里，我们只是在操作Extender。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;在Extender之后则是Behavior，Behavior是使用JavaScript写的类，它以ASP.NET AJAX客户端组件的形式出现：&lt;/p&gt;
&lt;pre class="code"&gt;MyProject.MyBehavior = &lt;span style="COLOR: #0000ff"&gt;function&lt;/span&gt;(e){
MyProject.MyBehavior.initializeBase(&lt;span style="COLOR: #0000ff"&gt;this&lt;/span&gt;, [e]);
&lt;span style="COLOR: #0000ff"&gt;    this&lt;/span&gt;._myStringPropValue = &lt;span style="COLOR: #0000ff"&gt;null&lt;/span&gt;;
&lt;span style="COLOR: #0000ff"&gt;    this&lt;/span&gt;._myStringIntValue = 0;
}
MyProject.MyBehavior.&lt;span style="COLOR: #0000ff"&gt;prototype&lt;/span&gt; = {
    initialize : &lt;span style="COLOR: #0000ff"&gt;function&lt;/span&gt;() {...},
    get_MyStringProp : &lt;span style="COLOR: #0000ff"&gt;function&lt;/span&gt;(){...},
    set_MyStringProp : &lt;span style="COLOR: #0000ff"&gt;function&lt;/span&gt;(value){...},
    get_MyIntProp : &lt;span style="COLOR: #0000ff"&gt;function&lt;/span&gt;(){...},
    set_MyIntProp : &lt;span style="COLOR: #0000ff"&gt;function&lt;/span&gt;(value){...}
}&lt;/pre&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;可以发现，在这里，Behavior里定义的这些属性和Extender的属性一一对应，您可以发现这些对应的属性名是相同的的。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;然后在使用Extender时，您可以在页面中发现这样的标记：&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;cc1&lt;/span&gt;:&lt;span style="COLOR: #ff0000"&gt;MyExtender&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;TargetControlID&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"TextBox1"&lt;/span&gt;
&lt;span style="COLOR: #ff0000"&gt;&lt;font color=#000000&gt;    &lt;/font&gt;MyStringProp&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"Hello"&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;MyIntProp&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"23"&lt;/span&gt;
&lt;font color=#0000ff&gt;&amp;lt;/&lt;/font&gt;&lt;span style="COLOR: #ff0000"&gt;&lt;font color=#800000&gt;cc1&lt;/font&gt;&lt;/span&gt;:&lt;span style="COLOR: #ff0000"&gt;MyExtender&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;在上面的标记里我们在页面中定义了一个Extender控件，设置它的TargetControlID属性，这样就指定了这个Extender会扩展的控件，然后在指定其它一些属性。就是使用ASP.NET控件的标准方法。当然，您也可以通过编写代码来动态地使用Extender，就像您使用其它ASP.NET控件的方法一样。如下：&lt;/p&gt;
&lt;pre class="code"&gt;MyExtender ex1 = &lt;span style="COLOR: #0000ff"&gt;new&lt;/span&gt; MyExtender();
ex1.MyStringProp = "&lt;span style="COLOR: #8b0000"&gt;Hello&lt;/span&gt;";
ex1.MyIntProp = 23;
ex1.TargetControlID = "&lt;span style="COLOR: #8b0000"&gt;TextBox1&lt;/span&gt;";
Page.Add(ex1);&lt;/pre&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="FONT-SIZE: 16pt"&gt;&lt;strong&gt;讲座演示&lt;/strong&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;这个演示的代码可以在压缩包&amp;#8220;TechEd_Dev344.zip&amp;#8221;的&amp;#8220;Demos\CreatingExtender\Finished&amp;#8221;目录下找到，打开FontSizeExtender.sln即可。没有任何复杂的部署方式，只需要装有&lt;a href="http://go.microsoft.com/fwlink/?LinkID=77296"&gt;ASP.NET AJAX Beta 2&lt;/a&gt;。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;现在来看一下我们即将演示的内容，如图（点击小图可查看大图）：&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;a href="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV344.NETAJAXControlToolkit_93BC/TechEd2006DEV344_10%5B1%5D.jpg" atomicselection="true"&gt;&lt;img style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height=180 src="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV344.NETAJAXControlToolkit_93BC/TechEd2006DEV344_10.jpg" width=240 border=0&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;我记得在CNN.com网站上它有个Widght，它可以让用户改变一片文章的字体大小。您可以不改变浏览器的字体大小，而单独改变某一块区域的字体大小。所以我想这应该会是个有趣的示例。这个Extender的TargetControl是一个含有文字的Element，我们会改变它的字体大小，例如上图中的红色部分。上图的黄色区域就是控制文字大小控件，蓝色为&amp;#8220;加大&amp;#8221;按钮，绿色为&amp;#8220;减少&amp;#8221;按钮。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;如果想要开发Extender控件，首先需要建立一个Extender项目。在Toolkit的zip包内有一个VSI文件，安装后就会出现一些模版可以选择。我们可以使用其中的控件创建一个使用Extender的ASP.NET AJAX站点，您也可以使用其中的模版创建一个C#或者VB.NET的Extender组件项目。如图（点击小图可显示大图）：&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;a href="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV344.NETAJAXControlToolkit_93BC/TechEd2006DEV344_11%5B1%5D.jpg" atomicselection="true"&gt;&lt;img style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height=174 src="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV344.NETAJAXControlToolkit_93BC/TechEd2006DEV344_11.jpg" width=240 border=0&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;在这之前您需要安装ASP.NET AJAX，由于需要在GAC里查找所需的程序集。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;首先我们来看一下Toolkit中的&amp;#8220;序列化&amp;#8221;能力元数据。这些功能的作用是使的这些组件能够对自身进行标记和描述，例如您可以为控件添加普通的属性，再使用CustomAttribute进行标记，这就告诉了Toolkit这些属性的意义，Toolkit会使用反射来获得它们。最常用的CustomAttribute以及它们的作用如下：&lt;/p&gt;
&lt;ol&gt;
    &lt;li&gt;
    &lt;div style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;ExtenderControlPropertyAttribute：在之前的代码中您也可以看到这个CustromAttribute的使用。它的作用是告诉Toolkit，一个Extender的哪些属性需要被设置到客户端的Behavior中。&lt;/div&gt;
    &lt;li&gt;
    &lt;div style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;ElementReferenceAttribute：它表明了该属性会指定一个客户端的元素，这样只要在服务器端指定ID后，在客户端使用Behavior时就能直接得到那个元素了。&lt;/div&gt;
    &lt;li&gt;
    &lt;div style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;IDReferenceAttribute：它的作用是在服务器端指定一个服务器控件的ID，这样在客户端的Behavior就能得到这个服务器控件的ClientID，如果您查看页面的代码时则会看到一个可能会非常长的ID。&lt;/div&gt;
    &lt;li&gt;
    &lt;div style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;ClientPropertyNameAttribute：它是配合ExtenderControlPropertyAttribute使用的，能够把服务器端的属性名客户端Behavior里的不同属性名进行映射，而不是使用默认的相同属性名。&lt;/div&gt;
    &lt;/li&gt;
&lt;/ol&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;那么我们现在就来尝试着开发这个控件（&lt;font color=#ff0000&gt;老赵：请注意，在Shawn提供的压缩包内有三个空文件夹：Demo_Base、Demo_Step_2和Demo_Step_3，现在它们在演示时也是有内容的，我已经根据讲座视频设法将它们恢复到了演示时的样子，请&lt;a href="http://files.cnblogs.com/JeffreyZhao/TechEd_Dev344_DemoExt.zip"&gt;点击这里&lt;/a&gt;下载&lt;/font&gt;）。&lt;/p&gt;
&lt;p style="FONT-SIZE: 12pt; FONT-FAMILY: verdana"&gt;Step 1：Define the Extender Class&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;打开Demo_Base文件夹下的解决方案文件，可以看到这里已经存在了一个站点。事实上这个站点已经写好了，它就像是一张报纸。如图（点击小图可查看大图）：&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;a href="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV344.NETAJAXControlToolkit_93BC/TechEd2006DEV344_12%5B1%5D.jpg" atomicselection="true"&gt;&lt;img style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height=180 src="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV344.NETAJAXControlToolkit_93BC/TechEd2006DEV344_12.jpg" width=240 border=0&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;在这里您可以看到一些AJAX Control Toolkit的一些很有趣的新闻，比如它是如何能够轻易地添加客户端UI功能等等。这里存在许多文本，我们希望提供改变大小的能力。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;我们要做的第一件事是创建我们的Toolkit项目，我们在安装Tookit的VSI文件后会产生Toolkit项目的模版，我们创建一个名为FontSize的Toolkit项目。如图（点击小图可查看大图）：&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;a href="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV344.NETAJAXControlToolkit_93BC/TechEd2006DEV344_13%5B1%5D.jpg" atomicselection="true"&gt;&lt;img style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height=156 src="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV344.NETAJAXControlToolkit_93BC/TechEd2006DEV344_13.jpg" width=240 border=0&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;点击确定以后可以看到它为我们创建了三个文件：FontSizeBehavior.js，FontSizeDesigner.cs和FontSizeExtender.cs文件。我们不用关心FontSizeDesigner类，Toolkit会自动为你提供设计器的功能，您在大多数情况下无须为它编写代码。最重要的是Behavior和Extender。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;我们首先为我们的组件建立Extender。我们首先需要关心的元数据是TargetControlTypeAttribute的使用，它表示了您的Extender能够扩展的控件类型。您可以指定任何的ASP.NET控件，在这里我们将其限制为Paenl，如下：&lt;/p&gt;
&lt;pre class="code"&gt;[Designer(&lt;span style="COLOR: #0000ff"&gt;typeof&lt;/span&gt;(FontSizeDesigner))]
[ClientScriptResource("&lt;span style="COLOR: #8b0000"&gt;FontSize.FontSizeBehavior&lt;/span&gt;", "&lt;span style="COLOR: #8b0000"&gt;FontSize.FontSizeBehavior.js&lt;/span&gt;")]
[TargetControlType(&lt;span style="COLOR: #0000ff"&gt;typeof&lt;/span&gt;(Panel))]
&lt;span style="COLOR: #0000ff"&gt;public&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;class&lt;/span&gt; FontSizeExtender : ExtenderControlBase {
    ...
}&lt;/pre&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;接下来为其添加Property代码：&lt;/p&gt;
&lt;pre class="code"&gt;[ExtenderControlProperty]
&lt;span style="COLOR: #0000ff"&gt;public&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;string&lt;/span&gt; SizePanelControlID
{
&lt;span style="COLOR: #0000ff"&gt;&lt;font color=#000000&gt;    &lt;/font&gt;get&lt;/span&gt; {
&lt;span style="COLOR: #0000ff"&gt;&lt;font color=#000000&gt;        &lt;/font&gt;return&lt;/span&gt; GetPropertyStringValue("&lt;span style="COLOR: #8b0000"&gt;SizePanelControlID&lt;/span&gt;");
    }
&lt;span style="COLOR: #0000ff"&gt;&lt;font color=#000000&gt;    &lt;/font&gt;set&lt;/span&gt; {
        SetPropertyStringValue("&lt;span style="COLOR: #8b0000"&gt;SizePanelControlID&lt;/span&gt;", &lt;span style="COLOR: #0000ff"&gt;value&lt;/span&gt;);
    }
}

[ExtenderControlProperty]
&lt;span style="COLOR: #0000ff"&gt;public&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;string&lt;/span&gt; IncreaseSizeControlID { ... }
[ExtenderControlProperty]
&lt;span style="COLOR: #0000ff"&gt;public&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;string&lt;/span&gt; DecreaseSizeControlID { ... }
[ExtenderControlProperty]
&lt;span style="COLOR: #0000ff"&gt;public&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;string&lt;/span&gt; PanelHoverCssClass { ... }

[DefaultValue(2)]
[ExtenderControlProperty]
&lt;span style="COLOR: #0000ff"&gt;public&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;int&lt;/span&gt; FontSizeIncrement
{
&lt;span style="COLOR: #0000ff"&gt;&lt;font color=#000000&gt;    &lt;/font&gt;get&lt;/span&gt; {
&lt;span style="COLOR: #0000ff"&gt;&lt;font color=#000000&gt;        &lt;/font&gt;return&lt;/span&gt; GetPropertyValue("&lt;span style="COLOR: #8b0000"&gt;FontSizeIncrement&lt;/span&gt;", 2);
    }
&lt;span style="COLOR: #0000ff"&gt;&lt;font color=#000000&gt;    &lt;/font&gt;set&lt;/span&gt; {
        SetPropertyIntValue("&lt;span style="COLOR: #8b0000"&gt;FontSizeIncrement&lt;/span&gt;", &lt;span style="COLOR: #0000ff"&gt;value&lt;/span&gt;);
    }
}&lt;/pre&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;第一个是SizePanelControlID，就是我们用于放置增大缩小按钮的控件。IncreaseSizeControlID和DecreaseSizeControlID的作用是指定了哪个控件被点击时我们会增大或减小Panel的字体。PanelHoverCssClass是我们定义的CSS类，当我们将鼠标移到Panel上时会改变Panel的CSS类。FontSizeIncrement表示了每次我们点击按钮时字体大小的改变程度。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;请注意，我们这里存在一些有用的方法：GetPropertyStringValue、SetPropertyStringValue、GetPropertyInt等，Toolkit中定义了一整套这样的方法，Toolkit为自己会对这些属性的保存方式作一些特别的处理，因此请不要使用自己的方法，例如ViewState来保存。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;这里还出现了DefaultValueAttribute，我会在稍后对它进行介绍。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;接着在WebSite项目中引入这个FontSize项目，编译，然后在页面中添加如下的注册标记：&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="COLOR: black; BACKGROUND-COLOR: #ffff00"&gt;&amp;lt;%&amp;#64; Register Assembly="FontSize" Namespace="FontSize" TagPrefix="fontSize" %&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;然后我们需要修改FontSizeBehavior.js文件。首先我们需要在构造函数里添加我们需要的私有变量。如下：&lt;/p&gt;
&lt;pre class="code"&gt;FontSize.FontSizeBehavior = &lt;span style="COLOR: #0000ff"&gt;function&lt;/span&gt;(element) {
FontSize.FontSizeBehavior.initializeBase(&lt;span style="COLOR: #0000ff"&gt;this&lt;/span&gt;, [element]);
&lt;span style="COLOR: #008000"&gt;&lt;font color=#000000&gt;    &lt;/font&gt;// the DOM elemens we'll be interacting with&lt;/span&gt;
&lt;span style="COLOR: #008000"&gt;&lt;font color=#000000&gt;    &lt;/font&gt;//&lt;/span&gt;
&lt;span style="COLOR: #0000ff"&gt;&lt;font color=#000000&gt;    &lt;/font&gt;this&lt;/span&gt;._sizePanelElement = &lt;span style="COLOR: #0000ff"&gt;null&lt;/span&gt;;
&lt;span style="COLOR: #0000ff"&gt;&lt;font color=#000000&gt;    &lt;/font&gt;this&lt;/span&gt;._incrementElement = &lt;span style="COLOR: #0000ff"&gt;null&lt;/span&gt;;
&lt;span style="COLOR: #0000ff"&gt;&lt;font color=#000000&gt;    &lt;/font&gt;this&lt;/span&gt;._decrementElement = &lt;span style="COLOR: #0000ff"&gt;null&lt;/span&gt;;
&lt;span style="COLOR: #0000ff"&gt;&lt;font color=#000000&gt;    &lt;/font&gt;this&lt;/span&gt;._hoverCssClass = &lt;span style="COLOR: #0000ff"&gt;null&lt;/span&gt;;
}&lt;/pre&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;接着在客户端里添加一个Behavior的属性：&lt;/p&gt;
&lt;pre class="code"&gt;get_sizePanelElement : &lt;span style="COLOR: #0000ff"&gt;function&lt;/span&gt;() {
&lt;span style="COLOR: #0000ff"&gt;&lt;font color=#000000&gt;    &lt;/font&gt;return&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;this&lt;/span&gt;._sizePanelElement;
},
set_sizePanelElement: &lt;span style="COLOR: #0000ff"&gt;function&lt;/span&gt;(val) {
&lt;span style="COLOR: #0000ff"&gt;&lt;font color=#000000&gt;    &lt;/font&gt;this&lt;/span&gt;._sizePanelElement = val;
}&lt;/pre&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;在客户端是使用get/set方法来表示一个属性的。至于客户端组件的创建，赋值，销毁等操作都是由ASP.NET AJAX来处理了。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;我们打开页面，在页面里添加我们的Extender以及一组用于字体放大/缩小的按钮：&lt;/p&gt;
&lt;pre class="code"&gt;    ...
&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #c71585"&gt;fontSize&lt;/span&gt;:&lt;span style="COLOR: #800000"&gt;FontSizeExtender&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;ID&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"fse"&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;&lt;font color=#000000&gt;    &lt;/font&gt;TargetControlID&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"pnlMainStory"&lt;/span&gt;　&lt;span style="COLOR: #ff0000"&gt;SizePanelControlID&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"extenderUI"　&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;/&amp;gt;&lt;br&gt;&lt;/span&gt;
&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="COLOR: #800000"&gt;Panel&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;ID&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"extenderUI"&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;CssClass&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"popup"&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="COLOR: #0000ff"&gt;&lt;font color=#000000&gt;    &lt;/font&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="COLOR: #800000"&gt;Button&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;ID&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"btnSmaller"&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;Text&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"-"&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/span&gt;
&lt;span style="COLOR: #0000ff"&gt;&lt;font color=#000000&gt;    &lt;/font&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="COLOR: #800000"&gt;Button&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;ID&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"btnBigger"&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;Text&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"+"&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: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="COLOR: #800000"&gt;Panel&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;br&gt;&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;class&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"panelNormal"&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;
    ...
&lt;span style="COLOR: #0000ff"&gt;&lt;font color=#000000&gt;    &lt;/font&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="COLOR: #800000"&gt;Panel&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;ID&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"pnlMainStory"&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;span style="COLOR: #0000ff"&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;/pre&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;在这里我们将TargetControlID设为pnlMainStory，表明Extender将操作那个Panel。SizePanelControlID设为extenderUI，它为增大/减小按钮的容器。然后指定分别指定字体增大和减小两个按钮，最后将CssClass设为panelHover。现在我们打开页面，由于我们只写了一小部分代码，因此会出现脚本执行错误。在页面下方可以发现这段代码：&lt;/p&gt;
&lt;pre class="code"&gt;Sys.Application.add_init(&lt;span style="COLOR: #0000ff"&gt;function&lt;/span&gt;() {
    $create(
        FontSize.FontSizeBehavior,
        {"&lt;span style="COLOR: #8b0000"&gt;DecreaseSizeControlID&lt;/span&gt;":"&lt;span style="COLOR: #8b0000"&gt;&lt;/span&gt;", "&lt;span style="COLOR: #8b0000"&gt;id&lt;/span&gt;":"&lt;span style="COLOR: #8b0000"&gt;fse&lt;/span&gt;", "&lt;span style="COLOR: #8b0000"&gt;IncreaseSizeControlID&lt;/span&gt;":"&lt;span style="COLOR: #8b0000"&gt;&lt;/span&gt;",
        "&lt;span style="COLOR: #8b0000"&gt;PanelHoverCssClass&lt;/span&gt;":"&lt;span style="COLOR: #8b0000"&gt;&lt;/span&gt;", "&lt;span style="COLOR: #8b0000"&gt;SizePanelControlID&lt;/span&gt;":"&lt;span style="COLOR: #8b0000"&gt;extenderUI&lt;/span&gt;"},
&lt;span style="COLOR: #0000ff"&gt;&lt;font color=#000000&gt;        &lt;/font&gt;null&lt;/span&gt;, &lt;span style="COLOR: #0000ff"&gt;null&lt;/span&gt;, $get('pnlMainStory'));
        });&lt;/pre&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;$create方法是ASP.NET AJAX Library中定义的方法，用于创建一个组件。这就是ASP.NET AJAX将客户端组件与DOM元素进行绑定的方法，在$create方法内部会有许多操作。它被添加到Sys.Application的init事件中，这个事件会在脚本加载完成，在页面在初始化时触发。$create的第一个参数表示即将创建的Behavior类型，从第二个参数中可以看到我们定义的属性，它们会被赋值，可以发现这里大部分的属性都是空值。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;我们暂时不关心客户端没有定义的属性，事实上就SizePanelControlID来说就有很多问题。第一个问题就在于，我们定义了SizePanelControlID的ID为extenderUI，但是如果这个控件被放进了别的控件内，那么很可能它就会变成一个有许多前缀的ID。至于第二个问题，请注意在Behavior中我们希望sizePanelElement属性会直接获得一个HTML元素，而不是元素的ID。让我们先来解决这两个问题。另外可以发现，我们需要的客户端属性名称为sizePanelElement，而不是Extender的属性名：SizePanelControlID。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;正如之前提到过的，我们会在Extender中大量使用CustomAttribute。如下：&lt;/p&gt;
&lt;pre class="code"&gt;[ExtenderControlProperty]
[IDReferenceProperty(&lt;span style="COLOR: #0000ff"&gt;typeof&lt;/span&gt;(Panel))]
[ElementReference]
[ClientPropertyName("&lt;span style="COLOR: #8b0000"&gt;sizePanelElement&lt;/span&gt;")]
&lt;span style="COLOR: #0000ff"&gt;public&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;string&lt;/span&gt; SizePanelControlID {
&lt;span style="COLOR: #0000ff"&gt;&lt;font color=#000000&gt;    &lt;/font&gt;get&lt;/span&gt; {
&lt;span style="COLOR: #0000ff"&gt;&lt;font color=#000000&gt;        &lt;/font&gt;return&lt;/span&gt; GetPropertyStringValue("&lt;span style="COLOR: #8b0000"&gt;SizePanelControlID&lt;/span&gt;");
    }
&lt;span style="COLOR: #0000ff"&gt;&lt;font color=#000000&gt;    &lt;/font&gt;set&lt;/span&gt; {
        SetPropertyStringValue("&lt;span style="COLOR: #8b0000"&gt;SizePanelControlID&lt;/span&gt;", &lt;span style="COLOR: #0000ff"&gt;value&lt;/span&gt;);
    }
}&lt;/pre&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;首先我会使用&lt;font color=#ff0000&gt;IDReferencePropertyAttribute&lt;/font&gt;，它告诉Toolkit这个字符串属性事实上代表了一个ASP.NET服务器端的Panel控件。这里起到的效果有两个：首先它能告诉设计器，这样设计器在处理这个属性时就会使用一个下拉框列出所有的Panel让用户选择；其次它保证了最终传递给客户端的值是控件在客户端的ID，而不是在服务器端的ID，这样客户端就能通过这个客户端ID来得到这个元素。在这里我们添加的另一个CustomAttribute是&lt;font color=#ff0000&gt;ElementReferenceAttribute&lt;/font&gt;，它的作用就是告诉Toolkit需要在客户端得到指定的HTML元素后再将值赋给属性。最后我们使用了&lt;font color=#ff0000&gt;ClientPropertyNameAttribute&lt;/font&gt;，告诉Toolkit需要在客户端使用sizePanelElement作为属性名。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;我们编译项目，刷新页面，再来查看一下页面的代码。如下：&lt;/p&gt;
&lt;pre class="code"&gt;Sys.Application.add_init(&lt;span style="COLOR: #0000ff"&gt;function&lt;/span&gt;() {
    $create(
        FontSize.FontSizeBehavior,
        {"&lt;span style="COLOR: #8b0000"&gt;DecreaseSizeControlID&lt;/span&gt;" : "&lt;span style="COLOR: #8b0000"&gt;&lt;/span&gt;", "&lt;span style="COLOR: #8b0000"&gt;id&lt;/span&gt;" : "&lt;span style="COLOR: #8b0000"&gt;fse&lt;/span&gt;",
        "&lt;span style="COLOR: #8b0000"&gt;IncreaseSizeControlID&lt;/span&gt;" : "&lt;span style="COLOR: #8b0000"&gt;&lt;/span&gt;", "&lt;span style="COLOR: #8b0000"&gt;PanelHoverCssClass&lt;/span&gt;" : "&lt;span style="COLOR: #8b0000"&gt;&lt;/span&gt;",
        "&lt;span style="COLOR: #8b0000"&gt;sizePanelElement&lt;/span&gt;" : $get("&lt;span style="COLOR: #8b0000"&gt;extenderUI&lt;/span&gt;")},
&lt;span style="COLOR: #0000ff"&gt;&lt;font color=#000000&gt;        &lt;/font&gt;null&lt;/span&gt;, &lt;span style="COLOR: #0000ff"&gt;null&lt;/span&gt;, $get('pnlMainStory'));
        });&lt;/pre&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;可以发现，由于ElementReferenceAttribute的作用，这里的代码使用了客户端$get方法，这是ASP.NET AJAX为document.getElementById方法建立的缩写。另外可以发现属性名也从SizePanelControlID变为了sizePanelElement，这是因为使用了ClientPropertyNameAttribute。可惜由于这个控件没有在别的控件之内，因此客户端ID和服务器端ID相同，依旧是extenderUI，没有看出IDReferencePropertyAttribute的效果。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;于是我们为其余的服务器端属性也添加CustomAttribute（老赵：这里就不一一例举了，大家可以查看代码）。这里还使用了DefalutValueAttribute。它的作用是告诉Toolkit，如果没有对属性进行修改，那么会使用哪个值作为默认值，这样在当前值等于默认值的时候则会省去不少客户端代码。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;由于没有提供默认值，刚才生成的客户端代码依旧有很多空字符串，我们重新编译项目，刷新页面，再看一下现在代码：&lt;/p&gt;
&lt;pre class="code"&gt;Sys.Application.add_init(&lt;span style="COLOR: #0000ff"&gt;function&lt;/span&gt;() {
    $create(
        FontSize.FontSizeBehavior,
        {"&lt;span style="COLOR: #8b0000"&gt;id&lt;/span&gt;":"&lt;span style="COLOR: #8b0000"&gt;fse&lt;/span&gt;","&lt;span style="COLOR: #8b0000"&gt;sizePanelElement&lt;/span&gt;":$get('extenderUI')},
&lt;span style="COLOR: #0000ff"&gt;&lt;font color=#000000&gt;        &lt;/font&gt;null&lt;/span&gt;, &lt;span style="COLOR: #0000ff"&gt;null&lt;/span&gt;, $get('pnlMainStory'));
        });&lt;/pre&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;可以发现，许多属性的设置被省去了，这就是DefaultValue的效果。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;于是我们在客户端也添加上相应的Behavior属性（老赵：这里就不一一例举了，大家可以查看代码），最后补全页面中的Extender声明：&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #c71585"&gt;fontSize&lt;/span&gt;:&lt;span style="COLOR: #800000"&gt;FontSizeExtender&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;ID&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"fse"&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;TargetControlID&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"pnlMainStory"&lt;/span&gt;
&lt;span style="COLOR: #ff0000"&gt;&lt;font color=#000000&gt;    &lt;/font&gt;SizePanelControlID&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"extenderUI"&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;DecreaseSizeControlID&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"btnSmaller"&lt;/span&gt;
&lt;span style="COLOR: #ff0000"&gt;&lt;font color=#000000&gt;    &lt;/font&gt;IncreaseSizeControlID&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"btnBigger"&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;PanelHoverCssClass&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"panelHover"&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;我们设置了所有的属性：指定了用于增大／减小字体的按钮，还有鼠标移上Panel时所使用的CSS类。我们再来看一下现在的客户端代码：&lt;/p&gt;
&lt;pre class="code"&gt;Sys.Application.add_init(&lt;span style="COLOR: #0000ff"&gt;function&lt;/span&gt;() {
    $create(
        FontSize.FontSizeBehavior,
        {"&lt;span style="COLOR: #8b0000"&gt;decrementElement&lt;/span&gt;" : $get('btnSmaller'), 
        "&lt;span style="COLOR: #8b0000"&gt;hoverCssClass&lt;/span&gt;" : "&lt;span style="COLOR: #8b0000"&gt;panelHover&lt;/span&gt;", "&lt;span style="COLOR: #8b0000"&gt;id&lt;/span&gt;" : "&lt;span style="COLOR: #8b0000"&gt;fse&lt;/span&gt;",
        "&lt;span style="COLOR: #8b0000"&gt;incrementElement&lt;/span&gt;" : $get('btnBigger'), 
        "&lt;span style="COLOR: #8b0000"&gt;sizePanelElement&lt;/span&gt;" : $get('extenderUI')},
&lt;span style="COLOR: #0000ff"&gt;&lt;font color=#000000&gt;        &lt;/font&gt;null&lt;/span&gt;, &lt;span style="COLOR: #0000ff"&gt;null&lt;/span&gt;, $get('pnlMainStory'));
        });&lt;/pre&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;/p&gt;</description>
      <comments>http://blog.zhaojie.me/2006/11/lecture-teched-europe-dev344-2.html#comments</comments>
      <pubDate>Fri, 17 Nov 2006 10:17:00 GMT</pubDate>
      <lastBuildDate>Fri, 17 Nov 2006 10:17:00 GMT</lastBuildDate>
    </item>
    <item>
      <author>jeffz@live.com (老赵)</author>
      <category domain="http://blog.zhaojie.me/speech/">培训演讲</category>
      <category domain="http://blog.zhaojie.me/translation/">翻译引进</category>
      <category domain="http://blog.zhaojie.me/asp-net/">ASP.NET</category>
      <category domain="http://blog.zhaojie.me/front-end/">前端表现</category>
      <title>讲座展示：TechEd Europe DEV344 - ASP.NET AJAX Control Toolkit（上）</title>
      <link>http://blog.zhaojie.me/2006/11/lecture-teched-europe-dev344-1.html</link>
      <guid>http://blog.zhaojie.me/2006/11/lecture-teched-europe-dev344-1.html</guid>
      <description>&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;从现在开始，我会将一些我认为有价值的讲座内容介绍给大家，尤其会将其中的经典示例里以Step by Step的形式演示一下。可能这些讲座的不会非常深入，但是能保证其质量非常高，因此都是不可多得的学习内容。而通过类似于Hands on Lab的一步一步实践，也能让大家对于某项技术有着更加牢固的理解。另外，由于某些讲座的演示的部署会比较复杂，我在这里也会比较详细地对这些演示的部署方式进行说明，方便大家在使用演示项目的同时能够动手进行修改，加深理解。对于难以接受英文讲座的朋友也可以通过我的文章了解讲座的精彩内容。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;除非特别注明，文章里使用的内容，图片以及源代码均来源于演讲者本人或者官方发布的讲座内容。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="FONT-SIZE: 16pt"&gt;&lt;strong&gt;讲座内容&lt;/strong&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;这次我选择的讲座内容是最近在TechEd 2006 Europe中Shawn Burke的讲座&amp;#8220;ASP.NET AJAX Control Toolkit Unleashed: Creating Rich Client-Side Controls and Components&amp;#8221;。Shawn Burke是微软.NET Developer Platform总监。这个讲座的PPT和演示代码的下载地址已经由他本人&lt;a href="http://blogs.msdn.com/sburke/archive/2006/11/07/teched-talk-demos.aspx" target=_blank&gt;公布在他的Blog上&lt;/a&gt;（&lt;a href="http://files.cnblogs.com/JeffreyZhao/TechEd_Dev344.zip"&gt;本地下载&lt;/a&gt;）。另外，在MSDN's Showtime上也已经有了&lt;a href="http://www.microsoft.com/emea/msdnshowtime/sessionl.aspx?videoid=320" target=_blank&gt;这个讲座的完整视频&lt;/a&gt;。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;此次讲座的内容主要是对于ASP.NET AJAX Control Toolkit进行简单的介绍，展示了Extender控件是如何帮助ASP.NET开发人员简单地将丰富的用户体验集成到他们的Web应用程序中。在这次讲座里将看到应该如何在您的应用中使用ASP.NET AJAX Control Toolkit中的组件，并且了解开发人员是如何方便地开发一个APS.NET AJAX Extender的。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;此次讲座分为两部分：&amp;#8220;ASP.NET AJAX Control Toolkit介绍和使用&amp;#8221;以及&amp;#8220;开发一个Extender控件&amp;#8221;。本文将对于该讲座的第一部分进行讲述，并且对其第一个演示进行分析。&lt;br&gt;&lt;br&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;ASP.NET AJAX Control Toolkit开发团队使用了敏捷方法，能够尽早地接受到用户反馈。整个项目的开发过程非常透明，使用户很好能参与进来，并且完全开放各种资源（例如bug数据库，源代码等），这种做法使得项目能在相对较早的阶段就能拥有较高的质量。ASP.NET AJAX Control Toolkit的目标是为了能够让服务器端开发人元非常方便地将AJAX特性加入他们的站点中，同时也能使客户端开发人员能够比较轻易地写出良好封装容易复用的AJAX组件。这种良好的AJAX组件开发和使用方式能够使AJAX特性更加容易被各种类型的开发人员所接受。另外，ASP.NET AJAX Control Toolkit也创造性地使用了一种透明的，并且由社区驱动的开发模型。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;ASP.NET AJAX&amp;nbsp;Control Toolkit包含许多组件，能够使ASP.NET开发人员方便地为自己的应用增加客户端的UI效果。关于这一点Scott Guthrie提到过：&amp;#8220;Scott Hanselman曾经开玩笑地把这些AJAX控件称作&amp;#8216;作弊&amp;#8217;&amp;#8230;&amp;#8230;因为它们能使您在最常用的情况下不用写任何客户端JavaScript代码而获得AJAX特性&amp;#8221;。它也是一个能够开发和部署AJAX组件的框架，而这种开源的方式也能将社区和微软强强联手，开发出一套具有最佳实践价值的产品。在开发过程中，会使用3名微软的开发人员组成的小团队和10名左右的外部人员贡献他们的力量。任何人都可以在&lt;a href="http://www.codeplex.com/"&gt;http://www.codeplex.com&lt;/a&gt;中下载到任何时候check-in的代码，不过在开发过程中会使用Microsoft Visual Studio Team Foundation Server的功能进行控制，只有拥有一定权限的参与者才能对代码进行更新。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;下面这幅图描述了ASP.NET&amp;nbsp;AJAX&amp;nbsp;Control Toolkit的技术组成（点击小图可查看大图）：&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;a href="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdDEV344ASP.NETAJAXControlToolkit_1A96/TechEd2006DEV344_1%5B4%5D.jpg" atomicselection="true"&gt;&lt;img style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height=180 src="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdDEV344ASP.NETAJAXControlToolkit_1A96/TechEd2006DEV344_1%5B3%5D.jpg" width=240 border=0&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;我们通过这幅图看到ASP.NET AJAX Control Toolkit是如何结合ASP.NET AJAX的。在这些技术的核心，是ASP.NET AJAX Extentions和ASP.NET AJAX Library，它们刚在周一发布了Beta 2，而且&lt;font color=#ff0000&gt;会在下个月将发布最终版本，并且会集成进下一版本的.NET Framework&lt;/font&gt;&lt;font color=#000000&gt;（Shawn原话）。图中黄色部分表示了在Atlas里而不是核心的功能，我们称之为Value-Add和CTP，它们也能从ASP.NET AJAX网站下载。蓝色部分表示了Toolkit，是个由社区驱动的项目，分为Server端组件和Client端组件两部分。这就是我们发布各种Toolkit功能的模型，我们用了各种方法使用户参与进来，让项目得到及时的大量反馈。&lt;/font&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;下面这幅图描述了ASP.NET AJAX Control Toolkit的架构（点击小图可查看大图）：&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;a href="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdDEV344ASP.NETAJAXControlToolkit_1A96/TechEd2006DEV344_2%5B1%5D.jpg" atomicselection="true"&gt;&lt;img style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height=180 src="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdDEV344ASP.NETAJAXControlToolkit_1A96/TechEd2006DEV344_2.jpg" width=240 border=0&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;我们可以看到ASP.NET Control Toolkit是如何工作的。ASP.NET Control Toolkit不光是基于已有的ASP.NET 2.0和.NET Framework，也使用了ASP.NET Server Extentions和ASP.NET AJAX Library。黄色部分表示了已经存在的ASP.NET 2.0功能基础，而绿色部分表示了由ASP.NET AJAX团队已经建立的核心基础。我们起初在开发Atlas时建立了一部分的组件，通过社区反馈来得知这些组件是否常用。目前已经建立了超过30个组件了。另外为了帮助用户开发自己的组件，我们也建立了Visual Studio 2005的模版。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;ASP.NET AJAX Control Toolkit拥有良好的跨浏览器特性，能够良好地支持IE6、IE7、FireFox和Safari等主流浏览器。对于Opera浏览器的支持是一个的目标，我们将会尽可能地对于Opera浏览器进行支持，关于这一点有个好消息：目前只有非常少的功能无法支持了。另外，我们尽力使目前的ASP.NET AJAX框架能够与其它的AJAX框架（例如Prototype，dojo）进行良好地集成，而不会引发冲突。在这里我们会提到三种组件：Control、Extender和Behavior。其中Control就是传统的控件，它是ASP.NET AJAX Control Toolkit的表现方式；Extender组件是一些服务器端代码，它使客户端的功能得到执行；最后则是Behavior组件，它是使用JavaScript编写的客户端核心功能。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;在使用ASP.NET AJAX Control Toolkit进行页面开发时，能够很轻易地为已有站点的功能进行增强，当然新建一个站点就更不在话下了。目前ASP.NET AJAX Control Toolkit包含了超过30个具有AJAX特性的组件，您无需掌握JavaScript就能很轻易地使用它们。您能够在设计期以拖放的形式进行开发，而且这一点在Visual Studio "Orcas"中会有更好的体现。在部署时，您也只需将程序集简单地复制到站点的Bin目录下即可，而开发源代码的特性也使得这些组件能够很方便地让用户针对自己的项目自定义其中的任何部分，包括添加新的功能和修补其中的Bug。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="FONT-SIZE: 16pt"&gt;&lt;strong&gt;讲座演示&lt;/strong&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;这个演示的代码可以在压缩包&amp;#8220;TechEd_Dev344.zip&amp;#8221;的&amp;#8220;\Demos\ToolkitBasics\WebSite&amp;#8221;目录下找到，没有任何复杂的部署方式，只需要装有&lt;a href="http://go.microsoft.com/fwlink/?LinkID=77296" target=_blank&gt;ASP.NET AJAX Beta 2&lt;/a&gt;即可。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;我们来简单看一下如何在已有的站点中使用Toolkit。首先打开&amp;#8220;Before.aspx&amp;#8221;文件，我们可以看到如下的页面（点击小图可查看大图）：&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;a href="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV344.NETAJAXControlToolkit_9271/TechEd2006DEV344_3%5B1%5D.jpg" atomicselection="true"&gt;&lt;img style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height=216 src="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV344.NETAJAXControlToolkit_9271/TechEd2006DEV344_3.jpg" width=240 border=0&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;这是个图片展示网站。这个站点叫做&amp;#8220;Image Flix&amp;#8221;，它会搜索服务器中收藏的图片，并以表格的形式展示出来。我们可以看到一些分类，也有搜索框。当点击某个分类时，这个示例会随机选择一些图片，不过您可以想象这是在浏览一个图片分类。每一个次点击都会引发一个Post Back，这是个标准的ASP.NET应用程序。如果我们要把Toolkit运用到我们的站点中，我们首先要做的就是为站点添加一个Microsoft.web.Extensions程序集的引用，这个是Microsoft ASP.NET AJAX的程序集。然后需要添加一个AjaxControlToolkit的引用。如图（点击小图可查看大图）：&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;a href="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV344.NETAJAXControlToolkit_9271/TechEd2006DEV344_4%5B3%5D.jpg" atomicselection="true"&gt;&lt;img style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height=137 src="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV344.NETAJAXControlToolkit_9271/TechEd2006DEV344_4%5B2%5D.jpg" width=240 border=0&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;下一步要做的就是改变Web.config中的内容。最好的方法是新建一个ASP.NET AJAX站点，然后查看它的Web.config文件的内容，然后将内容合并到您的Web.config文件中。您现在能够在现在Web.config文件中看到所有的Section定义：&lt;/p&gt;
&lt;fieldset&gt;&lt;legend style="FONT-FAMILY: verdana"&gt;Configuration Sections - Web.config文件&lt;/legend&gt;
&lt;pre style="MARGIN: 5px"&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;configSections&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;sectionGroup&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;name&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"microsoft.web"&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;type&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"..."&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;sectionGroup&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;name&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"scripting"&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;type&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"..."&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;sectionGroup&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;name&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"webServices"&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;type&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"..."&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;section&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;name&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"jsonSerialization"&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;type&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"..."&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;requirePermission&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"false"&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;section&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;name&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"profileService"&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;type&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"..."&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;requirePermission&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"false"&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;section&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;name&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"authenticationService"&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;type&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"..."&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;requirePermission&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"false"&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;sectionGroup&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;sectionGroup&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;sectionGroup&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;configSections&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/fieldset&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;还有一些Tag前缀和Tag映射的定义：&lt;/p&gt;
&lt;fieldset&gt;&lt;legend style="FONT-FAMILY: verdana"&gt;Tag Prefix and Tag Mapping Definitions - Web.config文件&lt;/legend&gt;
&lt;pre style="MARGIN: 5px"&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;pages&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;controls&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;add&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;tagPrefix&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"asp"&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;namespace&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"Microsoft.Web.UI"&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;assembly&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"..."&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;add&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;tagPrefix&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"asp"&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;namespace&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"Microsoft.Web.UI.Controls"&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;assembly&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"..."&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;controls&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;tagMapping&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;add&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;tagType&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"..."&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;mappedTagType&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"..."&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/span&gt;
&lt;span style="COLOR: #008000"&gt;    &amp;lt;!-- other tag mapping --&amp;gt;&lt;/span&gt;
&lt;span style="COLOR: #0000ff"&gt;  &amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;tagMapping&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;pages&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/fieldset&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;当您将这些设置好以后，就可以使用ASP.NET AJAX了。在这个示例中我们已经添加了ASP.NET AJAX的功能（DemoStart.aspx文件）。我们使用了UpdatePanel，UpdatePanel是ASP.NET AJAX的核心控件，它使我们能够在页面不完全加载的情况下，使页面的一部分内容得以刷新：&lt;/p&gt;
&lt;fieldset&gt;&lt;legend style="FONT-FAMILY: verdana"&gt;UpdatePanel - DemoStart.aspx文件&lt;/legend&gt;
&lt;pre style="MARGIN: 5px"&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="COLOR: #800000"&gt;UpdatePanel&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;ID&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"up1"&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;span style="COLOR: #0000ff"&gt;    &amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;ContentTemplate&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: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="COLOR: #800000"&gt;DataList&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;ID&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"DataList1"&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;RepeatColumns&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;ItemTemplate&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: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="COLOR: #800000"&gt;Panel&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;ID&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"Panel1"&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;Height&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"100px"&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"100px"&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;CssClass&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"panel"&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: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="COLOR: #800000"&gt;Image&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;ID&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"Image1"&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;                        ImageUrl&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;'&amp;lt;%# ImageFromFile((string)Eval("FileName"), 100, 100) %&amp;gt;'&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: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="COLOR: #800000"&gt;Panel&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="COLOR: #008000"&gt;                &amp;lt;!-- TODO: HoverMenu and Panel --&amp;gt;&lt;/span&gt;
&lt;span style="COLOR: #0000ff"&gt;            &amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;ItemTemplate&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: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="COLOR: #800000"&gt;DataList&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;ContentTemplate&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: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="COLOR: #800000"&gt;UpdatePanel&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/fieldset&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;现在，当您点击右边的类别时，可以发现左边的图片展示框的更新，但是页面并没有重新加载。我们的示例将从这里开始，它已经提供了一个不错的用户体验（老赵：您可以打开DemoStart.aspx查看效果）。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;我们第一件需要做的事情就是在页面顶端添加AjaxControlToolkit的注册标签，这样才能够使用Toolkit的功能。这只是一个简单的Tag，引用了AjaxControlToolkit的程序集，并定义了Namespace，然后给定了一个Tag前缀，在这里我们使用&amp;#8220;ajaxToolkit&amp;#8221;，当然您也可以使用任意的前缀。如下：&lt;/p&gt;
&lt;fieldset&gt;&lt;legend style="FONT-FAMILY: verdana"&gt;Register ASP.NET AJAX Control Toolkit&lt;/legend&gt;
&lt;pre style="MARGIN: 5px"&gt;&lt;span style="COLOR: #008000"&gt;&amp;lt;!-- TODO: Register --&amp;gt;&lt;/span&gt;
&lt;span style="COLOR: black; BACKGROUND-COLOR: #ffff00"&gt;&amp;lt;%&amp;#64; Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="ajaxToolkit" %&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/fieldset&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;首先我们需要做的就是增强我们页面下方的搜索框，我们这里使用TextBoxWatermarkExtender，它允许我为页面中的文本框增加水印效果，可以告诉用户在这个文本框中应该输入什么内容。这个很容易做到：&lt;/p&gt;
&lt;fieldset&gt;&lt;legend style="FONT-FAMILY: verdana"&gt;TextBoxWatermarkExtender&lt;/legend&gt;
&lt;pre style="MARGIN: 5px"&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="COLOR: #800000"&gt;Panel&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;ID&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"SearchGroup"&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;CssClass&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"group"&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;
Search:&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;br&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: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="COLOR: #800000"&gt;TextBox&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;ID&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"Search"&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;Width&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"120"&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;br&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: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="COLOR: #800000"&gt;Button&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;ID&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"Submit"&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;Text&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"Go"&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/span&gt;
&lt;span style="COLOR: #008000"&gt;    &amp;lt;!-- TODO: TextBoxWatermark --&amp;gt;&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: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="COLOR: #008000"&gt;        &amp;lt;!-- div works around browser bug for margin-bottom collapse --&amp;gt;&lt;/span&gt;
&lt;span style="COLOR: #0000ff"&gt;        &amp;lt;&lt;/span&gt;&lt;span style="COLOR: #c71585"&gt;ajaxToolkit&lt;/span&gt;:&lt;span style="COLOR: #800000"&gt;TextBoxWatermarkExtender&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;ID&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"TextBoxWatermarkExtender2"&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;            TargetControlID&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"Search"&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;WatermarkText&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"Type query"&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;WatermarkCssClass&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"watermark"&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;div&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: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="COLOR: #800000"&gt;Panel&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/fieldset&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;当我们将一个Extender添加到页面中之后，看到几个属性，其中最重要的属性就是TargetControlID，它指定了Extender需要操作的控件的ID，在这里我们就指定那个搜索用的文本框。在设计模式里我们可以在PropertyGrid中看到这个文本框有了一个附加的属性。如图（点击小图可查看大图）：&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;a href="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV344.NETAJAXControlToolkit_9271/TechEd2006DEV344_5%5B1%5D.jpg" atomicselection="true"&gt;&lt;img style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height=240 src="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV344.NETAJAXControlToolkit_9271/TechEd2006DEV344_5.jpg" width=187 border=0&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;这里每一个属性都与Extender本身相对应。WatermarkText表示在水印效果时文本框内显示的文本。那么什么是WatermarkCssClass属性呢？WatermarkCssClass是我们希望在水印效果时，应用在那个控件上的CSS类。如图：&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;img style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height=145 src="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV344.NETAJAXControlToolkit_9271/TechEd2006DEV344_6%5B2%5D.jpg" width=240 border=0&gt; &lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;我们再回到页面。我们接着再为每个选择图片类别的Panel各添加一个CollapsiblePanelExtender。代码如下：&lt;/p&gt;
&lt;fieldset&gt;&lt;legend style="FONT-FAMILY: verdana"&gt;CollapsiblePanelExtender&lt;/legend&gt;
&lt;pre style="MARGIN: 5px"&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="COLOR: #800000"&gt;Panel&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;ID&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"PopularGroup"&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;CssClass&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"group"&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: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="COLOR: #800000"&gt;Panel&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;ID&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"PopularHeader"&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;"cursor: pointer"&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: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="COLOR: #800000"&gt;Label&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;ID&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"PopularLabel"&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;Text&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"Popular Groups"&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: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="COLOR: #800000"&gt;Panel&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: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="COLOR: #800000"&gt;Panel&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;ID&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"PopularContent"&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;span style="COLOR: #0000ff"&gt;        &amp;lt;&lt;/span&gt;&lt;span style="COLOR: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="COLOR: #800000"&gt;LinkButton&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;ID&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"LinkButton1"&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;Pretty images&lt;span style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="COLOR: #800000"&gt;LinkButton&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;br&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/span&gt;
&lt;span style="COLOR: #0000ff"&gt;&lt;span style="COLOR: #0000ff"&gt;        &lt;/span&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="COLOR: #800000"&gt;LinkButton&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;ID&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"LinkButton2"&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;Cool images&lt;span style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="COLOR: #800000"&gt;LinkButton&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;br&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/span&gt;
&lt;span style="COLOR: #0000ff"&gt;&lt;span style="COLOR: #0000ff"&gt;        &lt;/span&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="COLOR: #800000"&gt;LinkButton&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;ID&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"LinkButton3"&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;Neat images&lt;span style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="COLOR: #800000"&gt;LinkButton&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;br&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/span&gt;
&lt;span style="COLOR: #0000ff"&gt;&lt;span style="COLOR: #0000ff"&gt;        &lt;/span&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="COLOR: #800000"&gt;LinkButton&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;ID&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"LinkButton4"&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;Silly images&lt;span style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="COLOR: #800000"&gt;LinkButton&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;br&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/span&gt;
&lt;span style="COLOR: #0000ff"&gt;&lt;span style="COLOR: #0000ff"&gt;    &lt;/span&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="COLOR: #800000"&gt;Panel&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="COLOR: #008000"&gt;    &amp;lt;!-- TODO: CollapsiblePanel --&amp;gt;&lt;/span&gt;
&lt;span style="COLOR: #0000ff"&gt;    &amp;lt;&lt;/span&gt;&lt;span style="COLOR: #c71585"&gt;ajaxToolkit&lt;/span&gt;:&lt;span style="COLOR: #800000"&gt;CollapsiblePanelExtender&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;ID&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"CollapsiblePanelExtender1"&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;&lt;span style="COLOR: #0000ff"&gt;        &lt;/span&gt;TargetControlID&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"PopularContent"&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;TextLabelID&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"PopularLabel"&lt;/span&gt;
&lt;span style="COLOR: #ff0000"&gt;&lt;span style="COLOR: #0000ff"&gt;        &lt;/span&gt;CollapsedText&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"Popular Groups ▼"&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;ExpandedText&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"Popular Groups ▲"&lt;/span&gt;
&lt;span style="COLOR: #ff0000"&gt;&lt;span style="COLOR: #0000ff"&gt;        &lt;/span&gt;CollapseControlID&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"PopularHeader"&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;ExpandControlID&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"PopularHeader"&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: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="COLOR: #800000"&gt;Panel&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/fieldset&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;CollapsiblePanelExtender能让我们指定一个Panel，使它能够收缩和展开，如图：&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;img style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height=240 src="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV344.NETAJAXControlToolkit_9271/TechEd2006DEV344_7%5B2%5D.jpg" width=216 border=0&gt; &lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;请看CollapsiblePanelExtender的属性。TargetControlID在这里为PopularContent，表示Extender会操作这个Panel。TextLabelID为NewLabel，我们指定了一个Label，在展开和收缩两种不同状态时会修改这个Label的文字。然后我们通过定义CollapsedText和ExpandedText属性决定了在收缩和展开两种状态下显示在Label中的文字。我们这里使用了Unicode字符来显示那个箭头，当然您也可以在这里使用图片。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;下面我们要添加一个查看大图片的功能。我们在这里可以使用HoverMenuExtender来实现。HoverMenuExtender的功能是当用户将鼠标移动到某个元素时，弹出另外一个UI元素。代码如下：&lt;/p&gt;
&lt;fieldset&gt;&lt;legend style="FONT-FAMILY: verdana"&gt;HoverMenuExtender&lt;/legend&gt;
&lt;pre style="MARGIN: 5px"&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="COLOR: #800000"&gt;DataList&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;ID&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"DataList1"&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;RepeatColumns&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;ItemTemplate&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: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="COLOR: #800000"&gt;Panel&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;ID&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"Panel1"&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;Height&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"100px"&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"100px"&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;CssClass&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"panel"&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="COLOR: #0000ff"&gt;&lt;span style="COLOR: #0000ff"&gt;            &lt;/span&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="COLOR: #800000"&gt;Image&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;ID&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"Image1"&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;&lt;span style="COLOR: #0000ff"&gt;        &lt;span style="COLOR: #0000ff"&gt;        &lt;/span&gt;&lt;/span&gt;ImageUrl&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;'&amp;lt;%# ImageFromFile((string)Eval("FileName"), 100, 100) %&amp;gt;'&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/span&gt;
&lt;span style="COLOR: #0000ff"&gt;&lt;span style="COLOR: #0000ff"&gt;        &lt;/span&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="COLOR: #800000"&gt;Panel&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="COLOR: #008000"&gt;&lt;span style="COLOR: #0000ff"&gt;        &lt;/span&gt;&amp;lt;!-- TODO: HoverMenu and Panel --&amp;gt;&lt;/span&gt;
&lt;span style="COLOR: #0000ff"&gt;&lt;span style="COLOR: #0000ff"&gt;        &lt;/span&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #c71585"&gt;ajaxToolkit&lt;/span&gt;:&lt;span style="COLOR: #800000"&gt;HoverMenuExtender&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;ID&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"HoverMenuExtender1"&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;&lt;span style="COLOR: #0000ff"&gt;            &lt;/span&gt;TargetControlID&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"Panel1"&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;OffsetX&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"50"&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;OffsetY&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"50"&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;PopupControlID&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"Panel2"&lt;/span&gt;
&lt;span style="COLOR: #ff0000"&gt;&lt;span style="COLOR: #ff0000"&gt;&lt;span style="COLOR: #0000ff"&gt;            &lt;/span&gt;&lt;/span&gt;HoverCssClass&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"panelHover"&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;DynamicControlID&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"Label1"&lt;/span&gt;
&lt;span style="COLOR: #ff0000"&gt;&lt;span style="COLOR: #ff0000"&gt;&lt;span style="COLOR: #0000ff"&gt;            &lt;/span&gt;&lt;/span&gt;DynamicServiceMethod&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"GetDetails"&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;DynamicContextKey&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;'&amp;lt;%# Eval("FileName") %&amp;gt;'&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/span&gt;
&lt;span style="COLOR: #0000ff"&gt;&lt;span style="COLOR: #ff0000"&gt;&lt;span style="COLOR: #0000ff"&gt;        &lt;/span&gt;&lt;/span&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="COLOR: #800000"&gt;Panel&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;ID&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"Panel2"&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;CssClass&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"popup"&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;Style&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"display: none"&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="COLOR: #0000ff"&gt;&lt;span style="COLOR: #ff0000"&gt;&lt;span style="COLOR: #0000ff"&gt;            &lt;/span&gt;&lt;/span&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="COLOR: #800000"&gt;Label&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;ID&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"Label1"&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;span style="COLOR: #0000ff"&gt;        &amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="COLOR: #800000"&gt;Panel&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;ItemTemplate&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: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="COLOR: #800000"&gt;DataList&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/fieldset&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;对于HoverMenuExtender来说，TargetControlID为响应鼠标移动的控件，在这里就是显示图片的Panel1。PopupControlID指定了弹出的控件，因此我们添加Panel2用来作为弹出的UI。另外可以发现，在HoverMenuExtender的DynamicServiceMethod属性设定了GetDetails方法，而DynamicContextKey则设定了图片名。HoverMenuExtender提供了这样一个功能，比如在UI显示之前从服务器端更新内容，这样我们就能控制在UI中显示的内容。因此我们会在页面中添加一个静态方法：&lt;/p&gt;
&lt;fieldset&gt;&lt;legend style="FONT-FAMILY: verdana"&gt;GetDetails方法（定义在After.aspx.cs中）&lt;/legend&gt;
&lt;pre style="MARGIN: 5px"&gt;[System.Web.Services.WebMethod]
[Microsoft.Web.Script.Services.ScriptMethod()]
&lt;span style="COLOR: #0000ff"&gt;public&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;static&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;string&lt;/span&gt; GetDetails(&lt;span style="COLOR: #0000ff"&gt;string&lt;/span&gt; contextKey)
{
&lt;span style="COLOR: #0000ff"&gt;    foreach&lt;/span&gt; (ImageInfo ii &lt;span style="COLOR: #0000ff"&gt;in&lt;/span&gt; data)
&lt;span style="COLOR: #0000ff"&gt;    &lt;/span&gt;{
&lt;span style="COLOR: #0000ff"&gt;&lt;span style="COLOR: #0000ff"&gt;    &lt;span style="COLOR: #0000ff"&gt;    &lt;/span&gt;&lt;/span&gt;if&lt;/span&gt; (ii.FileName == contextKey)
&lt;span style="COLOR: #0000ff"&gt;    &lt;span style="COLOR: #0000ff"&gt;    &lt;/span&gt;&lt;/span&gt;{
&lt;span style="COLOR: #0000ff"&gt;&lt;span style="COLOR: #0000ff"&gt;    &lt;span style="COLOR: #0000ff"&gt;    &lt;span style="COLOR: #0000ff"&gt;    &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;return&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;string&lt;/span&gt;.Format(
&lt;span style="COLOR: #0000ff"&gt;    &lt;span style="COLOR: #0000ff"&gt;    &lt;span style="COLOR: #0000ff"&gt;    &lt;span style="COLOR: #0000ff"&gt;    &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;"&lt;span style="COLOR: #8b0000"&gt;&amp;lt;img src='{0}'&amp;gt;&amp;lt;br/&amp;gt;Name: {1}&amp;lt;br/&amp;gt;Dimensions: {2} pixels&amp;lt;br/&amp;gt;Size: {3} bytes&lt;/span&gt;",
&lt;span style="COLOR: #0000ff"&gt;    &lt;span style="COLOR: #0000ff"&gt;    &lt;span style="COLOR: #0000ff"&gt;    &lt;span style="COLOR: #0000ff"&gt;    &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;ImageFromFile(ii.FileName, 300, 250), ii.Name, ii.Dimensions, ii.Size);
&lt;span style="COLOR: #0000ff"&gt;    &lt;span style="COLOR: #0000ff"&gt;    &lt;/span&gt;&lt;/span&gt;}
&lt;span style="COLOR: #0000ff"&gt;    &lt;/span&gt;}
&lt;span style="COLOR: #0000ff"&gt;&lt;span style="COLOR: #0000ff"&gt;    &lt;/span&gt;return&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;string&lt;/span&gt;.Format("&lt;span style="COLOR: #8b0000"&gt;[Missing image: {0}]&lt;/span&gt;", contextKey);
}&lt;/pre&gt;
&lt;/fieldset&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;现在重新打开页面可以发现，当鼠标指向图片时，将会弹出一个UI，其中显示了大图及其详细信息。如下（点击小图可查看大图）：&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;a href="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV344.NETAJAXControlToolkit_F8C6/TechEd2006DEV344_8%5B1%5D.jpg" atomicselection="true"&gt;&lt;img style="BORDER-RIGHT: 0px; BORDER-TOP: 0px; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px" height=216 src="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV344.NETAJAXControlToolkit_F8C6/TechEd2006DEV344_8.jpg" width=240 border=0&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;现在还有一个比较让用户迷惑的就是，在点击分类中的每一项时，左边的图片需要等一段时间才能刷新。我们也需要提高这里的用户体验。之前我们在页面里使用了UpdatePanel，我们现在为它添加动画，以提醒用户UpdatePanel正在更新，所以我们在这里使用另一个组件：UpdatePanelAnimationExtender：&lt;/p&gt;
&lt;fieldset&gt;&lt;legend style="FONT-FAMILY: verdana"&gt;UpdatePanelAnimationExtender&lt;/legend&gt;
&lt;pre style="MARGIN: 5px"&gt;&lt;span style="COLOR: #008000"&gt;&amp;lt;!-- TODO: UpdatePanelAnimation --&amp;gt;&lt;/span&gt;
&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #c71585"&gt;ajaxToolkit&lt;/span&gt;:&lt;span style="COLOR: #800000"&gt;UpdatePanelAnimationExtender&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;&lt;span style="COLOR: #0000ff"&gt;    &lt;/span&gt;ID&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"UpdatePanelAnimationExtender1"&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;TargetControlID&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"UpdatePanel1"&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="COLOR: #0000ff"&gt;&lt;span style="COLOR: #0000ff"&gt;    &lt;/span&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;Animations&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="COLOR: #0000ff"&gt;&lt;span style="COLOR: #0000ff"&gt;    &lt;span style="COLOR: #0000ff"&gt;    &lt;/span&gt;&lt;/span&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;OnUpdating&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="COLOR: #0000ff"&gt;&lt;span style="COLOR: #0000ff"&gt;    &lt;span style="COLOR: #0000ff"&gt;    &lt;span style="COLOR: #0000ff"&gt;    &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;FadeOut&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;AnimationTarget&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"Fader"&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;MinimumOpacity&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"0.2"&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;Duration&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"0.25"&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/span&gt;
&lt;span style="COLOR: #0000ff"&gt;&lt;span style="COLOR: #0000ff"&gt;    &lt;span style="COLOR: #0000ff"&gt;    &lt;/span&gt;&lt;/span&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;OnUpdating&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="COLOR: #0000ff"&gt;&lt;span style="COLOR: #0000ff"&gt;    &lt;span style="COLOR: #0000ff"&gt;    &lt;/span&gt;&lt;/span&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;OnUpdated&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="COLOR: #0000ff"&gt;&lt;span style="COLOR: #0000ff"&gt;    &lt;span style="COLOR: #0000ff"&gt;    &lt;span style="COLOR: #0000ff"&gt;    &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;FadeIn&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;AnimationTarget&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"Fader"&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;MinimumOpacity&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"0.2"&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;Duration&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"0.25"&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/span&gt;
&lt;span style="COLOR: #0000ff"&gt;&lt;span style="COLOR: #0000ff"&gt;    &lt;span style="COLOR: #0000ff"&gt;    &lt;/span&gt;&lt;/span&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;OnUpdated&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="COLOR: #0000ff"&gt;&lt;span style="COLOR: #0000ff"&gt;    &lt;/span&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;Animations&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: #c71585"&gt;ajaxToolkit&lt;/span&gt;:&lt;span style="COLOR: #800000"&gt;UpdatePanelAnimationExtender&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/fieldset&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;在这里，TargetControlID指定的是UpdatePanel1。在这里有一段XML，Toolkit提供了一套完整的动画类库以供客户端使用，它们都完全使用了JavaScript和DHTML编写。现在这段XML的含义是：在UpdatePanel在向服务器端请求数据时会出现淡出效果，而得到数据后会产生淡入的效果。现在当切换类别时就会出现淡出的效果，当更新结束后，图片区域就会淡入。效果如下（点击小图可查看大图）：&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;a href="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV344.NETAJAXControlToolkit_F8C6/TechEd2006DEV344_9%5B1%5D.jpg" atomicselection="true"&gt;&lt;img style="BORDER-RIGHT: 0px; BORDER-TOP: 0px; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px" height=216 src="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEdEuropeDEV344.NETAJAXControlToolkit_F8C6/TechEd2006DEV344_9.jpg" width=240 border=0&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;这种方式使用户能够更清晰地了解到页面正在更新中。正如我刚才提到了，Toolkit提供了一套完整的动画类库，您可以使用各种组合来得到各种效果。在下载Toolkit的站点上，我们提供了4份参考文档来解释Animation的使用，例如SizeAnimation，MoveAnimation，FadeIn/FadeOutAnimation等等，您可以将它们组合起来得到各种有趣的效果。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;好，以上就是演示应该如何在已有的站点中使用ASP.NET AJAX Control Toolkit的例子。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&amp;nbsp;&lt;/p&gt;</description>
      <comments>http://blog.zhaojie.me/2006/11/lecture-teched-europe-dev344-1.html#comments</comments>
      <pubDate>Wed, 15 Nov 2006 10:23:00 GMT</pubDate>
      <lastBuildDate>Wed, 15 Nov 2006 10:23:00 GMT</lastBuildDate>
    </item>
    <item>
      <author>jeffz@live.com (老赵)</author>
      <category domain="http://blog.zhaojie.me/speech/">培训演讲</category>
      <category domain="http://blog.zhaojie.me/translation/">翻译引进</category>
      <category domain="http://blog.zhaojie.me/news/">新闻信息</category>
      <title>推荐：体验TechEd 2006 Europe Edition</title>
      <link>http://blog.zhaojie.me/2006/11/teched-2006-europe-edition.html</link>
      <guid>http://blog.zhaojie.me/2006/11/teched-2006-europe-edition.html</guid>
      <description>&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&lt;img style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height=145 src="http://img.zhaojie.me/blog/WindowsLiveWriter/TechEd2006EuropeEdition_121EF/fourdays_right2%5B8%5D.jpg" width=499 border=0&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;TechEd 2006 China不久刚落下帷幕，TechEd 2006 Europe Edition又在西班牙巴塞罗那风风火火地开始了。微软为这次盛会专门准备一个网站来介绍它的一切。在这个站点里您能够看到此次盛会的大量相关信息，当然也有Virtual Side，不过最重要的就是其中有部分讲座的视频！这些都是优秀的资源。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;这次盛会的内容自然相当丰富，不过比较吸引我的就是在TechEd 2006 Europe Edition中也包含了ASP.NET AJAX的内容，ASP.NET AJAX Beta 2的到来也使人们对于ASP.NET AJAX的真正发布翘首以盼。似乎此次的Beta 2和正式版的区别也不是很大了。&lt;/p&gt;
&lt;iframe style="DISPLAY: none; VISIBILITY: hidden" src="http://blog.zhaojie.me/2006/11/558960.html" width=0 height=0&gt;&lt;/iframe&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;TechEd 2006 Europe Edition的日期是11月6日-10日，和11月13日到17日，这个站点上的内容应该也会进行不断地更新。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;这里推荐一下TechEd 2006 Europe Edition - Developers的网站：&lt;a href="http://www.mseventseurope.com/TechEd/06/pre/defaultDev.aspx"&gt;http://www.mseventseurope.com/TechEd/06/pre/defaultDev.aspx&lt;/a&gt;。还有它的Virtual Side：&lt;a href="http://www.mseventseurope.com/TechEd/06/pre/Live/DefaultDev.aspx"&gt;http://www.mseventseurope.com/TechEd/06/pre/Live/DefaultDev.aspx&lt;/a&gt;。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;另外，还需要推荐一下Virtual Pressroom：&lt;a href="http://www.microsoft.com/emea/presscentre/teched/default.mspx"&gt;http://www.microsoft.com/emea/presscentre/teched/default.mspx&lt;/a&gt;。&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;如果您对于ASP.NET AJAX有兴趣的话，那么可能下面两个视频您可能就不应该错过了，它们都是在这次TechEd Europe上的演讲：&lt;/p&gt;
&lt;ol style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;
    &lt;li&gt;&lt;a href="http://www.microsoft.com/emea/msdnshowtime/sessionl.aspx?videoid=320" target=_blank&gt;ASP.NET AJAX Control Toolkit Unleashed: Creating Rich Client-Side Controls and Components&lt;/a&gt; by Shawn Burke - Development manager at Microsoft's Windows Forms team
    &lt;li&gt;&lt;a href="http://www.microsoft.com/emea/msdnshowtime/sessionh.aspx?videoid=331" target=_blank&gt;AJAX Patterns with the Microsoft AJAX Library&lt;/a&gt; by Jeff Prosise - Co-founder of Wintellect and Microsoft .NET programmer &lt;/li&gt;
&lt;/ol&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;这些都是MSDN's Showtime的视频，有兴趣的朋友也可以看看上面的其他资源。以后我也会将我认为比较有价值的视频推荐给大家。:)&lt;/p&gt;
&lt;p style="FONT-SIZE: 10pt; FONT-FAMILY: verdana"&gt;不过似乎上面的视频都需要再现观看，这对于网络质量有着一定的要求，而且对于这些英语的演讲，有些朋友可能会比较难以接受。因此我想，我会在接下来的时间里，会将一些我觉得比较有价值的部分为大家介绍一下，尤其会着重对于它的演示代码进行Step by Step地演示和分析。这些大会上的代码都非常优秀，也有很高的参考价值，例如早在Atlas CTP阶段，在Mix06上的示例大都成为了Atlas官方示例了。另外，如果这些代码比较难以部署和使用的话，我也会在文章进行一些讲解。这样大家就能在示例代码上进行修改和学习了。&lt;/p&gt;</description>
      <comments>http://blog.zhaojie.me/2006/11/teched-2006-europe-edition.html#comments</comments>
      <pubDate>Tue, 14 Nov 2006 12:37:00 GMT</pubDate>
      <lastBuildDate>Tue, 14 Nov 2006 12:37:00 GMT</lastBuildDate>
    </item>
    <item>
      <author>jeffz@live.com (老赵)</author>
      <category domain="http://blog.zhaojie.me/translation/">翻译引进</category>
      <category domain="http://blog.zhaojie.me/asp-net/">ASP.NET</category>
      <category domain="http://blog.zhaojie.me/front-end/">前端表现</category>
      <title>从Atlas到Microsoft ASP.NET AJAX（9） - Using the Value-add Scripts</title>
      <link>http://blog.zhaojie.me/2006/10/from-atlas-to-microsoft-asp-net-ajax-9.html</link>
      <guid>http://blog.zhaojie.me/2006/10/from-atlas-to-microsoft-asp-net-ajax-9.html</guid>
      <description>&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"&gt;&lt;span style="FONT-SIZE: 18pt; COLOR: #339966"&gt;Using the Value-add Scripts&lt;/span&gt;&lt;br&gt;&lt;br&gt;在CTP版本中，您只需简单地将一个&lt;strong&gt;ScriptManager&lt;/strong&gt;控件加到页面中，默认的CTP核心功能（&lt;strong&gt;Atlas.js&lt;/strong&gt;）就被添加了。不过其它一些脚本是可选的，例如AtlasUIGlitz.js文件。如果您要使用它们，则需要手动地将其加入&lt;strong&gt;ScriptManager&lt;/strong&gt;的references中，或者将他们定义在XML-Script的&lt;strong&gt;&amp;lt;refereces /&amp;gt;&lt;/strong&gt;里。&lt;br&gt;&lt;br&gt;在RTM版本中，为了使用Value-add里的功能，您必须在&lt;strong&gt;ScriptManager&lt;/strong&gt;中添加特定的脚本引用。下面的例子展示了如何引用Value-add中定义的所有脚本。&lt;br&gt;&lt;br&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;p&gt;&lt;strong&gt;注意：&lt;/strong&gt;在这里，注册的顺序非常重要，它表明了一个&amp;#8220;dependency chain&amp;#8221;。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #ffff88"&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;asp:ScriptManager&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;runat&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;=&amp;#8221;server&amp;#8221;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;id&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;=&amp;#8221;ScriptManager1&amp;#8221;&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #993300"&gt;&amp;lt;Scripts&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;asp:ScriptReference&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;Assembly&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="Microsoft.Web.Preview"&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&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; Name&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="Microsoft.Web.Resources.ScriptLibrary.PreviewScript.js"&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=#ff0000&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;asp:ScriptReference&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;Assembly&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="Microsoft.Web.Preview"&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&amp;nbsp;&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;Name&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="Microsoft.Web.Resources.ScriptLibrary.PreviewGlitz.js"&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&lt;font color=#ff0000&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;asp:ScriptReference&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;Assembly&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="Microsoft.Web.Preview"&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&amp;nbsp;&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;Name&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="Microsoft.Web.Resources.ScriptLibrary.PreviewDragDrop.js"&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;Scripts&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;ScriptManager&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;br&gt;&lt;br&gt;&lt;span style="FONT-SIZE: 14pt"&gt;Client-based and Server-based Types&lt;/span&gt;&lt;br&gt;&lt;br&gt;定义在Value-add脚本中的类型从CTP版本中的&lt;strong&gt;Sys.*&lt;/strong&gt;命名空间转移到了&lt;strong&gt;Sys.Preview.*&lt;/strong&gt;中。这确保了功能上的明显区别。从CTP转移到Value-add脚本的开发人员需要更新他们的JavaScript代码。例如，&lt;strong&gt;Sys.Services.Components.Profile&lt;/strong&gt;组件现在已经变成了&lt;strong&gt;Sys.Preview.Services.Components.Profile&lt;/strong&gt;。&lt;br&gt;&lt;br&gt;相似地，使用CTP版本中服务器控件的开发人员在转移到Value-add时，则必须更新Web.config文件，以使用新的命名空间：&lt;strong&gt;Microsoft.Web.Preview.*&lt;/strong&gt;。例如，&lt;strong&gt;Microsoft.Web.UI.Controls.DragOverlayExtender&lt;/strong&gt;现在已经变成了&lt;strong&gt;Microsoft.Web.Preview.UI.Controls.DragOverlayExtender&lt;/strong&gt;。&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;span style="FONT-SIZE: 14pt"&gt;XML-Script&lt;/span&gt;&lt;br&gt;&lt;br&gt;在Value-add包内依旧能够使用XML-Script，但是由于RTM版本的影响，必须作一些改变。另外，XML-Script的功能也得到了增强。&lt;br&gt;&lt;br&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;p&gt;&lt;strong&gt;注意：&lt;/strong&gt;XML-Script标签不是大小写敏感的。然而，一些特定的属性和它们的值是大小写相关的，因此可能需要对您的应用程序做一些修改。&lt;/p&gt;
&lt;/blockquote&gt;　　XML-Script的标签名直接使用了类型名称，在CTP版本中内置的下列标签在Value-add包中被改变了：&lt;br&gt;
&lt;div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #eeeeee"&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;opacity&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;layout&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;autoComplete&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;setProperty&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;invokeMethod&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;serviceMethod&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;postback&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;select&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;br&gt;在Value-add包中，上述标签名变成了：&lt;br&gt;
&lt;div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #ffff88"&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;opacityBehavior&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;layoutBehavior&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;autoCompleteBehavior&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;setPropertyAction&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;invokeMethodAction&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;serviceMethodRequest&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;postbackAction&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;selector&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;br&gt;&lt;br&gt;&lt;span style="FONT-SIZE: 14pt"&gt;Defining Tag Prefixes&lt;/span&gt;&lt;br&gt;&lt;br&gt;XML标签依旧使用内置的脚本前缀。另外，对自定义前缀的支持被增强了，它使用了如下的语法。这允许开发人员使用逗号来分隔命名空间的标记。&lt;br&gt;
&lt;div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #ffff88"&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;script&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;type&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="text/xml-script"&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;page&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;xmlns:script&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="http://schemas.microsoft.com/xml-script/2005"&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;xmlns&lt;span style="COLOR: #0000ff"&gt;="JavaScript:&amp;nbsp;Sys.UI,&amp;nbsp;Sys"&lt;/span&gt;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;components&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&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;...&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;components&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;page&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&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: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;br&gt;
&lt;fieldset&gt;&lt;legend&gt;Comment&lt;/legend&gt;　　事实上，在原文中出现的是&amp;#8220;xmlns:"JavaScirpt: Sys.UI, Sys"&amp;#8221;而不是&amp;#8220;xmlns="JavaScript: Sys.UI, Sys"&amp;#8221;，我在阅读代码之后作了纠正。&lt;/fieldset&gt;&lt;br&gt;&lt;br&gt;&lt;span style="FONT-SIZE: 14pt"&gt;Creating Declarative Bindings&lt;/span&gt;&lt;br&gt;&lt;br&gt;CTP版本中的Binding被转移到了Value-add脚本中，并且它能够支持在各种级别中使用，而无须嵌套在某个特定的控件中。当它被嵌套在某个控件中时，binding会从它父控件得到上下文或者数据源。下面的代码能够同时在CTP和Value-add中正确使用binding：&lt;br&gt;
&lt;div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #eeeeee"&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;script&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;type&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="text/xml-script"&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;page&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;xmlns:script&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="http://schemas.microsoft.com/xml-script/2005"&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;components&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&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;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;textbox&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;id&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="Name"&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&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;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;label&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;id&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="FirstName"&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&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;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;bindings&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;binding&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;dataContext&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="Name"&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&amp;nbsp;dataPath&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="text"&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&amp;nbsp;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;property&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="text"&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;&amp;nbsp;&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;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;bindings&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&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;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;label&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;components&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;page&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&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: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;br&gt;在Value-add包中，binding的propertyKey属性能够支持&amp;#8220;.&amp;#8221;的使用，这允许您指定某个特定的子属性。对于某些已经从&lt;strong&gt;Control&lt;/strong&gt;基类被移除的属性（例如&lt;strong&gt;visible&lt;/strong&gt;），您能够通过子属性来访问到它们。下面的示例展示了如何设定一个Button元素的style属性。&lt;br&gt;
&lt;div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #ffff88"&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;script&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;type&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="text/xml-script"&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;page&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;xmlns:script&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="http://schemas.microsoft.com/xml-script/2005"&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;xmlns:"JavaScript:&amp;nbsp;Sys.UI, Sys"&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;components&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&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;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;textbox&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;id&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="Name"&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&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;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;label&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;id&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="FirstName"&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&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;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;bindings&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;binding&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;dataContext&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="Name"&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&amp;nbsp;dataPath&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="text"&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&amp;nbsp;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;property&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="text"&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&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;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;bindings&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&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;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;label&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&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;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;button&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;id&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="button2"&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&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;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;click&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;setPropertyAction&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;target&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="text1"&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&amp;nbsp;property&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="element"&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&amp;nbsp;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;propertyKey&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="style.borderColor"&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&amp;nbsp;value&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="black"&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&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;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;click&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&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;&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;span style="COLOR: #000000"&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;components&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;page&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&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: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;br&gt;这个示例也展示了action的使用方式：&lt;strong&gt;setPropertyAction&lt;/strong&gt;在&lt;strong&gt;Button&lt;/strong&gt;控件的click事件触发时被调用。&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;span style="FONT-SIZE: 14pt"&gt;References&lt;/span&gt;&lt;br&gt;&lt;br&gt;在CTP版本中您能够在XML-Script添加对于脚本的引用，在Value-add Beta版本中并没有支持这个功能。RTM版本很可能会解决这个问题。&lt;br&gt;&lt;/span&gt;</description>
      <comments>http://blog.zhaojie.me/2006/10/from-atlas-to-microsoft-asp-net-ajax-9.html#comments</comments>
      <pubDate>Sun, 22 Oct 2006 18:48:00 GMT</pubDate>
      <lastBuildDate>Sun, 22 Oct 2006 18:48:00 GMT</lastBuildDate>
    </item>
    <item>
      <author>jeffz@live.com (老赵)</author>
      <category domain="http://blog.zhaojie.me/translation/">翻译引进</category>
      <category domain="http://blog.zhaojie.me/asp-net/">ASP.NET</category>
      <category domain="http://blog.zhaojie.me/front-end/">前端表现</category>
      <title>从Atlas到Microsoft ASP.NET AJAX（8） - UpdatePanel Control</title>
      <link>http://blog.zhaojie.me/2006/10/from-atlas-to-microsoft-asp-net-ajax-8.html</link>
      <guid>http://blog.zhaojie.me/2006/10/from-atlas-to-microsoft-asp-net-ajax-8.html</guid>
      <description>&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"&gt;&lt;span style="FONT-SIZE: 18pt; COLOR: #339966; FONT-FAMILY: Verdana"&gt;UpdatePanel&lt;/span&gt;&lt;br&gt;&lt;br&gt;对于&lt;strong&gt;UpdatePanel&lt;/strong&gt;控件的使用是ASP.NET AJAX Extentions的重要部分。我们收到了关于它和&lt;strong&gt;UpdateProgress&lt;/strong&gt;控件的大量用户反馈。为了增强局部刷新的功能我们作了多处修改，并加强了&lt;strong&gt;UpdatePanel&lt;/strong&gt;对于控件的兼容性。我们也为异步PoskBack实现了一个丰富的事件模型，这样您就可以在客户端响应它们并对页面更新提供额外操作了。&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;span style="FONT-SIZE: 14pt"&gt;ScriptManager Control&lt;/span&gt;&lt;br&gt;&lt;br&gt;在RTM版本中，&lt;strong&gt;ScriptManager&lt;/strong&gt;有一个&lt;strong&gt;EnablePartialRendering&lt;/strong&gt;属性，其默认值为&lt;strong&gt;true&lt;/strong&gt;，这减少了使用&lt;strong&gt;UpdatePanel&lt;/strong&gt;来做异步的页面局部刷新所需的步骤。&lt;br&gt;&lt;br&gt;为了降低控件的复杂程度，&lt;strong&gt;ScriptManager&lt;/strong&gt;的&lt;strong&gt;ErrorTemplate&lt;/strong&gt;属性在RTM版本中被去除了。现在错误处理的模型变得更加灵活，例如您可以为它创建一个独立的服务器控件。另外，您现在也可以使用&lt;strong&gt;ScriptManager&lt;/strong&gt;的&lt;strong&gt;AsyncPostBackErrorMessage&lt;/strong&gt;属性，不过它只是设置了默认的错误信息，如果您需要动态地自定义的错误信息的话，您可以使用&lt;strong&gt;AsyncPostBackError&lt;/strong&gt;事件。&lt;br&gt;&lt;br&gt;现在&lt;strong&gt;ScriptManager&lt;/strong&gt;暴露出了一个新的属性&lt;strong&gt;AsyncPostBackTimeout&lt;/strong&gt;，以此控制异步PostBack的超时时间。&lt;br&gt;&lt;br&gt;值得一提的是，服务器控件目前可能会使用到&lt;strong&gt;ScriptManager&lt;/strong&gt;中新增的注册方法。这个方法增加了对于&lt;strong&gt;UpdatePanel&lt;/strong&gt;使用的支持，并减少了CTP版本中&lt;strong&gt;UpdatePanel&lt;/strong&gt;的复杂性。现在的资源已经包括了脚本，样式表，Hidden Field等。&lt;strong&gt;ClientScriptManager&lt;/strong&gt;中的方法与上述方法相对应。它们能够接受一个控件实例作为参数，这样如果在&lt;strong&gt;UpdatePanel&lt;/strong&gt;中使用这些控件，他们所需的脚本就能被正确跟踪了。&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;span style="FONT-SIZE: 14pt"&gt;Dynamic UpdatePanel Controls&lt;/span&gt;&lt;br&gt;&lt;br&gt;现在有两种在页面中动态添加&lt;strong&gt;UpdatePanel&lt;/strong&gt;的方法，这是RTM版本中最大的改进。使用动态&lt;strong&gt;UpdatePanel&lt;/strong&gt;的方法是：&lt;br&gt;
&lt;ul&gt;
    &lt;li&gt;编写自定义控件的开发人员现在能够将&lt;strong&gt;UpdatePanel&lt;/strong&gt;控件添加到组合控件中。这样，只要页面中存在&lt;strong&gt;ScriptManager&lt;/strong&gt;并且其&lt;strong&gt;EnablePartialRendering&lt;/strong&gt;设为&lt;strong&gt;true&lt;/strong&gt;，这样就能使用该自定义控件并得到局部刷新的体验了。并且，如果页面中没有&lt;strong&gt;ScriptManager&lt;/strong&gt;，也能在传统PostBack模型中正常使用该控件。
    &lt;li&gt;页面开发人员能够在其他控件的模版中添加&lt;strong&gt;UpdatePanel&lt;/strong&gt;。 &lt;/li&gt;
&lt;/ul&gt;
　　下面的示例展示了如何在自定义控件中使用&lt;strong&gt;UpdatePanel&lt;/strong&gt;控件。&lt;br&gt;
&lt;div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #ffff88"&gt;&lt;span style="COLOR: #0000ff"&gt;protected&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;override&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;void&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;CreateChildControls()&amp;nbsp;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;base&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;.CreateChildControls();&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ScriptManager&amp;nbsp;sm&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;=&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;ScriptManager.GetCurrent(Page);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Control&amp;nbsp;parent;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Control&amp;nbsp;container;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;if&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;(sm&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;==&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;null&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;||&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;!&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;sm.EnablePartialRendering)&amp;nbsp;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;//&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&amp;nbsp;If&amp;nbsp;not&amp;nbsp;doing&amp;nbsp;partial&amp;nbsp;rendering,&amp;nbsp;use&amp;nbsp;a&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;//&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&amp;nbsp;dummy&amp;nbsp;control&amp;nbsp;as&amp;nbsp;the&amp;nbsp;container.&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;parent&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;=&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;container&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;=&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;new&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;Control();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;else&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;//&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&amp;nbsp;Create&amp;nbsp;an&amp;nbsp;UpdatePanel&amp;nbsp;control.&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;UpdatePanel&amp;nbsp;up&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;=&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;new&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;UpdatePanel();&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;//&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&amp;nbsp;Instead&amp;nbsp;of&amp;nbsp;adding&amp;nbsp;child&amp;nbsp;controls&amp;nbsp;directly&amp;nbsp;to&amp;nbsp;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;//&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&amp;nbsp;the&amp;nbsp;UpdatePanel&amp;nbsp;control,&amp;nbsp;add&amp;nbsp;them&amp;nbsp;to&amp;nbsp;its&amp;nbsp;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;//&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&amp;nbsp;ContentTemplateContainer.&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;container&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;=&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;up.ContentTemplateContainer;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;parent&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;=&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;up;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;AddDataControls(container);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Controls.Add(parent);&lt;br&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;br&gt;&lt;br&gt;&lt;span style="FONT-SIZE: 14pt"&gt;Client Events During Asynchronous Postbacks&lt;/span&gt;&lt;br&gt;&lt;br&gt;在CTP版本中，客户端&lt;strong&gt;PageRequestManager&lt;/strong&gt;对象依靠&lt;strong&gt;XMLHttpRequest&lt;/strong&gt;对象来实现异步的PoskBack并处理&lt;strong&gt;Response&lt;/strong&gt;。在RTM版本中，&lt;strong&gt;PageRequestManager&lt;/strong&gt;对象提供了一个异步PoskBack的生命周期事件，您能够使用它们自定义处理Request和Response的方式。以下为可用的客户端事件，并且提供了事件所需的参数信息：&lt;br&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;strong&gt;initializeRequest&lt;/strong&gt;：您能够使用这个事件来取消即将发送的异步PostBack请求，它也能够让您根据PostBack信息来做一些额外的工作。这个事件的参数为&lt;strong&gt;InitializeRequestEventArgs&lt;/strong&gt;类型。
    &lt;li&gt;&lt;strong&gt;beginRequest&lt;/strong&gt;：您能够使用该事件来启动某些工作，例如您可以在这个事件中显示Progress并且在&lt;strong&gt;endRequest&lt;/strong&gt;事件中再将其隐藏。这个事件的参数为&lt;strong&gt;BeginRequestEventArgs&lt;/strong&gt;。
    &lt;li&gt;&lt;strong&gt;pageLoding&lt;/strong&gt;：您能够使用这个事件中为&lt;strong&gt;UpdatePanel&lt;/strong&gt;的即将更新或删除进行一些额外的工作，例如释放资源。您也可以在响应这个事件时检查服务器端发送过来的自定义信息，以此进行一些自定义工作。这个事件的参数为&lt;strong&gt;PageLoadingEventArgs&lt;/strong&gt;类型。
    &lt;li&gt;&lt;strong&gt;pageLoaded&lt;/strong&gt;：这个事件和&lt;strong&gt;pageLoading&lt;/strong&gt;事件相似，它提供了异步PostBack结果所创建的&lt;strong&gt;UpdatePanel&lt;/strong&gt;的信息。这个事件的参数为&lt;strong&gt;PageLoadedEventArgs&lt;/strong&gt;类型。
    &lt;li&gt;&lt;strong&gt;engRequest&lt;/strong&gt;：您能够使用这个事件来自定义错误处理方式，处理服务器端发送的额外信息等工作。您可以使用它来隐藏&lt;strong&gt;UpdateProgress&lt;/strong&gt;控件。这个事件的参数为&lt;strong&gt;EndRequestEventArgs&lt;/strong&gt;类型。 &lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;&lt;span style="FONT-SIZE: 14pt"&gt;Developing Controls Compatible with the UpdatePanel Control&lt;/span&gt;&lt;br&gt;&lt;br&gt;在CTP版本中，&lt;strong&gt;UpdatePanel&lt;/strong&gt;控件会处理许多被输出的对象，甚至包括不在&lt;strong&gt;UpdatePanel&lt;/strong&gt;中的控件，然后在页面上进行完整的更新。这使一些控件无法和&lt;strong&gt;UpdatePanel&lt;/strong&gt;兼容了。例如，在CTP版本中，如果在&lt;strong&gt;UpdatePanel&lt;/strong&gt;动态添加ASP.NET验证控件的话，它们便无法正确工作了，这种情形在使用&lt;strong&gt;Wizard&lt;/strong&gt;控件的每一步中验证用户输入时尤为常见。&lt;br&gt;&lt;br&gt;在RTM版本中改变了&lt;strong&gt;UpdatePanel&lt;/strong&gt;的模型。您可以使用注册脚本类库相同的办法，向&lt;strong&gt;ScriptManager&lt;/strong&gt;注册将要发送到客户端的脚本或数据。在RTM版本中包括了一组新的ASP.NET验证控件，它们会将自己的脚本使用&lt;strong&gt;ScriptManager&lt;/strong&gt;注册。这些新控件的Tag名与ASP.NET原有的验证控件相对应，因此您不需要改变在页面中声明创建的验证控件。不过，如果在&lt;strong&gt;UpdatePanel&lt;/strong&gt;内部使用了验证控件的话，您需要改变代码以使用新的控件。&lt;br&gt;&lt;br&gt;下面的示例展示了RTM版本中的一个兼容&lt;strong&gt;UpdatePanel&lt;/strong&gt;的自定义控件。如下：&lt;br&gt;
&lt;div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #ffff88"&gt;&lt;span style="COLOR: #0000ff"&gt;protected&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;override&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;void&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;OnPreRender(EventArgs&amp;nbsp;e)&amp;nbsp;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;base&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;.OnPreRender(e);&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Control&amp;nbsp;control&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;=&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;FindControl(_controlID);&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;//&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&amp;nbsp;Register&amp;nbsp;scripts&amp;nbsp;with&amp;nbsp;new&amp;nbsp;ScriptManager&amp;nbsp;APIs.&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;//&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&amp;nbsp;The&amp;nbsp;scripts&amp;nbsp;hook&amp;nbsp;up&amp;nbsp;new&amp;nbsp;PageRequestManager&amp;nbsp;events.&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;string&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;script&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;=&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;String.Format(&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;CultureInfo.InvariantCulture,&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;#64;"&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;var&amp;nbsp;{0}_hover&amp;nbsp;=&amp;nbsp;&lt;br&gt;new&amp;nbsp;Microsoft.Samples.HoverExtender(document.getElementById('{1}'),&amp;nbsp;'{2}');&lt;br&gt;{0}_hover.attach();&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;"&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;,&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ClientID,&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;control.ClientID,&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ColorTranslator.ToHtml(BackgroundColor));&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ScriptManager.RegisterClientScriptInclude(&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;this&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;typeof&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;(HoverExtender),&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;"&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;HoverExtenderScript&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;"&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;,&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ResolveClientUrl(&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;"&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;~/ScriptLibrary/HoverExtender.js&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;"&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;));&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ScriptManager.RegisterStartupScript(&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;this&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;typeof&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;(HoverExtender),&amp;nbsp;ClientID,&amp;nbsp;script,&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;true&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;);&lt;br&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;br&gt;&lt;br&gt;&lt;span style="FONT-SIZE: 14pt"&gt;Sending Additional Data to the Client&lt;/span&gt;&lt;br&gt;&lt;br&gt;在CTP版本中，有个功能比较难以实现，那就是在异步PoskBack页面后，根据从服务器端收到的数据更新UpdatePanel外的控件。在RTM版本中可以通过调用ScriptManager的一个方法将数据注册并输出到页面，以此解决这个问题。&lt;br&gt;&lt;br&gt;试想，如果需要使用服务器的代码来改变客户端的Timer控件的interval和enabled属性的值，但是这个Timer却不在UpdatePanel中。在CTP版本中是无法做到这一点的。&lt;br&gt;&lt;br&gt;在RTM版本中，&lt;strong&gt;ScriptManager&lt;/strong&gt;在服务器段保存了一个字典对象，您可以使用&lt;strong&gt;RegisterDataItem&lt;/strong&gt;方法来更新和注册对象。这个字典会被发送到客户端，您可以在客户端的&lt;strong&gt;pageLoading&lt;/strong&gt;，&lt;strong&gt;pageLoaded&lt;/strong&gt;和&lt;strong&gt;endRequest&lt;/strong&gt;事件中通过&lt;strong&gt;eventArgs.get_dataItems()&lt;/strong&gt;方法获得该字典对象。&lt;br&gt;&lt;br&gt;下面的示例展示了注册数据的方法：&lt;br&gt;
&lt;div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #ffff88"&gt;&lt;span style="COLOR: #008000"&gt;//&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&amp;nbsp;Server&amp;nbsp;control&amp;nbsp;code.&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;...&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;public&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;int&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;interval&amp;nbsp;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;get&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;{...}&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;set&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_data&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;=&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;value;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;}&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;void&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;PreRender()&amp;nbsp;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ScriptManager&amp;nbsp;sm1&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;=&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;ScriptManager.GetCurrent(Page);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;if&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;(sm1&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;!=&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;null&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;sm1.IsInAsyncPostBack)&amp;nbsp;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ScriptManager.RegisterDataItem(&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;this&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;,&amp;nbsp;_data.ToString());&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;//&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&amp;nbsp;The&amp;nbsp;control&amp;nbsp;also&amp;nbsp;needs&amp;nbsp;to&amp;nbsp;register&amp;nbsp;script&amp;nbsp;to&amp;nbsp;handle&amp;nbsp;the&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;//&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&amp;nbsp;endRequest&amp;nbsp;event&amp;nbsp;on&amp;nbsp;the&amp;nbsp;client&amp;nbsp;and&amp;nbsp;retrieve&amp;nbsp;this&amp;nbsp;value.&amp;nbsp;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;//&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&amp;nbsp;The&amp;nbsp;script&amp;nbsp;below&amp;nbsp;adds&amp;nbsp;a&amp;nbsp;handler&amp;nbsp;for&amp;nbsp;the&amp;nbsp;current&amp;nbsp;instance&amp;nbsp;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;//&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&amp;nbsp;of&amp;nbsp;the&amp;nbsp;PageRequestManager&amp;nbsp;object&amp;nbsp;and&amp;nbsp;calls&amp;nbsp;the&amp;nbsp;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;//&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&amp;nbsp;get_dataItem()&amp;nbsp;method&amp;nbsp;from&amp;nbsp;eventArgs.&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ScriptManager.RegisterClientScriptBlock(&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;this&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;this&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;.GetType(),&amp;nbsp;key,&amp;nbsp;script)&lt;br&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;br&gt;
&lt;fieldset&gt;&lt;legend&gt;Comment&lt;/legend&gt;　　上面的代码最有意思的可能是最后一行，它的作用是在客户端的PageRequestManager对象中注册一个endRequest的handler，以此来做一些修改或者别的工作。其实有了这个方法之后，即使没有向客户端输出DataItem的支持，也已经能够在操作客户端对象了。有了DataItem这一功能之后，可能更重要的作用就是能够使服务器端代码和客户端代码分开，分别进行集中地维护。&lt;/fieldset&gt;&lt;br&gt;&lt;br&gt;&lt;span style="FONT-SIZE: 14pt"&gt;Custom Error Handling and Redirection&lt;/span&gt;&lt;br&gt;&lt;br&gt;在CTP版本中并没有提供控制错误的办法，甚至没有自定义错误的设置。在RTM版本中则解决了这个问题。&lt;br&gt;&lt;br&gt;在&lt;strong&gt;ScriptManager&lt;/strong&gt;对象里提供了一个属性：&lt;strong&gt;AllowCustomError&lt;/strong&gt;。当该属性被设为&lt;strong&gt;false&lt;/strong&gt;时，&lt;strong&gt;ScriptManager&lt;/strong&gt;对象会覆盖自定义的错误跳转，并将错误信息发送到客户端，这样您就可以将错误信息显示出来，而避免了页面被转向到其他地方。&lt;br&gt;&lt;br&gt;在RTM版本中是通过一个额外的&lt;strong&gt;Redirct&lt;/strong&gt; Module来控制页面转向的。因此，在RTM版本中已经能够处理跨页面的Posting的情况。&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;span style="FONT-SIZE: 14pt"&gt;Triggers&lt;/span&gt;&lt;br&gt;&lt;br&gt;在CTP版本中，&lt;strong&gt;ScriptManager&lt;/strong&gt;控件使用了&lt;strong&gt;ControlValueTrigger&lt;/strong&gt;和&lt;strong&gt;ControlEventTrigger&lt;/strong&gt;类型，并将它们存放一个触发器集合中，以此将这些触发器绑定到页面的控件上去。在RTM版本中，两者被集中到了一个类型：&lt;strong&gt;AsyncPostBackTrigger&lt;/strong&gt;，以此避免以前的两个触发器可能带来的混乱状况。&lt;br&gt;&lt;br&gt;根据用户反馈，我们增加了一个&lt;strong&gt;PostBackTrigger&lt;/strong&gt;对象，它提供了了从&lt;strong&gt;UpdatePanel&lt;/strong&gt;内部产生页面完全（同步）PostBack的能力。这个&lt;strong&gt;Trigger&lt;/strong&gt;对象现在也能够与实现了&lt;strong&gt;IPostbackEventHandler&lt;/strong&gt;，&lt;strong&gt;IPostbackDataHandler&lt;/strong&gt;或者&lt;strong&gt;INamingContainer&lt;/strong&gt;接口的控件配合使用。&lt;br&gt;&lt;br&gt;&lt;strong&gt;AsyncPostBackTrigger&lt;/strong&gt;能够使&lt;strong&gt;UpdatePanel&lt;/strong&gt;触发异步的PostBack更新。这个触发器也能指向&lt;strong&gt;UpdatePanel&lt;/strong&gt;外部的控件，或者指向控件的层次结构中的父控件。当一个作为naming container的控件被指定为触发器，则它内部的所有控件所引发的PoskBack都和这个触发器的行为相同。&lt;br&gt;&lt;br&gt;下面的例子展示了&lt;strong&gt;AsyncPostBackTrigger&lt;/strong&gt;对象声明形式的使用方法：&lt;br&gt;
&lt;div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #ffff88"&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;asp:Button&amp;nbsp;&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;&amp;nbsp;id&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="Button1"&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&amp;nbsp;Text&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="Go"&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;asp:UpdatePanel&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;ID&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="UP1"&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&amp;nbsp;UpdateMode&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="Conditional"&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&amp;nbsp;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;span style="COLOR: #000000"&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;ContentTemplate&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;span style="COLOR: #000000"&gt;...&lt;/span&gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;ContentTemplate&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;Triggers&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;asp:AsyncPostBackTrigger&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;ControlID&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="Button1"&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;Triggers&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;asp:UpdatePanel&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;br&gt;一个&lt;strong&gt;PostBackTrigger&lt;/strong&gt;能够指向一个&lt;strong&gt;UpdatePanel&lt;/strong&gt;内部的控件，使它能产生普通的PostBack。这些控件必须是当前UpdatePanel内部的控件。&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;span style="FONT-SIZE: 14pt"&gt;UpdateProgress Control&lt;/span&gt;&lt;br&gt;&lt;br&gt;在RTM版本中增强了&lt;strong&gt;UpdateProgress&lt;/strong&gt;控件，使它具有了一个额外的功能：指定一个时间间隔，只有异步PostBack超出这个时间后才显示Progress控件。您也可以控制UpdateProgress的输出来控制这个控件在隐藏时是否会占用页面的空间，就像设置ASP.NET验证控件的&lt;strong&gt;DisplayMode&lt;/strong&gt;属性一样。另外，您还可以通过增加几行代码，为Progress UI添加一个取消的功能。&lt;br&gt;&lt;br&gt;下面的例子展示了如何设置&lt;strong&gt;UpdateProgress&lt;/strong&gt;控件，使它只在PostBack超过半秒（500毫秒）之后才显示出来：&lt;br&gt;
&lt;div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #ffff88"&gt;&amp;lt;asp:UpdateProgress&amp;nbsp;runat=server&amp;nbsp;ID="Progress1"&amp;nbsp;DisplayAfter="500"&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;ProgressTemplate&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;b&amp;gt;Working&amp;nbsp;on&amp;nbsp;request...&amp;lt;/b&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;input&amp;nbsp;type="button"&amp;nbsp;id="abortButton"&amp;nbsp;onclick="abortPB()"&amp;nbsp;value="Cancel"&amp;nbsp;/&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/ProgressTemplate&amp;gt;&lt;br&gt;&amp;lt;/asp:UpdateProgress&amp;gt;&lt;br&gt;&lt;br&gt;&amp;lt;script&amp;nbsp;type="text/javascript"&amp;gt;&lt;br&gt;&lt;span style="BACKGROUND-COLOR: #ffff88"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;function&amp;nbsp;abortPB()&amp;nbsp;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var&amp;nbsp;obj&amp;nbsp;=&amp;nbsp;Sys.WebForms.PageRequestManager.getInstance();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(obj.get_isInAsyncPostBack())&amp;nbsp;{&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;obj.abortPostBack();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;br&gt;&amp;lt;/script&amp;gt;&lt;/div&gt;
&lt;/span&gt;</description>
      <comments>http://blog.zhaojie.me/2006/10/from-atlas-to-microsoft-asp-net-ajax-8.html#comments</comments>
      <pubDate>Sun, 22 Oct 2006 13:17:00 GMT</pubDate>
      <lastBuildDate>Sun, 22 Oct 2006 13:17:00 GMT</lastBuildDate>
    </item>
    <item>
      <author>jeffz@live.com (老赵)</author>
      <category domain="http://blog.zhaojie.me/asp-net/">ASP.NET</category>
      <category domain="http://blog.zhaojie.me/translation/">翻译引进</category>
      <category domain="http://blog.zhaojie.me/front-end/">前端表现</category>
      <title>从Atlas到Microsoft ASP.NET AJAX（7） - ScriptManager and ScriptManagerProxy Controls, Extender Controls</title>
      <link>http://blog.zhaojie.me/2006/10/from-atlas-to-microsoft-asp-net-ajax-7.html</link>
      <guid>http://blog.zhaojie.me/2006/10/from-atlas-to-microsoft-asp-net-ajax-7.html</guid>
      <description>&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"&gt;&lt;span style="FONT-SIZE: 18pt; COLOR: #339966"&gt;ScriptManager and ScriptManagerProxy Controls&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style="FONT-SIZE: 14pt"&gt;Script References&lt;/span&gt;&lt;br&gt;&lt;br&gt;CTP版本中的&lt;strong&gt;ScriptManager&lt;/strong&gt;和&lt;strong&gt;ScriptManagerProxy&lt;/strong&gt;控件提供了引用所需Client FX脚本的方式，同时也提供了一个使用&lt;strong&gt;path&lt;/strong&gt;或&lt;strong&gt;name&lt;/strong&gt;属性来指定脚本引用的方法。下面的示例展示了这些控件的使用方式。
&lt;div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #eeeeee"&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;atlas:ScriptManager&amp;nbsp;&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;&amp;nbsp;ID&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="ScriptManager"&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;Scripts&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;atlas:ScriptReference&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;ScriptName&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="AtlasUIGlitz"&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;atlas:ScriptReference&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;Path&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="~/Scripts/Custom.js"&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;Scripts&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;atlas:ScriptManager&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;br&gt;被CTP版本所限制的几个关键情形在RTM版本中得以解决。事实上，RTM版本向页面开发人员提供了许多可选设置。在RTM版本中所作的改变包括：&lt;br&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;strong&gt;ScriptManager&lt;/strong&gt;依旧保留了对于必须和可选脚本的支持。对于可选脚本来说，与CTP版本最大的区别在于现在没有了&lt;strong&gt;ScriptName&lt;/strong&gt;枚举。这个功能被一个能够适合更多场合的模型所替代，该模型允许第三方使用基于程序集的方式来发送Web资源脚本。下面的示例展示了新的模型，并且使用了Value-Add包中额外的可选脚本。如下：
    &lt;div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #ffff88"&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;asp:ScriptManager&amp;nbsp;&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;&amp;nbsp;ID&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="ScriptManager"&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;Scripts&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;asp:ScriptReference&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;&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;Name&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="Microsoft.Web.Resources.ScriptLibrary.PreviewScript.js"&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&amp;nbsp;&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;Assembly&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="Microsoft.Web.Preview"&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;asp:ScriptReference&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;&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;Name&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="Microsoft.Web.Resources.ScriptLibrary.PreviewGlitz.js"&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&amp;nbsp;&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;Assembly&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="Microsoft.Web.Preview"&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;asp:ScriptReference&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;Path&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="~/Scripts/Custom.js"&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;Scripts&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;asp:ScriptManager&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
    &lt;li style="MARGIN-TOP: 10px"&gt;&lt;strong&gt;ScriptManager&lt;/strong&gt;控件允许您以引用静态文件的方式引用磁盘上的文件，并以此提高性能。这点同时应用于Client FX和自定义的脚本。这点依靠&lt;strong&gt;ScriptPath&lt;/strong&gt;属性（全局路径）来实现。这个属性标明了一个根路径，控间会在此后加上程序集名和版本号作为脚本引用的路径。这意味着，如果您将组件升级为一个新的版本（例如，&lt;strong&gt;System.Web.Extensions&lt;/strong&gt;），页面依然会正常运行，只是它会引用新的脚本文件。下面的例子展示了&lt;strong&gt;ScriptPath&lt;/strong&gt;属性的使用方式：
    &lt;div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; MARGIN-BOTTOM: 5px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #ffff88"&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;asp:ScriptManager&amp;nbsp;&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;&amp;nbsp;ID&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="ScriptManager"&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&amp;nbsp;ScriptPath&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;=&amp;#8221;~/Scripts&amp;#8221;&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&amp;lt;Scripts&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;asp:ScriptReference&amp;nbsp;&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;&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;Name&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="Microsoft.Web.Resources.ScriptLibrary.PreviewScript.js"&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&amp;nbsp;&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;Assembly&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="Microsoft.Web.Preview"&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;asp:ScriptReference&amp;nbsp;&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;&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;Name&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="Microsoft.Web.Resources.ScriptLibrary.PreviewGlitz.js"&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&amp;nbsp;&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;Assembly&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="Microsoft.Web.Preview"&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;asp:ScriptReference&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;Path&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="~/Scripts/Custom.js"&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;Scripts&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;asp:ScriptManager&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
    由于使用了&lt;strong&gt;ScriptPath&lt;/strong&gt;设置全局（根）路径，这个模型意味着那些脚本文件所在的位置是&lt;strong&gt;ScriptPath&lt;/strong&gt;的值之后再加上程序集名和它的版本。在现在的示例中，它表示了：
    &lt;ul&gt;
        &lt;li&gt;框架脚本为：~/Scripts/Microsoft.Web.Extensions/1.0.&amp;lt;build&amp;gt;.0/*.js。
        &lt;li&gt;可选的Preview脚本为：~/Scripts/Microsoft.Web.Preview/1.0.0.0/*.js。 &lt;/li&gt;
    &lt;/ul&gt;
    您依旧能够在应用里使用&lt;strong&gt;Path&lt;/strong&gt;属性来覆盖&lt;strong&gt;ScriptPath&lt;/strong&gt;的值。您也能够通过将&lt;strong&gt;IgnoreScriptPath&lt;/strong&gt;属性设为true来强行使用程序集内的脚本。
    &lt;li style="MARGIN-TOP: 10px"&gt;您能够使用Path属性来引用磁盘上的脚本文件，您也可能直接指定某个特定的Client FX的脚本。如果您修改了Client FX脚本，您能够直接引用修改后的版本而不是框架中的脚本。下面的示例说明了这一点：
    &lt;div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #ffff88"&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;asp:ScriptManager&amp;nbsp;&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;&amp;nbsp;ID&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="ScriptManager"&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;Scripts&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;asp:ScriptReference&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;Name&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="MicrosoftAjax.js"&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&amp;nbsp;&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;Path&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="~/Scripts/MicrosoftAjax2.js"&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;Scripts&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;asp:ScriptManager&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
    &lt;li style="MARGIN-TOP: 10px"&gt;&lt;strong&gt;ScriptManage&lt;/strong&gt;r控件允许您指定一个Web Resource脚本，以此提供IntelliSense功能，您可以使用&lt;strong&gt;ScriptRefernce&lt;/strong&gt;标签上指定的名称和程序集来做到这一点。
    &lt;li style="MARGIN-TOP: 10px"&gt;&lt;strong&gt;ScriptManager&lt;/strong&gt;提供了&lt;strong&gt;ResolveScripts&lt;/strong&gt;事件，该事件会为每一个脚本而触发以此，包括客户端框架脚本。您能够响应&lt;strong&gt;ResolveScripts&lt;/strong&gt;事件来动态地改变脚本的引用，将其指向另一个路径。例如，您能够将脚本路径指向离当前请求IP地理位置最近的服务器，以此来提升性能。下面的示例展示了操作&lt;strong&gt;ResolveScripts&lt;/strong&gt;事件的方式：
    &lt;div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #ffff88"&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;asp:ScriptManager&amp;nbsp;&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;&amp;nbsp;ID&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="ScriptManager"&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&lt;font color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;OnResolveScriptReference&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="ResolveScripts"&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;...&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;asp:ScriptManager&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;script&amp;nbsp;&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;span style="COLOR: #000000"&gt;&lt;br&gt;&lt;span style="COLOR: #0000ff"&gt;&lt;font color=#000000&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;protected&lt;/span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;void&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;ResolveScripts(object&amp;nbsp;sender,&amp;nbsp;ScriptReferenceEventArgs&amp;nbsp;e)&amp;nbsp;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;e.Script.Path&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;=&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;&amp;#8220;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;~/&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;newLocation&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;/&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;#8221;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;+&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;e.Script.Name;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;...&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;&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: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
    &lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;&lt;span style="FONT-SIZE: 14pt"&gt;Handling Debug and Release Scripts&lt;/span&gt;&lt;br&gt;&lt;br&gt;在CTP版本中，&lt;strong&gt;ScriptManager&lt;/strong&gt;控件能够指定一个是使用Debug还是Release类型的脚本引用。像之前提到的那样，两者的区别仅仅是Release脚本删除了不必要的空格而已。在页面中输出哪种类型的脚本，是由Web.config中&lt;strong&gt;debug&lt;/strong&gt;设置决定的。&lt;br&gt;&lt;br&gt;根据我们得到的用户反馈，在RTM版本中使用了一个新的模型，它能够允许&lt;strong&gt;ScriptManager&lt;/strong&gt;控件将服务器端和客户端的debug设置分开。&lt;strong&gt;ScriptManager&lt;/strong&gt;控件为客户端使用Debug脚本的依据在于添加为引用的命名规则。您能够总是引用Release脚本，而&lt;strong&gt;ScriptManager&lt;/strong&gt;控件会为您处理好别的事情，例如debug脚本不存在时的fallback控制。&lt;br&gt;&lt;br&gt;在RTM版本中，Release和Debug脚本都会经过压缩模块。在Release脚本中，它还会被&amp;#8220;crunched&amp;#8221;（混淆的意思？）——Beta暂不支持。&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;span style="FONT-SIZE: 14pt"&gt;Script and Other Resource Registration APIs&lt;/span&gt;&lt;br&gt;&lt;br&gt;正如&lt;strong&gt;UpdatePanel&lt;/strong&gt;的部分所解释过的，在RTM版本中&lt;strong&gt;ScriptManager&lt;/strong&gt;控件提供了新的API可用于注册脚本和其余的资源，这使得&lt;strong&gt;ScriptManager&lt;/strong&gt;和客户端&lt;strong&gt;pageRequestManager&lt;/strong&gt;能够控制如何跟踪在&lt;strong&gt;UpdatePanel&lt;/strong&gt;里出现的部分页面PostBack。&lt;br&gt;&lt;br&gt;另外，在RTM版本中，包括使用了Client FX的Entender在内的新控件，都会在将它们自己注册给&lt;strong&gt;ScriptManager&lt;/strong&gt;后，再将自己的脚本库和其他的客户端对象注册给&lt;strong&gt;ScriptManager&lt;/strong&gt;。&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;span style="FONT-SIZE: 18pt; COLOR: #339966"&gt;Extender Controls&lt;/span&gt;&lt;br&gt;&lt;br&gt;Extender控件能够允许你为现有的服务器控间添加客户端Behavior，以此增加新的功能和行为。在CTP版本中，您使用了一个单独的Extender控件，并设置它的控件属性与目标服务器控件一一对应，就像下面示例所展示的一样：&lt;br&gt;
&lt;div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #eeeeee"&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;asp:TextBox&amp;nbsp;&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;&amp;nbsp;ID&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="City"&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;br&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;asp:TextBox&amp;nbsp;&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;&amp;nbsp;ID&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="CountryOrRegion"&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;atlas:AutoCompleteExtender&amp;nbsp;&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;&amp;nbsp;ID&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="AutoComplete1"&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;atlas:AutoCompleteProperties&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;TargetControlID&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="City"&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Enabled&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="True"&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&amp;nbsp;ServicePath&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="AutoCompleteWebService.asmx"&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ServiceMethod&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="GetCompletionList"&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;atlas:AutoCompleteProperties&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;TargetControlID&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="CountryOrRegion"&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Enabled&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="True"&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&amp;nbsp;ServicePath&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="AutoCompleteWebService.asmx"&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ServiceMethod&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="GetCompletionList"&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;atlas:AutoCompleteExtender&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;br&gt;&lt;br&gt;&lt;span style="FONT-SIZE: 14pt"&gt;Extender Controls and the Component Developer&lt;/span&gt;&lt;br&gt;&lt;br&gt;在CTP版本中，组件开发人员能够使用&lt;strong&gt;ExtenderControl&lt;/strong&gt;基类和&lt;strong&gt;ExtenderControlProperties&lt;/strong&gt;类进行开发。在这里，开发人员负责开发相关Behavior的客户端脚本，然后使用Extender的&lt;strong&gt;RenderScript&lt;/strong&gt;方法中的&lt;strong&gt;ScriptTextWriter&lt;/strong&gt;类型参数将其XML-Script输出。组件开发人员会将他们的脚本注册给控件的特定生命周期事件，例如Init事件。&lt;br&gt;&lt;br&gt;根据用户反馈，并考虑到减轻其复杂度能够有利于今后的扩展，我们实现了一个新的模型。在RTM版本中，组件开发人员直接使用了&lt;strong&gt;ExtenderControl&lt;/strong&gt;类。开发人员能够为自己的控件实现&lt;strong&gt;IScriptControl&lt;/strong&gt;和&lt;strong&gt;IExtenderControl&lt;/strong&gt;接口，以此来处理页面中存在&lt;strong&gt;ScriptManager&lt;/strong&gt;的情况。&lt;br&gt;&lt;br&gt;Extender控件依然会注册给&lt;strong&gt;ScriptManager&lt;/strong&gt;控件。然而，它们会被框架要求提供它们的所需的脚本类库，并提供一个新的&lt;strong&gt;ScriptDescriptor&lt;/strong&gt;类型的对象，从而避免了旧的模型中需要控件开发人员在控件的生命周期中自行输出这些信息。&lt;strong&gt;ScriptDescriptor&lt;/strong&gt;类型会与&lt;strong&gt;Component&lt;/strong&gt;，&lt;strong&gt;Behavior&lt;/strong&gt;和&lt;strong&gt;Control&lt;/strong&gt;等客户端类型一一映射，这种做法为客户端对象抽象了脚本的生成过程，这使生成客户端对象变成了一件简单的事情。&lt;br&gt;&lt;br&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;p&gt;&lt;strong&gt;注意：&lt;/strong&gt;在RTM的Beta版本中，控件将在其在&lt;strong&gt;Init&lt;/strong&gt;时注册给&lt;strong&gt;ScriptManager&lt;/strong&gt;。这一点在RTM中会被改变为使用&lt;strong&gt;PreRender&lt;/strong&gt;。这样的话，在Extender的一个&lt;strong&gt;TargetControl&lt;/strong&gt;是不可见的情况下，在Beta版本中，这个Extender依旧会向其请求脚本引用和描述符。这一点在RTM中会被改变。&lt;/p&gt;
&lt;/blockquote&gt;　　在这种模型下，服务器控件就无需得知应该如何将脚本输出了，这方便了今后的扩展和支持。下面的示例简单展示了在RTM版本中ScriptDescriptor类型的使用方式：&lt;br&gt;
&lt;div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #ffff88"&gt;&lt;span style="COLOR: #0000ff"&gt;protected&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;override&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;IEnumerable&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;ScriptDescriptor&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;GetScriptDescriptors&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; (Control&amp;nbsp;targetControl)&amp;nbsp;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ScriptBehaviorDescriptor&amp;nbsp;descriptor&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;=&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;new&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;ScriptBehaviorDescriptor(&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;"&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;Sample.UI.BorderBehavior&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;"&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;,&amp;nbsp;targetControl.ClientID);&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;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;if&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;(&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;!&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;Color.IsEmpty)&amp;nbsp;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;descriptor.AddProperty(&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;"&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;color&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;"&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;,&amp;nbsp;ColorTranslator.ToHtml(Color));&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;if&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;(Style&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;!=&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;BorderStyle.NotSet)&amp;nbsp;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;descriptor.AddProperty(&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;"&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;style&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;"&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;,&amp;nbsp;Style.ToString());&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;if&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;(&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;!&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;Width.IsEmpty)&amp;nbsp;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;descriptor.AddProperty(&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;"&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;width&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;"&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;,&amp;nbsp;Width.ToString());&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;yield&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;return&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;descriptor;&lt;br&gt;}&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;protected&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;override&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;IEnumerable&amp;lt;ScriptReference&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;GetScriptReferences()&amp;nbsp;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ScriptReference&amp;nbsp;reference&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;=&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;new&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;ScriptReference();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Reference.Path&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;=&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;ResolveClientUrl(&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;"&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;~/ScriptControls/BorderBehavior.js&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;"&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;));&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=#0000ff&gt;yield &lt;/font&gt;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;return&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;reference;&lt;br&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;br&gt;在这个示例中，我们使用了&lt;strong&gt;ScriptDescriptor&lt;/strong&gt;类型中的&lt;strong&gt;AddProperty&lt;/strong&gt;方法来设置客户端对象的属性值。请注意我们也使用了&lt;strong&gt;ScriptReference&lt;/strong&gt;类型来返回一个特定的脚本引用，在这里我们使用了一个静态的URL，而不是Web Resource脚本引用。&lt;br&gt;&lt;br&gt;
&lt;fieldset&gt;&lt;legend&gt;Comment&lt;/legend&gt;　　上面的例子中有些小错误，我在参考了那些控件的代码后作了轻微的改动。&lt;/fieldset&gt;&lt;br&gt;&lt;br&gt;&lt;/span&gt;</description>
      <comments>http://blog.zhaojie.me/2006/10/from-atlas-to-microsoft-asp-net-ajax-7.html#comments</comments>
      <pubDate>Sun, 22 Oct 2006 04:18:00 GMT</pubDate>
      <lastBuildDate>Sun, 22 Oct 2006 04:18:00 GMT</lastBuildDate>
    </item>
    <item>
      <author>jeffz@live.com (老赵)</author>
      <category domain="http://blog.zhaojie.me/asp-net/">ASP.NET</category>
      <category domain="http://blog.zhaojie.me/translation/">翻译引进</category>
      <category domain="http://blog.zhaojie.me/front-end/">前端表现</category>
      <title>从Atlas到Microsoft ASP.NET AJAX（6） - Networking, Application Services</title>
      <link>http://blog.zhaojie.me/2006/10/from-atlas-to-microsoft-asp-net-ajax-6.html</link>
      <guid>http://blog.zhaojie.me/2006/10/from-atlas-to-microsoft-asp-net-ajax-6.html</guid>
      <description>&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"&gt;&lt;span style="FONT-SIZE: 18pt; COLOR: #339966"&gt;Networking&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;span style="FONT-SIZE: 14pt"&gt;Calling Web Service Methods from Script&lt;/span&gt;&lt;br&gt;&lt;br&gt;为了简化Web Services方法调用，客户端代理的设计被改变了，它在方法调用和回调函数设置方面提供了强大的灵活性。&lt;br&gt;&lt;br&gt;下面的例子展示了CTP版本中Web Services方法的客户端调用，以及回调函数的使用方式。第一个例子展示了在CTP版本中Web service的定义方式。如下：&lt;br&gt;
&lt;div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #eeeeee"&gt;&lt;span style="COLOR: #0000ff"&gt;public&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;class&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;MyService:&amp;nbsp;System.Web.Services.WebService&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[WebMethod]&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;public&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;string&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;MyWebMethod(&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;int&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;param1,&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;string&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;param2)&amp;nbsp;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;...&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;br&gt;下一个例子展示了CTP版本中调用上述方法的客户端代码。如下：&lt;br&gt;
&lt;div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #eeeeee"&gt;&lt;span style="COLOR: #008000"&gt;//&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&amp;nbsp;Invoke&amp;nbsp;method,&amp;nbsp;specifying&amp;nbsp;a&amp;nbsp;"succeeded"&amp;nbsp;callback&amp;nbsp;function.&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;MyNS.MyService.MyMethod(&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;126&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;"&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;my&amp;nbsp;value&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;"&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;,&amp;nbsp;OnComplete,&amp;nbsp;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;OnTimeout,&amp;nbsp;OnError,&amp;nbsp;onAborted,&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;"&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;MyUserContext&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;"&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;);&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;//&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&amp;nbsp;Callback&amp;nbsp;function.&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;function&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;OnComplete(result,&amp;nbsp;response,&amp;nbsp;userContext)&amp;nbsp;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;//&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&amp;nbsp;Use&amp;nbsp;result.&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;br&gt;下面的两个例子展示了上述代码在RTM版本的相应的定义与使用方式。RTM版本中服务器端方法的定义方式和下面的例子类似。如下：&lt;br&gt;
&lt;div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #ffff88"&gt;&lt;span style="COLOR: #000000"&gt;[ScriptService]&amp;nbsp;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;public&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;class&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;MyService:&amp;nbsp;System.Web.Services.WebService&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[WebMethod]&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;public&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;string&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;MyMethod(&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;int&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;param1,&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;string&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;param2)&amp;nbsp;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;...&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;br&gt;RTM版本中访问服务器端方法的客户端代码与下面的例子类似。如下：&lt;br&gt;
&lt;div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #ffff88"&gt;&lt;span style="COLOR: #008000"&gt;//&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&amp;nbsp;Invoke&amp;nbsp;method,&amp;nbsp;specifying&amp;nbsp;callback&amp;nbsp;functions&amp;nbsp;and&amp;nbsp;user&amp;nbsp;context.&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;MyNS.MyService.MyMethod(&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;126&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;"&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;my&amp;nbsp;value&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;"&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;,&amp;nbsp;OnSuccess,&amp;nbsp;OnFailure,&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;"&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;MyUserContext&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;"&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;);&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;//&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&amp;nbsp;Callback&amp;nbsp;function&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;function&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;OnSuccess(result,&amp;nbsp;userContext,&amp;nbsp;methodName)&amp;nbsp;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;//&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&amp;nbsp;Use&amp;nbsp;result.&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;br&gt;在RTM版本中，您能够指定一个默认的回调函数和默认的user context，这样访问Web Service方法时就无需指定那些参数了。下面的客户端代码设置了默认的回调函数和user context，然后使用不同的参数连续调用了两次Web Services方法。&lt;br&gt;
&lt;div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #ffff88"&gt;&lt;span style="COLOR: #0000ff"&gt;var&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;Fs&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;=&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;MyNS.MyService;&lt;br&gt;Fs.set_defaultSucceededCallback(OnSuccess);&lt;br&gt;Fs.set_defaultFailedCallback(OnFailure);&lt;br&gt;Fs.set_defaultUserContext(&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;"&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;MyUserContext&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;"&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;);&lt;br&gt;Fs.set_timeout(&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;100&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;);&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;//&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&amp;nbsp;Invoke&amp;nbsp;method&amp;nbsp;without&amp;nbsp;specifying&amp;nbsp;callback&amp;nbsp;functions&amp;nbsp;or&amp;nbsp;user&amp;nbsp;context.&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;Fs.MyMethod(&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;126&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;"&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;value&amp;nbsp;one&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;"&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;);&lt;br&gt;Fs.MyMethod(&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;456&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;"&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;value&amp;nbsp;two&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;"&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;);&lt;/span&gt;&lt;/div&gt;
&lt;br&gt;&lt;br&gt;&lt;span style="FONT-SIZE: 14pt"&gt;Server Attributes&lt;/span&gt;&lt;br&gt;&lt;br&gt;在CTP版本中，使用了.NET Framework中服务器端的自定义属性，以此对Web Services方法进行特定的控制。在RTM版本中引入了新的自定义属性来提供这些功能。这些改变的原因是考虑到安全因素，以及避免复用现有类库所带来的语义上的差别。&lt;br&gt;&lt;br&gt;针对Web Service方法的改变有：&lt;br&gt;
&lt;ul&gt;
    &lt;li&gt;必须使用&lt;strong&gt;[ScriptService]&lt;/strong&gt;自定义属性来标记Web Services类，使它的方法能够从客户端访问。
    &lt;li&gt;&lt;strong&gt;[ScriptIgnore]&lt;/strong&gt;自定义属性能够用来避免某个类的属性或者实例变量被JSON序列化，从而使它们不会出现在客户端为服务器端对象生成的代理中。这个自定义属性与CTP版本中&lt;strong&gt;[XmlIgnore]&lt;/strong&gt;自定义属性的作用相对应。
    &lt;li&gt;&lt;strong&gt;[GenerateScriptType()]&lt;/strong&gt;自定义属性的作用是为服务器端的类型添加客户端代理，这样就可以将其作为Web Services方法的参数或返回值了。这个自定义属性可以使用在任何Web Service类和方法中。这个自定义属性与CTP版本中&lt;strong&gt;[XmlInclude]&lt;/strong&gt;自定义属性的作用相对应。 &lt;/li&gt;
&lt;/ul&gt;
&lt;fieldset&gt;&lt;legend&gt;Comment&lt;/legend&gt;　　在这之前其实我已经在&amp;#8220;深入Atlas系列&amp;#8221;中将Atlas中访问Web Services方法的主要功能讨论完了，在了解Microsoft ASP.NET AJAX针对这部分的改变之后我也去简单阅读了一下程序集的代码。这部分代码的改变并不如想象中的大（也有可能是因为我没有仔细研究其细节）。其服务器端的实现虽然进行了修改和重构，但是原有功能大致不变。另外，服务器端的功能也增强了，例如到目前为止，我发现目前的实现已经能够支持Dictionary&amp;lt;T, K&amp;gt;这样的范型字典。哎，还算是不幸中的万幸，&amp;#8220;深入Atlas系列&amp;#8221;中&amp;#8220;分析&amp;#8221;部分的文章没有完全丧失其价值，只是&amp;#8220;示例&amp;#8221;部分可以说真正的无一幸免&amp;#8230;&amp;#8230;&lt;/fieldset&gt;&lt;br&gt;&lt;br&gt;&lt;span style="FONT-SIZE: 14pt"&gt;Support for WCF Web Services&lt;/span&gt;&lt;br&gt;&lt;br&gt;在RTM版本里，您已经无法从客户端访问Windows Communication Foundation (WCF) Web Services（.svc文件）了。访问WCF的能力将会被一个增强的实现所替代，在接下来的&amp;#8220;Orcas&amp;#8221;CTP中将有对于WCF的完全集成。&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;span style="FONT-SIZE: 14pt"&gt;Advanced Networking Scenarios Not Available in the RTM Release&lt;/span&gt;&lt;br&gt;&lt;br&gt;CTP版本内的下列功能在RTM版本中被取消了：&lt;br&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;strong&gt;iframe&lt;/strong&gt;调用。这个功能可以支持跨域名的调用，处于安全性考虑，在RTM中这项功能被移除了。
    &lt;li&gt;下列不常用的功能：
    &lt;ul&gt;
        &lt;li&gt;机遇程序集的方法调问。
        &lt;li&gt;&lt;strong&gt;InitialData&lt;/strong&gt;控件。
        &lt;li&gt;Web Service的批量调用。 &lt;/li&gt;
    &lt;/ul&gt;
    &lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;&lt;br&gt;&lt;span style="FONT-SIZE: 18pt; COLOR: #339966"&gt;Application Services&lt;/span&gt;&lt;br&gt;&lt;br&gt;在RTM版本中，我们为客户端使用Authentication服务和Profile服务提供了一个简化的并且更为灵活的设计。这个设计与前面讲过的客户端访问Web Services方法保持了统一。&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;span style="FONT-SIZE: 14pt"&gt;Profile Services&lt;/span&gt;&lt;br&gt;&lt;br&gt;RTM版本的Profile服务使用了Web Service客户端代理的模型，而没有单独作为一个组件而实现。但是，Value-add包内提供了一个Profile服务组件的实现。&lt;br&gt;&lt;br&gt;CTP版本和RTM版本中关于Profile服务的主要改变有以下几点：&lt;br&gt;
&lt;ul&gt;
    &lt;li&gt;相关的类名从Sys._Profile改变为Sys.Services._ProfileService。
    &lt;li&gt;全局实例从Sys.Profile改变为Sys.Services.ProfileService。
    &lt;li&gt;开发人员可以为save，load和error方法指定默认的回调函数。
    &lt;li&gt;增加了使用字符串数组作为参数的save和load方法。
    &lt;li&gt;增加了对于Profile Group的支持。
    &lt;li&gt;增加了使用ScriptManager和ProfileServiceManager服务器端控件预加载Profile属性的支持。
    &lt;li&gt;去除了AutoSave功能。
    &lt;li&gt;去除了saved，loaded和propertyChanged事件。 &lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;Value-add包提供的Profile服务缩小了CTP版本中的Profile组件和RTM版本中Profile代理之间的距离。它有以下一些功能：&lt;br&gt;
&lt;ul&gt;
    &lt;li&gt;类名变成了Sys.Preview.Services.Compoenents.Profile。
    &lt;li&gt;XML-Script的标签仍然是&lt;strong&gt;&amp;lt;profile /&amp;gt;&lt;/strong&gt;。
    &lt;li&gt;如果没有指定preloading功能的话，该组件会在页面加载时自动加载profile信息。
    &lt;li&gt;该组件提供了AutoSave功能。
    &lt;li&gt;该组件提供了saved和loaded事件。
    &lt;li&gt;该组件提供了getProperty()和setProperty()方法。
    &lt;li&gt;该组件可以作为Binding的target或source。 &lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;下列示例展示了Profile服务的使用方式。第一个示例展示了如何加载Profile信息。如下：&lt;br&gt;
&lt;div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #ffff88"&gt;&lt;span style="COLOR: #008000"&gt;//&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&amp;nbsp;Load&amp;nbsp;specific&amp;nbsp;properties,&amp;nbsp;after&amp;nbsp;setting&amp;nbsp;default&amp;nbsp;completed&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&lt;br&gt;//&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&amp;nbsp;and&amp;nbsp;failed&amp;nbsp;callback&amp;nbsp;functions.&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;Sys.Services.ProfileService.load([&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;"&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;SimpleProperty&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;"&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;"&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;Group.GroupedProperty&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;"&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;]);&amp;nbsp;&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;//&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&amp;nbsp;Load&amp;nbsp;all&amp;nbsp;properties&amp;nbsp;marked&amp;nbsp;as&amp;nbsp;"read&amp;nbsp;access"&amp;nbsp;in&amp;nbsp;the&amp;nbsp;Web&amp;nbsp;service,&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&lt;br&gt;//&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&amp;nbsp;after&amp;nbsp;setting&amp;nbsp;default&amp;nbsp;completed&amp;nbsp;and&amp;nbsp;failed&amp;nbsp;callback&amp;nbsp;functions.&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;Sys.Services.ProfileService.load();&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;//&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&amp;nbsp;Specify&amp;nbsp;explicit&amp;nbsp;callbacks&amp;nbsp;rather&amp;nbsp;than&amp;nbsp;using&amp;nbsp;defaults.&amp;nbsp;"88"&amp;nbsp;is&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&lt;br&gt;//&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&amp;nbsp;passed&amp;nbsp;to&amp;nbsp;the&amp;nbsp;callback&amp;nbsp;function&amp;nbsp;as&amp;nbsp;user&amp;nbsp;context.&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;Sys.Services.ProfileService.load(props,&amp;nbsp;loadCompletedCallback,&amp;nbsp;failedCallback,&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;88&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;);&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;br&gt;下面的示例展示了访问Profile属性的方法。如下：&lt;br&gt;
&lt;div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #ffff88"&gt;&lt;span style="COLOR: #0000ff"&gt;var&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;x&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;=&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;Sys.Services.ProfileService.properties.SimpleProperty;&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;var&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;x&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;=&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;Sys.Services.ProfileService.properties.Group.GroupedProperty1;&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;var&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;x&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;=&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;Sys.Services.ProfileService.properties.Group.GroupedComplexTypeProperty.AddressLine1;&lt;/span&gt;&lt;/div&gt;
&lt;br&gt;下面的示例展示了改变Profile属性的方式。如下：&lt;br&gt;
&lt;div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #ffff88"&gt;&lt;span style="COLOR: #000000"&gt;Sys.Services.ProfileService.properties.SimpleProperty&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;=&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;"&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;value&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;"&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;;&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;if&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;(&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;!&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;Sys.Services.ProfileService.properties.Group)&amp;nbsp;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Sys.Services.ProfileService.properties.Group&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;=&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;new&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;Sys.Services.ProfileGroup();&lt;br&gt;}&lt;br&gt;Sys.Services.ProfileService.properties.Group.GroupedProperty1&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;=&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;"&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;group&amp;nbsp;value&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;"&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;;&lt;br&gt;Sys.Services.ProfileService.properties.Group.GroupedComplexTypeProperty&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;=&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;{&amp;nbsp;AddressLine1:&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;"&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;abc&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;"&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;,&amp;nbsp;AddressLine2:&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;"&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;xyz&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;"&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;};&lt;/span&gt;&lt;/div&gt;
&lt;br&gt;下面的示例展示了保存Profile属性的方式。如下：&lt;br&gt;
&lt;div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #ffff88"&gt;&lt;span style="COLOR: #008000"&gt;//&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&amp;nbsp;Save&amp;nbsp;specific&amp;nbsp;properties,&amp;nbsp;after&amp;nbsp;setting&amp;nbsp;default&amp;nbsp;success&amp;nbsp;and&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&lt;br&gt;//&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&amp;nbsp;fail&amp;nbsp;callback&amp;nbsp;functions.&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;Sys.Services.ProfileService.save([&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;"&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;SimpleProperty&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;"&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;"&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;Group.GroupedProperty&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;"&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;]);&amp;nbsp;&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;//&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&amp;nbsp;Save&amp;nbsp;all&amp;nbsp;properties&amp;nbsp;in&amp;nbsp;the&amp;nbsp;.properties&amp;nbsp;object,&amp;nbsp;after&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&lt;br&gt;//&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&amp;nbsp;setting&amp;nbsp;default&amp;nbsp;completed&amp;nbsp;and&amp;nbsp;failed&amp;nbsp;callback&amp;nbsp;functions.&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;Sys.Services.ProfileService.save();&amp;nbsp;&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;//&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&amp;nbsp;Specify&amp;nbsp;explicit&amp;nbsp;callbacks,&amp;nbsp;rather&amp;nbsp;than&amp;nbsp;using&amp;nbsp;defaults.&amp;nbsp;"88"&amp;nbsp;is&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&lt;br&gt;//&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&amp;nbsp;passed&amp;nbsp;to&amp;nbsp;the&amp;nbsp;callback&amp;nbsp;function&amp;nbsp;as&amp;nbsp;user&amp;nbsp;context.&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;Sys.Services.ProfileService.save(props,&amp;nbsp;saveCompletedCallback,&amp;nbsp;failedCallback,&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;88&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;);&lt;/span&gt;&lt;/div&gt;
&lt;br&gt;下面的示例展示了completed回调函数参数信息。如下：&lt;br&gt;
&lt;div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #ffff88"&gt;&lt;span style="COLOR: #0000ff"&gt;function&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;loadCompletedCallback(numPropertiesLoaded,&amp;nbsp;userContext,&amp;nbsp;methodName)&amp;nbsp;{...}&amp;nbsp;&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;function&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;saveCompletedCallback(numPropertiesSaved,&amp;nbsp;userContext,&amp;nbsp;methodName)&amp;nbsp;{...}&lt;/span&gt;&lt;/div&gt;
&lt;br&gt;下面的示例展示了failed回调函数的参数信息。如下：&lt;br&gt;
&lt;div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #ffff88"&gt;&lt;span style="COLOR: #0000ff"&gt;function&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;failedCallback(errorObject,&amp;nbsp;userContext,&amp;nbsp;methodName)&amp;nbsp;{...}&lt;/span&gt;&lt;/div&gt;
&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;span style="FONT-SIZE: 14pt"&gt;Autentication Service&lt;/span&gt;&lt;br&gt;&lt;br&gt;CTP版本和RTM版本中Authentication服务的改变有以下几点：&lt;br&gt;
&lt;ul&gt;
    &lt;li&gt;您可以为login，logout和error指定默认的回调函数。
    &lt;li&gt;在login和logout函数中，可以传递一个redirectUrl作为参数，指定操作完成后的页面转向。
    &lt;li&gt;在login函数中，可以传递一个customInfo作为参数，这个参数为今后使用而保留，目前应该设置为null。
    &lt;li&gt;增加了get_isLoggedIn方法。这个方法不会与服务器端交互，它只和当前组件的状况有关。如果您使用了未指定redirctUrl参数的login函数，则在login成功之后，get_isLoggedIn就会返回true。
    &lt;li&gt;去除了verifyUser方法。 &lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;下面的示例表示了如何在RTM版本如何使用Authentication服务。如下：&lt;br&gt;
&lt;div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #ffff88"&gt;&lt;span style="COLOR: #0000ff"&gt;var&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;loggedIn&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;=&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;Sys.Services.AuthenticationService.get_isLoggedIn();&amp;nbsp;&lt;br&gt;&lt;br&gt;Sys.Services.AuthenticationService.login(userLogin,&amp;nbsp;userPassword,&amp;nbsp;isPersistentCookie,&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; customInfo, redirectUrl,&amp;nbsp;loginCompletedCallback,&amp;nbsp;failedCallback,&amp;nbsp;userContext);&lt;br&gt;&lt;br&gt;Sys.Services.AuthenticationService.logout(redirectUrl,&amp;nbsp;logoutCompletedCallback,&amp;nbsp;failedCallback,&amp;nbsp;userContext);&lt;/span&gt;&lt;/div&gt;
&lt;br&gt;下面的示例展示了completed回调函数的参数信息。如下：&lt;br&gt;
&lt;div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #ffff88"&gt;&lt;span style="COLOR: #0000ff"&gt;function&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;loginCompleted(validCredentials,&amp;nbsp;userContext,&amp;nbsp;methodName)&amp;nbsp;{...}&lt;/span&gt;&lt;/div&gt;
&lt;br&gt;下面的示例展示了failed回调函数的参数信息。如下：&lt;br&gt;
&lt;div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #ffff88"&gt;&lt;span style="COLOR: #0000ff"&gt;function&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;loginFailed(errorObject,&amp;nbsp;userContext,&amp;nbsp;methodName)&amp;nbsp;{...}&lt;/span&gt;&lt;/div&gt;
&lt;br&gt;&lt;br&gt;&lt;/span&gt;</description>
      <comments>http://blog.zhaojie.me/2006/10/from-atlas-to-microsoft-asp-net-ajax-6.html#comments</comments>
      <pubDate>Sat, 21 Oct 2006 17:47:00 GMT</pubDate>
      <lastBuildDate>Sat, 21 Oct 2006 17:47:00 GMT</lastBuildDate>
    </item>
    <item>
      <author>jeffz@live.com (老赵)</author>
      <category domain="http://blog.zhaojie.me/translation/">翻译引进</category>
      <category domain="http://blog.zhaojie.me/asp-net/">ASP.NET</category>
      <category domain="http://blog.zhaojie.me/front-end/">前端表现</category>
      <title>从Atlas到Microsoft ASP.NET AJAX（5） - Higher-level Component Framework</title>
      <link>http://blog.zhaojie.me/2006/10/from-atlas-to-microsoft-asp-net-ajax-5.html</link>
      <guid>http://blog.zhaojie.me/2006/10/from-atlas-to-microsoft-asp-net-ajax-5.html</guid>
      <description>&lt;font style="FONT-SIZE: 18pt" face=Verdana size=2&gt;&lt;span style="COLOR: #339966"&gt;Higher-level Component Framework&lt;/span&gt;&lt;/font&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"&gt;&lt;br&gt;&lt;br&gt;高级组件的功能已经根据客户反馈，性能等诸多因素进行了修改。就以之前的Button为例，DomEvent类使用了一个基于标准的法提供了一套API用于DOM事件的分发。这个抽象能够良好运行在多个浏览器中。&lt;br&gt;&lt;br&gt;许多API已经从CTP版本原来的地方（大都是Control类的成员）转移到了RTM版本中新的地方，而且被定义成了静态函数。这种做法减少了Contorl类的体积，而且这些操作DOM元素的API也能被开发人员随意使用了，不必像以前一样必须初始化一个Control对象。下面的示例展示了使用DomElement类的方式：&lt;br&gt;
&lt;div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #ffff88"&gt;&lt;span style="COLOR: #000000"&gt;Sys.UI.DomElement.addCssClass($get('AddressLine1'),&amp;nbsp;'rqdFieldStyle');&lt;/span&gt;&lt;/div&gt;
&lt;br&gt;请注意，在这里使用了新的$get函数，后面将对这些简写函数进行解释。&lt;br&gt;&lt;br&gt;&lt;span style="FONT-SIZE: 14pt"&gt;Component，Control and Behavior Class&lt;/span&gt;&lt;br&gt;&lt;br&gt;在CTP版本中存在着以下三个类：&lt;strong&gt;Component&lt;/strong&gt;，&lt;strong&gt;Control&lt;/strong&gt;和&lt;strong&gt;Behavior&lt;/strong&gt;。它们提供了许多重要的功能。其中&lt;strong&gt;Control&lt;/strong&gt;和&lt;strong&gt;Behavior&lt;/strong&gt;都是&lt;strong&gt;Component&lt;/strong&gt;的子类。&lt;br&gt;&lt;br&gt;这个模型在RTM版本中依旧存在。然而，经过了我们对它们用法的研究，并联系设计的原始目的进行研究后，改变了它们的使用方法。例如，在CTP版本中，一个&lt;strong&gt;Control&lt;/strong&gt;类和一个DOM元素紧密联系了起来，您能通过&lt;strong&gt;Control&lt;/strong&gt;对象来访问这个DOM元素。但是，尽管&lt;strong&gt;Behavior&lt;/strong&gt;和DOM元素有直接的关系，我们却只能通过&lt;strong&gt;Control&lt;/strong&gt;实例的一个Collection类型属性来访问到它。&lt;br&gt;&lt;br&gt;RTM版本使DOM元素相关的工作变得更加灵活。&lt;strong&gt;Control&lt;/strong&gt;和&lt;strong&gt;Behavior&lt;/strong&gt;在概念上非常相似，都和一个DOM元素有这密切的关系。然而，现在它们已经相互独立了。&lt;br&gt;&lt;br&gt;在RTM版本中，您能将一个&lt;strong&gt;Control&lt;/strong&gt;实例与一个DOM元素联系起来，并且可以通过control来获得，这一点和CTP版本相同。另外，如果一个&lt;strong&gt;Behavior&lt;/strong&gt;有一个&lt;strong&gt;Name&lt;/strong&gt;属性，您也能通过这个名字从DOM元素中获得它。一个DOM元素可以有多个&lt;strong&gt;Bihavior&lt;/strong&gt;与之相关联。下面的例子展示了如何使用RTM版本中新增的&lt;strong&gt;$create&lt;/strong&gt;和&lt;strong&gt;$get&lt;/strong&gt;，通过一个DOM元素来得到它的Control对象和Behavior对象的引用。如下：&lt;br&gt;
&lt;div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #ffff88"&gt;&lt;span style="COLOR: #008000"&gt;//&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&amp;nbsp;Add&amp;nbsp;a&amp;nbsp;control&amp;nbsp;and&amp;nbsp;behavior&amp;nbsp;to&amp;nbsp;the&amp;nbsp;GoShopping&amp;nbsp;DOM&amp;nbsp;element.&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;$create(Custom.UI.Button,&amp;nbsp;{},&amp;nbsp;{'click':'myHandler'},&amp;nbsp;{}, $get('GoShopping'));&lt;br&gt;$create(Custom.UI.BorderBehavior,&amp;nbsp;{'name':'border'},&amp;nbsp;{},&amp;nbsp;{},&amp;nbsp;$get('GoShopping'));&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;//&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&amp;nbsp;Page&amp;nbsp;developer&amp;nbsp;accesses&amp;nbsp;Button&amp;nbsp;using&amp;nbsp;the&amp;nbsp;DOM&amp;nbsp;element&amp;nbsp;directly.&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;var&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;gs&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;=&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;$get('GoShopping');&lt;br&gt;gs.control.set_text('Sale&amp;nbsp;items');&lt;br&gt;gs.border.set_color('red');&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;//&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&amp;nbsp;Page&amp;nbsp;developer&amp;nbsp;obtains&amp;nbsp;the&amp;nbsp;behavior&amp;nbsp;using&amp;nbsp;the&amp;nbsp;$&amp;nbsp;separator.&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;var&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;bb&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;=&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;&amp;nbsp;$find(&amp;#8216;GoShopping$border);&lt;/span&gt;&lt;/div&gt;
&lt;br&gt;&lt;br&gt;&lt;span style="FONT-SIZE: 14pt"&gt;Creating and Finding Components and Elements&lt;/span&gt;&lt;br&gt;&lt;br&gt;在CTP版本中，您能够使用JavaScript来实例化一个对象，设置属性，并调用&lt;strong&gt;initialize&lt;/strong&gt;方法。另外，您也可以使用XML-Script来操作它。在RTM版本的模型中：&lt;br&gt;
&lt;ul&gt;
    &lt;li&gt;能够使用以前一样的方式使用Javascript操作组件。
    &lt;li&gt;使用新的&lt;strong&gt;$create&lt;/strong&gt;别名来操作组件。它的功能覆盖了实例化对象，设置属性，调用initialize方法等操作。这是一个强大的模型，也能被服务器控件所使用。
    &lt;li&gt;使用Value-add包中的XML-Script支持，能够在RTM版本中使用与&lt;strong&gt;$create&lt;/strong&gt;功能相同的操作。 &lt;/li&gt;
&lt;/ul&gt;
　　在RTM版本中，当一个组件使用&lt;strong&gt;$create&lt;/strong&gt;初始化后，在全局的&lt;strong&gt;Application&lt;/strong&gt;对象中会添加一个它的引用。页面开发人员能够使用新的别名来获得这些组件的引用，即使开发人员并没有对它进行初始化工作。例如，页面开发人员能够使用新的别名获得一个使用XML-Script初始化的组件。&lt;br&gt;&lt;br&gt;&lt;span style="FONT-SIZE: 12pt; FONT-FAMILY: Verdana"&gt;&lt;strong&gt;$object, $find and $create Aliases&lt;/strong&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;在CTP版本中，我们能够使用&lt;strong&gt;$object('GoShopping')&lt;/strong&gt;来获得一个被XML-Script初始化的组件引用。Value-add包提供了这个操作。&lt;br&gt;&lt;br&gt;在RTM版本的代码中，我们引入了&lt;strong&gt;$find&lt;/strong&gt;方法。您能够使用这个方法来获得任意组件的引用——无论它是使用XML-Script还是&lt;strong&gt;$create&lt;/strong&gt;初始化的。这意味着我们能够使用它来获得服务器端控件或Extender创造的对象，自然也包括使用JavaScript和XML-Script创造的对象。&lt;br&gt;&lt;br&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;p&gt;&lt;strong&gt;Note：&lt;/strong&gt;Beta版本中的&lt;strong&gt;$find&lt;/strong&gt;方法能够通过ID来获得一个注册在&lt;strong&gt;Application&lt;/strong&gt;中的组件，Behavior和控件。控件的ID和DOM元素的ID相同。而Behavior能够通过它所在的元素ID和它的类名得到一个默认的UniqueID（&amp;#8220;&lt;strong&gt;elementId$ClassName&lt;/strong&gt;&amp;#8221;）——例如AddressLine1$AutoCompleteBehavior。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;fieldset&gt;&lt;legend&gt;Comment&lt;/legend&gt;　　我对这里的说法做一些补充。虽然Behavior会获得一个默认的UniqueID，但是如果一个控件里同时存在两个相同的Behavior会出现什么情况呢？如果同时存在两个不同的，但是名称相同（所在namespace不同）的Behavior，又会如何呢？只有尝试了或者分析代码之后才能知道。因此最好还是为每个需要find到的Behavior提供一个名字。这样就能像之前的例子一样，通过$find('GoShopping$border')来获得。&lt;/fieldset&gt;&lt;br&gt;&lt;span style="FONT-SIZE: 12pt"&gt;&lt;strong&gt;$ and $get&lt;/strong&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;在CTP版本中定义了一个全局的&lt;strong&gt;$()&lt;/strong&gt;来提供&lt;strong&gt;document.getElementById()&lt;/strong&gt;的功能。但是无论是RTM版本还是Value-add包已经取消了对它的支持。这么做的原因是为了避免与其他使用&lt;strong&gt;$()&lt;/strong&gt;的AJAX类库产生冲突。在RTM版本中提供了&lt;strong&gt;$get&lt;/strong&gt;函数来替代原有的&lt;strong&gt;$()&lt;/strong&gt;函数，它们具有完全相同的功能。&lt;br&gt;&lt;br&gt;&lt;span style="FONT-SIZE: 12pt"&gt;&lt;strong&gt;$addHandler and $removeHandler&lt;/strong&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;RTM版本提供的&lt;strong&gt;$addHandler&lt;/strong&gt;和&lt;strong&gt;$removeHandler&lt;/strong&gt;操作提供了一个简单的方式创建和移出对DOM元素事件的响应。在之前Button的例子中已经演示了它们的使用方式。请注意，传递给Handler的参数是个&lt;strong&gt;Sys.UI.DomEvent&lt;/strong&gt;对象，它是一个跨浏览器的事件对象。在CTP的模型中，您使用全局的&lt;strong&gt;window.event&lt;/strong&gt;对象进行操作，这并不是一个平台无关的对象。&lt;br&gt;&lt;br&gt;
&lt;fieldset&gt;&lt;legend&gt;Comment&lt;/legend&gt;　　虽然window.event不是个平台无关的对象，但是它依旧在多个浏览器运行良好，因为Atlas的Compact层为Event对象作了扩展，使它兼容了IE的操作。&lt;/fieldset&gt;&lt;br&gt;&lt;br&gt;&lt;span style="FONT-SIZE: 14pt"&gt;Application Object and Life Cycle&lt;/span&gt;&lt;br&gt;&lt;br&gt;在CTP版本中存在着&lt;strong&gt;Runtime&lt;/strong&gt;和&lt;strong&gt;Application&lt;/strong&gt;两个对象的概念。其中&lt;strong&gt;Application&lt;/strong&gt;对象负责分发window的事件，并且响应开发人员的&lt;strong&gt;pageLoad&lt;/strong&gt;（通过&lt;strong&gt;load&lt;/strong&gt;事件）和&lt;strong&gt;pageUnload&lt;/strong&gt;（通过&lt;strong&gt;unload&lt;/strong&gt;事件）的功能。&lt;strong&gt;pageLoad&lt;/strong&gt;的功能保证了这些代码在所有的脚本和XML-Script已经被加载和初始化完毕后才被调用。&lt;br&gt;&lt;br&gt;在RTM版本中将原来的&lt;strong&gt;Runtime&lt;/strong&gt;对象和&lt;strong&gt;Application&lt;/strong&gt;对象结合在了一起，成为了一个新的&lt;strong&gt;Application&lt;/strong&gt;对象。在RTM版本中依旧保留了&lt;strong&gt;load&lt;/strong&gt;和&lt;strong&gt;unload&lt;/strong&gt;事件，另外还引入了新的&lt;strong&gt;init&lt;/strong&gt;事件，一般用于使用&lt;strong&gt;$create&lt;/strong&gt;来建立对象。您也可以像以前那样响应&lt;strong&gt;load&lt;/strong&gt;事件来初始化对象。在RTM版本中，load事件在页面局部刷新的场景中也会被触发，因此如果您在pageLoad时操作对象的话，可能会由于round trip而重建对象。&lt;br&gt;&lt;br&gt;使用&lt;strong&gt;$create&lt;/strong&gt;语法在初始化对象时，保证了在实例化对象后调用了&lt;strong&gt;beginUpdate&lt;/strong&gt;方法，然后设置属性，再依次调用了&lt;strong&gt;endUpdate&lt;/strong&gt;和&lt;strong&gt;initialize&lt;/strong&gt;方法。此外，对象被注册到了&lt;strong&gt;Application&lt;/strong&gt;对象上，因此允许使用&lt;strong&gt;$find&lt;/strong&gt;来找到这个对象的引用。&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;span style="FONT-SIZE: 14pt"&gt;Property Change Notification&lt;/span&gt;&lt;br&gt;&lt;br&gt;CTP版本和RTM版本都定义了property-change事件。在RTM版本中，如果您在开发组件，请在属性改变之后为其触发property-change事件，它提供了对于binding功能的支持，并能通知其他的事件监听器。&lt;br&gt;&lt;br&gt;基础的&lt;strong&gt;Component&lt;/strong&gt;类型已经实现了&lt;strong&gt;INotifyPropertyChange&lt;/strong&gt;接口。&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;span style="FONT-SIZE: 14pt"&gt;Disposing&lt;/span&gt;&lt;br&gt;&lt;br&gt;在CTP版本中，基础类型&lt;strong&gt;Sys.Component&lt;/strong&gt;已经实现了&lt;strong&gt;Sys.IDisposable&lt;/strong&gt;接口，因而定义了&lt;strong&gt;dispose&lt;/strong&gt;方法。这个模型在RTM版本中得到延续。不过在RTM版本中引入了一个新的接口：&lt;strong&gt;Sys.INotifyDisposing&lt;/strong&gt;，它已经被&lt;strong&gt;Sys.Component&lt;/strong&gt;实现了。这个接口允许Value-add包中的binding来监听一个对象的销毁，因此能够在合适的时候从组件上分离。&lt;br&gt;&lt;br&gt;支持&lt;strong&gt;UpdatePanel&lt;/strong&gt;功能的对象必须被销毁，因此您必须正确地实现它们的&lt;strong&gt;dispose&lt;/strong&gt;方法以避免多次调用而产生的错误。例如在之前的&lt;strong&gt;Button&lt;/strong&gt;示例中，&lt;strong&gt;dispose&lt;/strong&gt;方法在调用&lt;strong&gt;$removeHandler&lt;/strong&gt;和&lt;strong&gt;delete&lt;/strong&gt;之前进行了检查，以确定click handler的存在。&lt;br&gt;&lt;br&gt;同时您也应该保证，在销毁任意的子组件或者对象前，要对它们进行检查，因为&lt;strong&gt;Application&lt;/strong&gt;对象无法保证自动销毁对象时的顺序。&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;span style="FONT-SIZE: 14pt"&gt;Bindings and Actions&lt;/span&gt;&lt;br&gt;&lt;br&gt;在CTP版本中能够为一个组件定义Binding。因此只有存在一个组件，才能将Binding添加给它。&lt;br&gt;&lt;br&gt;在RTM版本中并没有直接对Binding提供支持，但是提供了&lt;strong&gt;Sys.INotifyDisposing&lt;/strong&gt;接口。有了这个接口，在Value-add包中的Binding就能在某个对象被销毁时得到通知，以此进行自我管理。因此，Value-add包中的Binding就能够脱离RTM包中组件运行，这也意味着与CTP版本相比，现在的Binding能够更加自由地进行声明和使用。&lt;br&gt;&lt;br&gt;现在，Value-add包中的Binding能够获取一个source和一个target对象的引用，并且可以监听它们的销毁事件。当其中一个对象被销毁后，为两者建立联系的Binding也能独立地自行销毁。&lt;br&gt;&lt;br&gt;&lt;/span&gt;</description>
      <comments>http://blog.zhaojie.me/2006/10/from-atlas-to-microsoft-asp-net-ajax-5.html#comments</comments>
      <pubDate>Sat, 21 Oct 2006 13:32:00 GMT</pubDate>
      <lastBuildDate>Sat, 21 Oct 2006 13:32:00 GMT</lastBuildDate>
    </item>
  </channel>
</rss>
