<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">博客园_紫色永恒</title><subtitle type="text">Nothing lasts forever.</subtitle><id>http://feed.cnblogs.com/blog/u/33552/rss</id><updated>2011-12-23T17:56:11Z</updated><author><name>紫色永恒</name><uri>http://www.cnblogs.com/024hi/</uri></author><generator>feed.cnblogs.com</generator><link rel="alternate" type="text/html" href="http://www.cnblogs.com/024hi/"/><link rel="self" type="application/atom+xml" href="http://feed.cnblogs.com/blog/u/33552/rss"/><entry><id>http://www.cnblogs.com/024hi/archive/2011/12/24/2300087.html</id><title type="text">Silverlight Client&amp;larr;&amp;rarr;Server数据同步备忘代码</title><summary type="text">#region 同步单位void SyncUnit() { ProgressContent = "正在同步单位..."; var query = Context.GetUnitsQuery().Where(p =&gt; p.ShopUniqueId == App.CurrentShop.UniqueId); Context.Load(query, LoadUnitCallback, ...</summary><published>2011-12-23T17:56:00Z</published><updated>2011-12-23T17:56:00Z</updated><author><name>紫色永恒</name><uri>http://www.cnblogs.com/024hi/</uri></author><link rel="alternate" href="http://www.cnblogs.com/024hi/archive/2011/12/24/2300087.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/024hi/archive/2011/12/24/2300087.html"/><content type="html">&lt;pre class="code"&gt;&lt;span style="color: #8cd0d3"&gt;#region &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;同步单位&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;void &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;SyncUnit() {    ProgressContent = &lt;/span&gt;&lt;span style="color: #dca3a3"&gt;&amp;quot;正在同步单位...&amp;quot;&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;;    &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;var &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;query = Context.GetUnitsQuery().Where(p =&amp;gt; p.ShopUniqueId == &lt;/span&gt;&lt;span style="color: #efefaf"&gt;App&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;.CurrentShop.UniqueId);    Context.Load(query, LoadUnitCallback, &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;null&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;);}&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;void &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;LoadUnitCallback(&lt;/span&gt;&lt;span style="color: #efefaf"&gt;LoadOperation&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #efefaf"&gt;RP_Unit&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;&amp;gt; loadOp) {    &lt;/span&gt;&lt;span style="color: #7d9b7d"&gt;//服务端数据    &lt;/span&gt;&lt;span style="color: #d0d081"&gt;IEnumerable&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #efefaf"&gt;RP_Unit&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;&amp;gt; serverUnits = Context.RP_Units;    &lt;/span&gt;&lt;span style="color: #7d9b7d"&gt;//客户端数据    &lt;/span&gt;&lt;span style="color: #d0d081"&gt;IEnumerable&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #efefaf"&gt;RP_Unit&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;&amp;gt; clientUnits;    &lt;/span&gt;&lt;span style="color: #7d9b7d"&gt;//获取数据    &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;using &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;(&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;var &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;helper = &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;new &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;LocalDb.&lt;/span&gt;&lt;span style="color: #efefaf"&gt;UnitHelper&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;()) {        clientUnits = helper.GetList();    }    &lt;/span&gt;&lt;span style="color: #7d9b7d"&gt;//获取交集用来同步已存在且需要更新的实体    &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;var &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;intersectUnits = serverUnits.Intersect(clientUnits, &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;new &lt;/span&gt;&lt;span style="color: #efefaf"&gt;UnitEntityCompare&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;());    &lt;/span&gt;&lt;span style="color: #7d9b7d"&gt;//遍历交集集合    &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;foreach &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;(&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;var &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;item &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;in &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;intersectUnits) {        &lt;/span&gt;&lt;span style="color: #7d9b7d"&gt;// 根据交集的项目分别获取服务端及客户端需要更新的数据        &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;var &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;serverUnitToUpdate = serverUnits.First(p =&amp;gt; p.UniqueId == item.UniqueId);        &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;var &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;clientUnitToUpdate = clientUnits.First(p =&amp;gt; p.UniqueId == item.UniqueId);        &lt;/span&gt;&lt;span style="color: #7d9b7d"&gt;// 根据更新时间进行比较，如果相同则忽略操作        &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;if &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;(clientUnitToUpdate.UpdateDate != serverUnitToUpdate.UpdateDate) {            &lt;/span&gt;&lt;span style="color: #7d9b7d"&gt;//如果服务端较新，则更新客户端            &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;if &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;(clientUnitToUpdate.UpdateDate &amp;lt; serverUnitToUpdate.UpdateDate) {                &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;using &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;(&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;var &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;helper = &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;new &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;LocalDb.&lt;/span&gt;&lt;span style="color: #efefaf"&gt;UnitHelper&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;()) {                    helper.UpdateUnit(serverUnitToUpdate);                }            }            &lt;/span&gt;&lt;span style="color: #7d9b7d"&gt;//否则更新服务端            &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;else &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;{                serverUnitToUpdate.UpdateDate = clientUnitToUpdate.UpdateDate;                serverUnitToUpdate.NameCN = clientUnitToUpdate.NameCN;                serverUnitToUpdate.NameEN = clientUnitToUpdate.NameEN;            }        }    }    &lt;/span&gt;&lt;span style="color: #7d9b7d"&gt;//获取服务端与客户端的差集用来同步服务端或客户端不存在的实体    &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;var &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;exceptServer = serverUnits.Except(clientUnits, &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;new &lt;/span&gt;&lt;span style="color: #efefaf"&gt;UnitEntityCompare&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;());    &lt;/span&gt;&lt;span style="color: #7d9b7d"&gt;//遍历差集集合    //由于要修改集合，所以不使用foreach    &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;for &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;(&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;int &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;i = &lt;/span&gt;&lt;span style="color: #8cd0d3"&gt;0&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;; i &amp;lt; exceptServer.Count(); i++) {        &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;var &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;item = exceptServer.ElementAt(i);        &lt;/span&gt;&lt;span style="color: #7d9b7d"&gt;//如果本地最后更新时间在数据的更新时间之前，则向客户端添加该数据        &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;if &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;(!clientShopInfo.LastUpdateDate.HasValue || clientShopInfo.LastUpdateDate &amp;lt; serverShopInfo.LastUpdateDate) {            &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;using &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;(&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;var &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;helper = &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;new &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;LocalDb.&lt;/span&gt;&lt;span style="color: #efefaf"&gt;UnitHelper&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;()) {                helper.AddUnit(item);            }        }        &lt;/span&gt;&lt;span style="color: #7d9b7d"&gt;//否则说明数据已从本地库删除，同时从服务端数据库删除        &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;else &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;{            Context.RP_Units.Remove(item);        }    }    &lt;/span&gt;&lt;span style="color: #7d9b7d"&gt;//获取服务端与客户端的差集用来同步服务端或客户端不存在的实体    &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;var &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;exceptClient = clientUnits.Except(serverUnits, &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;new &lt;/span&gt;&lt;span style="color: #efefaf"&gt;UnitEntityCompare&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;());    &lt;/span&gt;&lt;span style="color: #7d9b7d"&gt;//遍历差集集合    //由于要修改集合，所以不使用foreach    &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;foreach &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;(&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;var &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;item &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;in &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;exceptClient) {        &lt;/span&gt;&lt;span style="color: #7d9b7d"&gt;//如果本地最后更新时间在数据的更新时间之前，则从客户端移除该数据        &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;if &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;(clientShopInfo.LastUpdateDate &amp;lt; serverShopInfo.LastUpdateDate) {            &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;using &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;(&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;var &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;helper = &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;new &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;LocalDb.&lt;/span&gt;&lt;span style="color: #efefaf"&gt;UnitHelper&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;()) {                helper.DeleteUnit(item);            }        }        &lt;/span&gt;&lt;span style="color: #7d9b7d"&gt;//否则说明将客户端数据添加到服务端        &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;else &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;{            Context.RP_Units.Add(item);        }    }    SyncOperations.Remove(&lt;/span&gt;&lt;span style="color: #dca3a3"&gt;&amp;quot;Unit&amp;quot;&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;);}&lt;/span&gt;&lt;span style="color: #8cd0d3"&gt;#endregion&lt;/span&gt;&lt;/pre&gt;&lt;img src="http://www.cnblogs.com/024hi/aggbug/2300087.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/024hi/archive/2011/12/24/2300087.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/024hi/archive/2011/09/07/2170125.html</id><title type="text">Expression Blend 5 Preview For Silverlight5 RC已发布</title><summary type="text">Expression Blend 5 Preview Ultimate for Silverlight 5 Release Candidate已经发布。该版本的Blend只支持Silverlight5项目（包括Sketch Flow） 。 更多细节请浏览 Microsoft Download Centre. 下载地址: Download Microsoft Expression Blend 5...</summary><published>2011-09-07T09:56:00Z</published><updated>2011-09-07T09:56:00Z</updated><author><name>紫色永恒</name><uri>http://www.cnblogs.com/024hi/</uri></author><link rel="alternate" href="http://www.cnblogs.com/024hi/archive/2011/09/07/2170125.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/024hi/archive/2011/09/07/2170125.html"/><content type="html">&lt;p&gt;Expression Blend 5 Preview Ultimate for Silverlight 5 Release Candidate已经发布。该版本的Blend只支持Silverlight5项目（包括Sketch Flow） 。&lt;/p&gt;  &lt;p&gt;更多细节请浏览 &lt;a href="http://www.microsoft.com/download/en/details.aspx?id=9503"&gt;Microsoft Download Centre&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;下载地址:&lt;/strong&gt; &lt;a href="http://www.microsoft.com/downloads/info.aspx?na=41&amp;amp;srcfamilyid=22feb67c-4f65-4ced-97cf-5f8ada296445&amp;amp;srcdisplaylang=en&amp;amp;u=http%3a%2f%2fdownload.microsoft.com%2fdownload%2f3%2f9%2fF%2f39F528F3-32CB-43CC-8CE6-5ECF74C23830%2fBlend_UltimateTrial_en.exe"&gt;Download Microsoft Expression Blend 5 Preview for Silverlight 5 RC&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a name="more"&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;img title="" border="0" alt="" src="http://lh4.ggpht.com/-eHx3eJgOF7A/Tmcu-wkZw_I/AAAAAAAAHx4/Z_Pu6MWTVrU/image%25255B7%25255D.png?imgmax=800" width="400" height="286" /&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/024hi/aggbug/2170125.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/024hi/archive/2011/09/07/2170125.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/024hi/archive/2011/09/06/2168419.html</id><title type="text">Siverlight5新功能/改进总结</title><summary type="text">参考资料：The Big List of What’s New or Improved in Silverlight 5 以下总结包括大家关心的Silverlight5的绝大多数新功能或改进，特别是Silverlight5 RC中的新玩意。 数据绑定相关 ICustomTypeProvider 自定义标记扩展（Custom Markup Extensions） Ances...</summary><published>2011-09-06T01:57:00Z</published><updated>2011-09-06T01:57:00Z</updated><author><name>紫色永恒</name><uri>http://www.cnblogs.com/024hi/</uri></author><link rel="alternate" href="http://www.cnblogs.com/024hi/archive/2011/09/06/2168419.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/024hi/archive/2011/09/06/2168419.html"/><content type="html">&lt;p&gt;参考资料：&lt;a href="http://10rem.net/blog/2011/09/04/the-big-list-of-whats-new-or-improved-in-silverlight-5"&gt;The Big List of What’s New or Improved in Silverlight 5&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;以下总结包括大家关心的Silverlight5的绝大多数新功能或改进，特别是Silverlight5 RC中的新玩意。&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;数据绑定相关&lt;/strong&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;ICustomTypeProvider &lt;/li&gt;    &lt;li&gt;自定义标记扩展（Custom Markup Extensions）&lt;/li&gt;    &lt;li&gt;Ancestor RelativeSource 绑定&lt;/li&gt;    &lt;li&gt;隐式 Data Templates&lt;/li&gt;    &lt;li&gt;绑定到Style的Setter&lt;/li&gt;    &lt;li&gt;DataContextChanged 事件 &lt;/li&gt;    &lt;li&gt;UpdateSourceTrigger中新增PropertyChanged&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;图形/显示相关&lt;/strong&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;XNA 3D API &lt;/li&gt;    &lt;li&gt;改进Graphics Stack &lt;/li&gt;    &lt;li&gt;3D 目标呈现&amp;#160; &lt;/li&gt;    &lt;li&gt;XNA 3D效果内置 &lt;/li&gt;    &lt;li&gt;3D 表面构成设置&lt;/li&gt;    &lt;li&gt;3D 采样抗锯齿&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;多媒体&lt;/strong&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;应用XNA SoundEffect及SoundEffectInstace的低延时音效&lt;/li&gt;    &lt;li&gt;硬编码H.264&lt;/li&gt;    &lt;li&gt;回放及变速&lt;/li&gt;    &lt;li&gt;支持遥控器及MediaCommand&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;文本&lt;/strong&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;文本间隙调节&lt;/li&gt;    &lt;li&gt;串联及多列文本&lt;/li&gt;    &lt;li&gt;支持OpenType&amp;#160; &lt;/li&gt;    &lt;li&gt;Pixel Snapped 文本及相应的 TextOptions &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;OS交互&lt;/strong&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;P/Invoke &lt;/li&gt;    &lt;li&gt;多窗口&lt;/li&gt;    &lt;li&gt;在完全信任模式下无限制的文件通信&lt;/li&gt;    &lt;li&gt;浏览器内完全信任模式 &lt;/li&gt;    &lt;li&gt;SaveFileDialog 和 OpenFileDialog 支持默认文件名 &lt;/li&gt;    &lt;li&gt;支持64位浏览器 &lt;/li&gt;    &lt;li&gt;当使用Silverlight播放多媒体内容时提供更好的电源管理(如不让计算机进入休眠、屏幕保护等状态) &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;性能及生产力提升&lt;/strong&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;改进网络延迟&lt;/li&gt;    &lt;li&gt;可以对Xaml中的数据绑定进行调试&lt;/li&gt;    &lt;li&gt;解析器性能提升&lt;/li&gt;    &lt;li&gt;使用多核JIT减少启动时间&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;控件&lt;/strong&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;支持双击（多击）&lt;/li&gt;    &lt;li&gt;PivotViewer 控件 &lt;/li&gt;    &lt;li&gt;在ComboBox中可以根据按键选择到相应的项（比如ComboBox中有Alice、Lily、Tom，当你敲击T建的时候会直接跳到Tom选项上）&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;其他&lt;/strong&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;浏览器内使用 HTML 控件&lt;/li&gt;    &lt;li&gt;矢量打印 &lt;/li&gt;    &lt;li&gt;融入了TPL（Tasks Parallel Library）并行类库的子集简化异步操作&lt;/li&gt; &lt;/ul&gt;&lt;img src="http://www.cnblogs.com/024hi/aggbug/2168419.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/024hi/archive/2011/09/06/2168419.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/024hi/archive/2011/07/19/2110186.html</id><title type="text">[译]WCF RIA Services中的集合（2）</title><summary type="text">原文地址：http://www.silverlightshow.net/items/Working-with-collections-in-WCF-RIA-Services-part-two.aspx 这是本文的第二部分。 在第一部分中，我们讨论了两个相对简单的集合类型：EntitySet和EntityList。在本文中，我们将更进一步的了解其他两个更高级的类型：ICollectionView和D...</summary><published>2011-07-19T01:17:00Z</published><updated>2011-07-19T01:17:00Z</updated><author><name>紫色永恒</name><uri>http://www.cnblogs.com/024hi/</uri></author><link rel="alternate" href="http://www.cnblogs.com/024hi/archive/2011/07/19/2110186.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/024hi/archive/2011/07/19/2110186.html"/><content type="html">&lt;p&gt;原文地址：&lt;a title="http://www.silverlightshow.net/items/Working-with-collections-in-WCF-RIA-Services-part-two.aspx" href="http://www.silverlightshow.net/items/Working-with-collections-in-WCF-RIA-Services-part-two.aspx"&gt;http://www.silverlightshow.net/items/Working-with-collections-in-WCF-RIA-Services-part-two.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;这是本文的第二部分。&lt;/p&gt;  &lt;p&gt;在第一部分中，我们讨论了两个相对简单的集合类型：EntitySet和EntityList。在本文中，我们将更进一步的了解其他两个更高级的类型：ICollectionView和DomainCollectionView。&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;b&gt;ICollectionView&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;ICollectionView并不是一个新的接口，已经有大量的Silverlight控件对其进行了实现，如DataGrid。现在，我们可以直接在ViewModel中使用它。为了允许控件绑定到一个ICollectionView的实现（如我们熟悉的CollectionViewSource和PagedCollectionView），我们可以这样做：&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: #dac6a5"&gt;private &lt;/span&gt;&lt;span style="color: #d0d081"&gt;ICollectionView &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;CreateView(&lt;/span&gt;&lt;span style="color: #d0d081"&gt;IEnumerable &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;source) {    &lt;/span&gt;&lt;span style="color: #efefaf"&gt;CollectionViewSource &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;cvs = &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;new &lt;/span&gt;&lt;span style="color: #efefaf"&gt;CollectionViewSource&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;();    cvs.Source = source;    &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;return &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;cvs.View;}&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;private &lt;/span&gt;&lt;span style="color: #d0d081"&gt;ICollectionView &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;_books;&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;public &lt;/span&gt;&lt;span style="color: #d0d081"&gt;ICollectionView &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;Books {    &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;get &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;{        &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;if &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;(&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;this&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;._books == &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;null&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;) {            &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;this&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;._books = CreateView(&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;this&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;.Context.Books);            &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;this&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;._books.Filter = &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;new &lt;/span&gt;&lt;span style="color: #efefaf"&gt;Predicate&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;object&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;&amp;gt;(BookCorrespondsToFilter);        }        &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;return this&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;._books;    }}&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;当载入Book数据时会自动反映到View中：&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #dac6a5"&gt;public &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;CollectionViewViewModel() {    InstantiateCommands();    &lt;/span&gt;&lt;span style="color: #7d9b7d"&gt;// load books    &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;Context.Load&amp;lt;&lt;/span&gt;&lt;span style="color: #efefaf"&gt;Book&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;&amp;gt;(Context.GetBooksQuery().Take(&lt;/span&gt;&lt;span style="color: #8cd0d3"&gt;10&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;));}&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;&lt;b&gt;ICollectionView:&lt;/b&gt;&lt;b&gt;添加和移除数据&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;可以通过直接从Context添加和移除实体来完成，这些EntitySet的变化变化都会被CollectionViewSource跟踪到。&lt;/p&gt;&lt;p&gt;那么，这么做的意义到底是什么？目前为止我们还没看到这种方式与直接使用EntitySet的区别是吧？其实，ICollectionView的真正特别之处体现在可以添加过滤、排序和分组规则。&lt;/p&gt;&lt;p&gt;&lt;b&gt;ICollectionView&lt;/b&gt;&lt;b&gt;的过滤&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;ICollectionView定义了一个Predicate&amp;lt;object&amp;gt;类型的Filter属性，让我们略加修改我们的代码：&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #dac6a5"&gt;private &lt;/span&gt;&lt;span style="color: #d0d081"&gt;ICollectionView &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;_books;&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;public &lt;/span&gt;&lt;span style="color: #d0d081"&gt;ICollectionView &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;Books {    &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;get &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;{        &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;if &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;(&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;this&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;._books == &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;null&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;) {            &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;this&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;._books = CreateView(&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;this&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;.Context.Books);            &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;this&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;._books.Filter = &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;new &lt;/span&gt;&lt;span style="color: #efefaf"&gt;Predicate&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;object&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;&amp;gt;(BookCorrespondsToFilter);        }        &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;return this&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;._books;    }}&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;public bool &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;BookCorrespondsToFilter(&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;object &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;obj) {    &lt;/span&gt;&lt;span style="color: #efefaf"&gt;Book &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;book = obj &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;as &lt;/span&gt;&lt;span style="color: #efefaf"&gt;Book&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;;    &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;if &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;(filterActive) {        &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;return &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;book.Title.Contains(&lt;/span&gt;&lt;span style="color: #dca3a3"&gt;&amp;quot;Silverlight&amp;quot;&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;);    }    &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;return true&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;;}&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;BookCorrespondsToFilter方法执行时会检查每一个Book的Title属性是否包含“Silverlight”这个单词，如果不包含，则它不会被显示在View中。&lt;/p&gt;&lt;p&gt;当前代码提供的功能仅当你明确知道过滤时机时使用，然而大部分的应用程序具有要用户自己确定过滤时机的需求，那么我们再来进行一些改动：添加filterActive属性，当用户点击Add Filter时它被置为true。&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #dac6a5"&gt;public bool &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;BookCorrespondsToFilter(&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;object &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;obj) {    &lt;/span&gt;&lt;span style="color: #efefaf"&gt;Book &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;book = obj &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;as &lt;/span&gt;&lt;span style="color: #efefaf"&gt;Book&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;;    &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;if &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;(filterActive) {        &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;return &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;book.Title.Contains(&lt;/span&gt;&lt;span style="color: #dca3a3"&gt;&amp;quot;Silverlight&amp;quot;&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;);    }    &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;return true&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;;}&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;然当我们点击按钮的时候，我们会发现界面并没有发生任何变化，为什么呢？&lt;/p&gt;&lt;p&gt;当我们针对过滤条件做出改变或Book实体发生变化时（如更改它的书名），ICollectionView的实现不回自动再次执行过滤：Filter方法仅在将实体添加到EntitySet时执行。这意味你不得不明确的通知它使用新的过滤条件重新检查已经载入的实体，我们可以通过调用ICollection的Refresh()方法实现：&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #d7d7c8"&gt;Refresh = &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;new &lt;/span&gt;&lt;span style="color: #efefaf"&gt;RelayCommand&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;(() =&amp;gt; {    Books.Refresh();});&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;现在，View会被重新创建，这会让所有的Book实体被重新过滤。当然这仅当我们改变过滤条件或EntitySet发生改变时才是必要的。&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;&lt;b&gt;ICollectionView&lt;/b&gt;&lt;b&gt;的排序和分组&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;ICollectionView具有SortDescriptions和GroupDescription这两个有趣的属性，可以使用它们定义针对EntitySet的排序和分组规则。&lt;/p&gt;&lt;p&gt;排序操作可以通过点击绑定了ICollectionView的DataGrid列头实现，但当我们使用其他的一些诸如ListBox一类没有表头的控件时则需要通过代码的方式改变它们的排序规则：&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #d7d7c8"&gt;AddSort = &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;new &lt;/span&gt;&lt;span style="color: #efefaf"&gt;RelayCommand&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;(() =&amp;gt; {    Books.SortDescriptions.Add(&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;new &lt;/span&gt;&lt;span style="color: #efefaf"&gt;SortDescription&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;(&lt;/span&gt;&lt;span style="color: #dca3a3"&gt;&amp;quot;Title&amp;quot;&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;, &lt;/span&gt;&lt;span style="color: #efefaf"&gt;ListSortDirection&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;.Ascending));});&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;对集合的分组操作类似：&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #d7d7c8"&gt;AddGrouping = &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;new &lt;/span&gt;&lt;span style="color: #efefaf"&gt;RelayCommand&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;(() =&amp;gt; {    Books.GroupDescriptions.Add(&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;new &lt;/span&gt;&lt;span style="color: #efefaf"&gt;PropertyGroupDescription&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;(&lt;/span&gt;&lt;span style="color: #dca3a3"&gt;&amp;quot;Author&amp;quot;&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;));});&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;效果如图：&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.silverlightshow.net/Storage/Users/KevinDockx/image_thumb7_2.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="clip_image002" border="0" alt="clip_image002" src="http://images.cnblogs.com/cnblogs_com/024hi/201107/201107190917234245.gif" width="672" height="426" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;有一点要注意，一旦对集合进行分组操作，UI虚拟化将会被关闭-所以在操作大量数据时要谨慎一些。当对大量数据进行分组时一般要和分页相配合。&lt;/p&gt;&lt;p&gt;当我们要进行排序、过滤和分组操作时，ICollection是一个非常好的选择。然而它只能作用于内存中的数据，这意味着所有的数据都必须载入到客户端。这适合大部分的应用场景。而其他的情况我们可以通过DomainCollectionView解决。&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;&lt;b&gt;DomainCollectionView&lt;/b&gt;&lt;/p&gt;&lt;p&gt;有很多的企业级应用中会有成千上万甚至百万千万级的数据要进行排序、过滤和分组。面对这类场景，ICollectionView就不再适用了，原因上文已经说明。我们需要一个允许服务端排序、过滤、分组以及更重要的分页操作的集合。&lt;/p&gt;&lt;p&gt;这就是DomainCollectionView的职责，你可以在WCF RIA Services Toolkit中的Microsoft.Windows.Data.DomainServices程序集中找到它（该程序集已经包含在示例代码中）。使用DomainCollectionView需要我们进行相比其他集合更多的设置，不过一旦你掌握了这些设置你会发现它们依然十分简单。DomainCollection初始化时需要Source和Loader（默认是CollectionViewLoader）属性。&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #dac6a5"&gt;public &lt;/span&gt;&lt;span style="color: #efefaf"&gt;DomainCollectionView&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #efefaf"&gt;Book&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;&amp;gt; Books{    &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;get &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;{         &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;return this&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;.view;     }}&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Source定义了用于View的源实体（任意的实现了IEnumerable的集合），典型的例子就是实现了INotifyCollectionChanged的集合。&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #dac6a5"&gt;this&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;.source = &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;new &lt;/span&gt;&lt;span style="color: #efefaf"&gt;EntityList&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #efefaf"&gt;Book&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;&amp;gt;(Context.Books);&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;而Loader关注点在于数据的载入。当我们使用默认的CollectionViewLoader时需要同事传入两个回调：OnLoad和OnLoadCompleted，它们分别定义当数据必须被载入和载入操作完成时的发生的事件（当然如果你愿意的话，也可以用一个简单些的LoadOperation代替CollectionViewLoader）。&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #dac6a5"&gt;this&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;.loader = &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;new &lt;/span&gt;&lt;span style="color: #efefaf"&gt;DomainCollectionViewLoader&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #efefaf"&gt;Book&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;&amp;gt;(    &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;this&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;.OnLoadBooks,    &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;this&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;.OnLoadBooksCompleted);&lt;/span&gt;&lt;/pre&gt;&lt;pre class="code"&gt;&lt;span style="color: #dac6a5"&gt;private &lt;/span&gt;&lt;span style="color: #efefaf"&gt;LoadOperation&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #efefaf"&gt;Book&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;&amp;gt; OnLoadBooks(){    &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;return this&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;.Context.Load(&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;this&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;.query.SortPageAndCount(&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;this&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;.view));}&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;private void &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;OnLoadBooksCompleted(&lt;/span&gt;&lt;span style="color: #efefaf"&gt;LoadOperation&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #efefaf"&gt;Book&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;&amp;gt; op){    &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;if &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;(op.HasError)    {        op.MarkErrorAsHandled();    }    &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;else if &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;(!op.IsCanceled)    {        &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;this&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;.source.Source = op.Entities;        &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;if &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;(op.TotalEntityCount != -&lt;/span&gt;&lt;span style="color: #8cd0d3"&gt;1&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;)        {            &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;this&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;.Books.SetTotalItemCount(op.TotalEntityCount);        }    }}&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;正像你所看到的那样，我们在OnLoadeBooks中确认请求执行时包含了排序（SortDescription）和分页（仅当前页所需数据被载入）以及数据总数（DataPager需要用到）。&lt;/p&gt;&lt;p&gt;当Books被载入时，Source集合会被设置成载入的Book实体，并通过TotalEntityCount得到实体总数赋给TotalItemCount属性。&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #dac6a5"&gt;this&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;.view = &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;new &lt;/span&gt;&lt;span style="color: #efefaf"&gt;DomainCollectionView&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #efefaf"&gt;Book&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;&amp;gt;(loader, source);&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;其余的部分用来进行载入的初始化（如设置页大小为5等）：&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #dac6a5"&gt;using &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;(&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;this&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;.view.DeferRefresh()){    &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;this&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;.view.PageSize = &lt;/span&gt;&lt;span style="color: #8cd0d3"&gt;5&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;;    &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;this&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;.view.MoveToFirstPage();}&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;（使用DeferRefresh()的可以让view的刷新数据事件推迟到所有using包含的代码段执行后再执行）&lt;/p&gt;&lt;p&gt;其实，当我们进行分页、排序（以及其他的可能出发View刷新的操作）时，Loader都被执行并载入数据。一旦载入操作完成便会更新Source属性并通过通知机制让View获知更新同时响应变化。&lt;/p&gt;&lt;p&gt;（注：在WCF RIA Services Toolkit的April版本中，SortPageAndCount已经改成了SortAndPageBy）&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;&lt;b&gt;DomainCollectionView&lt;/b&gt;&lt;b&gt;：添加和移除数据&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;代码如下&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #d7d7c8"&gt;AddBook = &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;new &lt;/span&gt;&lt;span style="color: #efefaf"&gt;RelayCommand&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;(() =&amp;gt;{    &lt;/span&gt;&lt;span style="color: #7d9b7d"&gt;// you can add books like this, but DCV is server side oriented: to get correct     // behaviour, you should add it to the Context and submit the changes, after which    // the next query will fetch the book you just added.    &lt;/span&gt;&lt;span style="color: #efefaf"&gt;Book &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;book = Books.AddNew() &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;as &lt;/span&gt;&lt;span style="color: #efefaf"&gt;Book&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;;    book.Author = &lt;/span&gt;&lt;span style="color: #dca3a3"&gt;&amp;quot;Kevin Dockx&amp;quot;&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;;    book.ASIN = &lt;/span&gt;&lt;span style="color: #dca3a3"&gt;&amp;quot;123456&amp;quot;&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;;    book.Title = &lt;/span&gt;&lt;span style="color: #dca3a3"&gt;&amp;quot;Silverlight for dummies&amp;quot;&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;;});DeleteBook = &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;new &lt;/span&gt;&lt;span style="color: #efefaf"&gt;RelayCommand&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;(() =&amp;gt;{    &lt;/span&gt;&lt;span style="color: #7d9b7d"&gt;// deleting an item can be done like this, but should be done directly on the context     // &amp;amp; submitted to the server    &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;Books.RemoveAt(&lt;/span&gt;&lt;span style="color: #8cd0d3"&gt;0&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;);});&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;然后这样的操作会导致View的筛选、排序等规则不同步，毕竟DomainCollectionView在被设计工作在服务端的。&lt;/p&gt;&lt;p&gt;正确的添加和移除实体的方式是同时在服务端进行相应的操作，如：添加一个实体到Context中（或从Context中移除），调用SubmitChanges提交至服务端然后刷新你的DomainCollectionView。&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;DomainCollectionView&lt;/b&gt;&lt;b&gt;：数据的过滤、排序及分组&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;接下来我们看一下如何对数据进行过滤。很简单，只要在EntityQuery后面增加相应的Where条件即可，比如：&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #d7d7c8"&gt;AddFilter = &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;new &lt;/span&gt;&lt;span style="color: #efefaf"&gt;RelayCommand&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;(() =&amp;gt;{    &lt;/span&gt;&lt;span style="color: #7d9b7d"&gt;// filters in DCV should be done by adding a Where clause to the query, as DCV is mainly used for    // server side logic    &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;this&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;.query = Context.GetOrderedBooksQuery().Where(b =&amp;gt; b.Title.Contains(&lt;/span&gt;&lt;span style="color: #dca3a3"&gt;&amp;quot;Silverlight&amp;quot;&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;));    &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;this&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;.view.MoveToFirstPage();});&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;接下来是排序和分组。当我们点击列头时，SortDesscription会被添加到Book集合中决定下次读取数据的排序策略并自动重新获取数据。&lt;/p&gt;&lt;p&gt;有一些应用程序中要求当排序规则变化后列表跳转到第一页。为对应这样的需求，我们则要像这样写一条event handler：&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #d0d081"&gt;INotifyCollectionChanged &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;notifyingSortDescriptions = (&lt;/span&gt;&lt;span style="color: #d0d081"&gt;INotifyCollectionChanged&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;)&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;this&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;.Books.SortDescriptions;notifyingSortDescriptions.CollectionChanged += (sender, e) =&amp;gt; {    &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;this&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;.view.MoveToFirstPage();};&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;像使用ICollectionView一样，我们也可以添加使用代码向DomainCollectionView中添加自定义的SortDescription&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #d7d7c8"&gt;AddSort = &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;new &lt;/span&gt;&lt;span style="color: #efefaf"&gt;RelayCommand&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;(() =&amp;gt; {    Books.SortDescriptions.Add(&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;new &lt;/span&gt;&lt;span style="color: #efefaf"&gt;SortDescription&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;(&lt;/span&gt;&lt;span style="color: #dca3a3"&gt;&amp;quot;Title&amp;quot;&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;, &lt;/span&gt;&lt;span style="color: #efefaf"&gt;ListSortDirection&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;.Ascending));    Books.Refresh();});&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;分组的方式类似：&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #d7d7c8"&gt;AddGrouping = &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;new &lt;/span&gt;&lt;span style="color: #efefaf"&gt;RelayCommand&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;(() =&amp;gt; {    Books.GroupDescriptions.Add(&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;new &lt;/span&gt;&lt;span style="color: #efefaf"&gt;PropertyGroupDescription&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;(&lt;/span&gt;&lt;span style="color: #dca3a3"&gt;&amp;quot;Author&amp;quot;&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;));    Books.Refresh();});&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;将以上内容整合一下，我们最后得到了一个服务端分页、排序和分组的集合：&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.silverlightshow.net/Storage/Users/KevinDockx/image_thumb9_2.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="clip_image004" border="0" alt="clip_image004" src="http://images.cnblogs.com/cnblogs_com/024hi/201107/20110719091725732.gif" width="634" height="339" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;总结&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;WCF RIA Services SP1新增或增强了许多的集合类型。无论是更好的绑定选项还是服务端可分页、排序的集合都让其与MVVM的交互变得更加便捷。如果你在使用WCF RIA Services配合MVVM开发行业软件或商用程序，那么对这些新的集合类型的了解就显得十分必要了。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/024hi/aggbug/2110186.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/024hi/archive/2011/07/19/2110186.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/024hi/archive/2011/07/15/2107554.html</id><title type="text">[译]WCF RIA Services中的集合（1）</title><summary type="text">原文地址：http://www.silverlightshow.net/items/Working-with-collections-in-WCF-RIA-Services-part-one.aspx 本文分为两部分，本篇为第一部分。 介绍 今天，很多的商业应用是使用WCF RIA Services构成的（这并不奇怪，它确实是一个强大的高扩展性框架）。然而它对集合类型的支持可以变得更好。你经常会做...</summary><published>2011-07-15T08:05:00Z</published><updated>2011-07-15T08:05:00Z</updated><author><name>紫色永恒</name><uri>http://www.cnblogs.com/024hi/</uri></author><link rel="alternate" href="http://www.cnblogs.com/024hi/archive/2011/07/15/2107554.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/024hi/archive/2011/07/15/2107554.html"/><content type="html">&lt;p&gt;原文地址：&lt;a href="http://www.silverlightshow.net/items/Working-with-collections-in-WCF-RIA-Services-part-one.aspx"&gt;http://www.silverlightshow.net/items/Working-with-collections-in-WCF-RIA-Services-part-one.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;本文分为两部分，本篇为第一部分。&lt;/p&gt;  &lt;p&gt;&lt;b&gt;介绍&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;今天，很多的商业应用是使用WCF RIA Services构成的（这并不奇怪，它确实是一个强大的高扩展性框架）。然而它对集合类型的支持可以变得更好。你经常会做这样的操作：获取实体（通常是一个Load Operation）在其完成事件中将其添加到一个ObservableCollection&amp;lt;T&amp;gt;中，现在你依然可以这样做。不过在WCF RIA Services的第一个SP中分别对一些之前就存在的集合类型进行了加强，同事也增加了一些新的集合类型。这些变化使你在使用WCF RIA Services配合MVVM模式时更得心应手。现在我们可用的集合可以自动跟踪你的DomainContext，你可以添加过滤、排序甚至分组条件，还提供了一个服务端可分页的DomainCollectionView。在这篇文章中，我们会一起探讨一下这些增强及新增的新集合类型以及看看它们在哪些场景中使用起来更给力。&lt;/p&gt;  &lt;p&gt;本文中将会涉及WCF RIA Services中的四种集合类型：EntitySet（增强）、EntityList（新增）、CollectionView（增强）以及DomainCollectionView（新增）。你可以在&lt;a href="http://www.silverlightshow.net/Storage/Sources/WCFRIAColl.zip"&gt;这里下载源码&lt;/a&gt;。&lt;/p&gt;  &lt;p&gt;WCF RIA Services SP1包含在Visual Studio 2010 SP1中，&lt;a href="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=75568aa6-8107-475d-948a-ef22627e57a5&amp;amp;displaylang=en"&gt;点此下载&lt;/a&gt;。&lt;/p&gt;  &lt;p&gt;&lt;b&gt;EntitySet&amp;lt;T&amp;gt;&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;EntitySet是WCF RIA Services应用程序中的一个基本集合类型—当我们建立ViewModel时会经常用到它。它是一个带有一些用来自定义返回类型选项的无序集合。因此当我们想查看通过DomainContext载入的某个类型的所有实体时，我们会经常使用它。&lt;/p&gt;  &lt;p&gt;下图是一个示例程序，我将Books属性绑定到ListBox上。&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.silverlightshow.net/Storage/Users/KevinDockx/__image_2.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="clip_image002" border="0" alt="clip_image002" src="http://images.cnblogs.com/cnblogs_com/024hi/201107/201107151604437819.gif" width="546" height="311" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;看下面的代码：&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;/// &lt;/span&gt;&lt;span style="color: #7d9b7d"&gt;The Books property&lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;public &lt;/span&gt;&lt;span style="color: #efefaf"&gt;EntitySet&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #efefaf"&gt;Book&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;&amp;gt; Books{    &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;get&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;{        &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;return &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;Context.Books;    }}&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;像你看到的那样，Books属性是一个Book类型的EntitySet集合，它只是Context.Books的简单引用。在构造函数中，我们载入10条数据：&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #dac6a5"&gt;public &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;EntitySetViewModel() {    InstantiateCommands();    &lt;/span&gt;&lt;span style="color: #7d9b7d"&gt;// load books    &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;Context.Load&amp;lt;&lt;/span&gt;&lt;span style="color: #efefaf"&gt;Book&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;&amp;gt;(Context.GetBooksQuery().Take(&lt;/span&gt;&lt;span style="color: #8cd0d3"&gt;10&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;));}&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;当需要更多数据时，这样&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #d7d7c8"&gt;LoadMoreBooks = &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;new &lt;/span&gt;&lt;span style="color: #efefaf"&gt;RelayCommand&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;(() =&amp;gt; {    Context.Load&amp;lt;&lt;/span&gt;&lt;span style="color: #efefaf"&gt;Book&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;&amp;gt;(Context.GetBooksQuery());});&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;当更多的Book类型的实体被添加到正确的Context.Books这个EntitySet时，这些新增的Books也被加载到ListBox中。换句话说，当Book数据被DomainContext载入时，它们也被同时添加到ContextBooks这个EntitySet中了。&lt;/p&gt;&lt;p&gt;&lt;b&gt;EntitySet&amp;lt;T&amp;gt;:&lt;/b&gt;&lt;b&gt;添加和移除数据&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;那么如何向EntitySet添加或移除数据呢？下面的代码展示如何添加数据：&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #d7d7c8"&gt;AddBook = &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;new &lt;/span&gt;&lt;span style="color: #efefaf"&gt;RelayCommand&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;(() =&amp;gt; {    Context.Books.Add(&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;new &lt;/span&gt;&lt;span style="color: #efefaf"&gt;Book&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;() {        Author = &lt;/span&gt;&lt;span style="color: #dca3a3"&gt;&amp;quot;Kevin Dockx&amp;quot;        &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;,        ASIN = &lt;/span&gt;&lt;span style="color: #dca3a3"&gt;&amp;quot;123456&amp;quot;        &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;,        Title = &lt;/span&gt;&lt;span style="color: #dca3a3"&gt;&amp;quot;Dummy book&amp;quot;    &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;});});&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;然后是移除数据:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #d7d7c8"&gt;DeleteBook = &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;new &lt;/span&gt;&lt;span style="color: #efefaf"&gt;RelayCommand&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;(() =&amp;gt; {    Context.Books.Remove(Context.Books.FirstOrDefault());});&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;当你调用SubmitChanges()方法时，DomainService会将增加/删除的数据切实的反映为服务端的相应操作。&lt;/p&gt;&lt;p&gt;&lt;b&gt;EnityList&amp;lt;T&amp;gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;下一个要介绍的集合类型是：EntityList&amp;lt;T&amp;gt;，它是一个新增的集合类型，你可以在&lt;a href="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=6f834bf7-ffde-4d5d-8573-18541762118b"&gt;WCF RIA Services Toolkit&lt;/a&gt;中找到它，它位于Microsoft.Windows.Data.DomainServices命名空间下（源码中已经包含了这个程序集）。本质上说它是一个基于EntitySet的Observable集合。它的优点是允许我们取得通过DomainContext载入的特定类型实体数据的子集。定义一个EntityList&amp;lt;T&amp;gt;属性大概是如下的样子：&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #dac6a5"&gt;private &lt;/span&gt;&lt;span style="color: #efefaf"&gt;EntityList&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #efefaf"&gt;Book&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;&amp;gt; _books;&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;public &lt;/span&gt;&lt;span style="color: #efefaf"&gt;EntityList&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #efefaf"&gt;Book&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;&amp;gt; Books {    &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;get &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;{        &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;if &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;(&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;this&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;._books == &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;null&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;) {            &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;this&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;._books = &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;new &lt;/span&gt;&lt;span style="color: #efefaf"&gt;EntityList&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #efefaf"&gt;Book&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;&amp;gt;(                &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;this&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;.Context.Books);        }        &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;return this&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;._books;    }}&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Entity List有一个Source属性，它定义了EntityList应该包含的实体：&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #dac6a5"&gt;public &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;EntityListViewModel() {    InstantiateCommands();    &lt;/span&gt;&lt;span style="color: #7d9b7d"&gt;// load books    &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;this&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;.Books.Source = Context.Load&amp;lt;&lt;/span&gt;&lt;span style="color: #efefaf"&gt;Book&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;&amp;gt;(Context.GetBooksQuery().Take(&lt;/span&gt;&lt;span style="color: #8cd0d3"&gt;10&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;)).Entities;}&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;通过这两段代码，你的EntityList就已经初始化并准备好了。&lt;/p&gt;&lt;p&gt;一旦你开始读取更多的Book类型实体，事情就变得有趣起来了：数据变化不会自动的反映到你的EntityList中。如果你想让EntityList对那些新增的Book作出反应，则需要设置它的Source属性：&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #d7d7c8"&gt;LoadMoreBooks = &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;new &lt;/span&gt;&lt;span style="color: #efefaf"&gt;RelayCommand&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;(() =&amp;gt; {    &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;this&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;.Books.Source = Context.Load&amp;lt;&lt;/span&gt;&lt;span style="color: #efefaf"&gt;Book&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;&amp;gt;(Context.GetBooksQuery()).Entities;});&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;&lt;b&gt;EntityList&amp;lt;T&amp;gt;:&lt;/b&gt;&lt;b&gt;添加和移除数据&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;添加一条新的Book实体通常通过两种方式，直接添加到Context中或添加到EntityList本身。这两种方式需要使用不同的方法处理。可以看到我们示例中的代码：&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #d7d7c8"&gt;AddBook = &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;new &lt;/span&gt;&lt;span style="color: #efefaf"&gt;RelayCommand&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;(() =&amp;gt; {    Context.Books.Add(&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;new &lt;/span&gt;&lt;span style="color: #efefaf"&gt;Book&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;() {        Author = &lt;/span&gt;&lt;span style="color: #dca3a3"&gt;&amp;quot;Kevin Dockx&amp;quot;        &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;,        ASIN = &lt;/span&gt;&lt;span style="color: #dca3a3"&gt;&amp;quot;123456&amp;quot;        &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;,        Title = &lt;/span&gt;&lt;span style="color: #dca3a3"&gt;&amp;quot;Dummy book&amp;quot;    &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;});});&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;一条新的Book被添加到Context中。不过EntityList不会自动的获知这些变化（上文说过，实现项的子集的变化跟踪需要通过设置Source属性，而非每次Context的载入变化），ListBox仍然显示EntityList的Source属性中的实体数据集合。&lt;/p&gt;&lt;p&gt;当如下代码执行时：&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #d7d7c8"&gt;AddBookToEntityList = &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;new &lt;/span&gt;&lt;span style="color: #efefaf"&gt;RelayCommand&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;(() =&amp;gt; {    Books.Add(&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;new &lt;/span&gt;&lt;span style="color: #efefaf"&gt;Book&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;() {        Author = &lt;/span&gt;&lt;span style="color: #dca3a3"&gt;&amp;quot;Kevin Dockx&amp;quot;        &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;,        ASIN = &lt;/span&gt;&lt;span style="color: #dca3a3"&gt;&amp;quot;123456&amp;quot;        &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;,        Title = &lt;/span&gt;&lt;span style="color: #dca3a3"&gt;&amp;quot;Dummy book&amp;quot;    &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;});});&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;一条新的Book实体被添加到EntityList中，这将直接反映到我们的ListBox控件中。如果EntitySet中不存在这条Book实体，则它会被同时添加到其对应的EntitySet中。&lt;/p&gt;&lt;p&gt;而移除一条Book的行为又有一些不同：当你从Context的EntitySet中移除Book数据的时候，它会直接反映到EntityList中：&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #d7d7c8"&gt;DeleteBook = &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;new &lt;/span&gt;&lt;span style="color: #efefaf"&gt;RelayCommand&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;(() =&amp;gt; {    Context.Books.Remove(Context.Books.FirstOrDefault());});&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;当你从EntityList中移除一条Book时，EntitySet中也会同时移除这条实体。&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #d7d7c8"&gt;DeleteBookFromEntityList = &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;new &lt;/span&gt;&lt;span style="color: #efefaf"&gt;RelayCommand&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;(() =&amp;gt; {    Books.Remove(Books.FirstOrDefault());});&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;这是本文的第一部分，第二部分将会对更高级的集合类型进行介绍，他们是：ICollectionView和DomainCollectionView，敬请期待。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/024hi/aggbug/2107554.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/024hi/archive/2011/07/15/2107554.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/024hi/archive/2011/06/28/2091949.html</id><title type="text">Silverlight通过MVVM实现多语言实时切换（含源代码）</title><summary type="text">由于本示例基于MVVMLightToolkit，所以我们的ViewModel基类继承自MVVMLightToolkit提供的ViewModelBase，并命名为AdvancedViewModelBase，项目中所有的ViewModel都继承自这个类,先看类图： 由于本示例基于MVVMLightToolkit，所以我们的ViewModel基类继承自MVVMLightToolkit提供的ViewMod...</summary><published>2011-06-28T02:13:00Z</published><updated>2011-06-28T02:13:00Z</updated><author><name>紫色永恒</name><uri>http://www.cnblogs.com/024hi/</uri></author><link rel="alternate" href="http://www.cnblogs.com/024hi/archive/2011/06/28/2091949.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/024hi/archive/2011/06/28/2091949.html"/><content type="html">&lt;p&gt;由于本示例基于MVVMLightToolkit，所以我们的ViewModel基类继承自MVVMLightToolkit提供的ViewModelBase，并命名为AdvancedViewModelBase，项目中所有的ViewModel都继承自这个类,先看类图：&lt;/p&gt;  &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/024hi/201106/201106281012262212.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/024hi/201106/20110628101227184.png" width="473" height="324" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;由于本示例基于MVVMLightToolkit，所以我们的ViewModel基类继承自MVVMLightToolkit提供的ViewModelBase，并命名为AdvancedViewModelBase，项目中所有的ViewModel都继承自这个类。&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;本文的重点是“实时”切换。我们知道，ViewModel中的属性发生变化时如果要将变化反映到界面中则必将使用通知机制—INotifyPropertyChanged，因此我们引入了一个中间“代理”类ObservableResources，代码如下：&lt;/p&gt;  &lt;pre class="code"&gt;&lt;p&gt;    &lt;span style="color: #dac6a5"&gt;public class &lt;/span&gt;&lt;span style="color: #efefaf"&gt;ObservableResources &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;: &lt;/span&gt;&lt;span style="color: #d0d081"&gt;INotifyPropertyChanged &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;{        &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;public string this&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;[&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;string &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;resourceName] {            &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;get &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;{                &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;return &lt;/span&gt;&lt;span style="color: #efefaf"&gt;Language&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;.ResourceManager.GetString(resourceName);            }        }        &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;public event &lt;/span&gt;&lt;span style="color: #efefaf"&gt;PropertyChangedEventHandler &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;PropertyChanged;        &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;public void &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;UpdateBindings() {            &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;if &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;(PropertyChanged != &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;null&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;)                PropertyChanged(&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;this&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;, &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;new &lt;/span&gt;&lt;span style="color: #efefaf"&gt;PropertyChangedEventArgs&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;(&lt;/span&gt;&lt;span style="color: #dca3a3"&gt;&amp;quot;Item[]&amp;quot;&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;));        }    }&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #d7d7c8"&gt;&lt;/span&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #d7d7c8"&gt;&lt;/span&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #d7d7c8"&gt;&lt;/span&gt;&amp;#160;&lt;/p&gt;&lt;/pre&gt;&lt;p&gt;注意，因为我们使用了类的索引器，所以PropertyChangedEventArgs的参数应该为“Item[]”，Language类为资源文件自动生成。&lt;/p&gt;&lt;p&gt;之后，我们在AdvancedViewModelBase类中对其进行实例化。AdvancedViewModelBase的关键代码如下：&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;pre class="code"&gt;        &lt;span style="color: #dac6a5"&gt;public &lt;/span&gt;&lt;span style="color: #efefaf"&gt;ObservableResources &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;LanguageResource { &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;get&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;; &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;set&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;; }        &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;public &lt;/span&gt;&lt;span style="color: #d0d081"&gt;ICommand &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;ChangeLanguageCommand { &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;get&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;; &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;set&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;; }        &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;public &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;AdvancedViewModelBase() {            LanguageResource = &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;new &lt;/span&gt;&lt;span style="color: #efefaf"&gt;ObservableResources&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;();            ChangeLanguageCommand = &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;new &lt;/span&gt;&lt;span style="color: #efefaf"&gt;RelayCommand&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #efefaf"&gt;EdsLanguage&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;&amp;gt;(ChangeLanguage);        }        &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;private void &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;ChangeLanguage(&lt;/span&gt;&lt;span style="color: #efefaf"&gt;EdsLanguage &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;lang) {            &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;var &lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;culture = &lt;/span&gt;&lt;span style="color: #dac6a5"&gt;new &lt;/span&gt;&lt;span style="color: #efefaf"&gt;CultureInfo&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;(lang.CultureName);            &lt;/span&gt;&lt;span style="color: #efefaf"&gt;Thread&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;.CurrentThread.CurrentCulture = culture;            &lt;/span&gt;&lt;span style="color: #efefaf"&gt;Thread&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;.CurrentThread.CurrentUICulture = culture;            LanguageResource.UpdateBindings();        }&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;这里我们准备了一个ICommand以供在界面中进行绑定，当ChangeLanguageCommand被激活时执行ChangeLanguage方法（传递选定的语言类型），调用LanguageResource的UpdateBindings方法通知界面当前Culture的改变。&lt;/p&gt;&lt;p&gt;EdsLanguage类为自定义，定义了Culture、图标及语言信息。&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/024hi/201106/201106281012314791.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/024hi/201106/201106281012325413.png" width="163" height="199" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;在XAML中，需要使用多语言的部分则需如此调用&lt;/p&gt;&lt;pre class="code"&gt;&lt;p&gt;&lt;span style="color: #efefaf"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;TextBlock &lt;/span&gt;&lt;span style="color: #efefaf"&gt;Grid.Row=&lt;/span&gt;&lt;span style="color: #dca3a3"&gt;&amp;quot;0&amp;quot; &lt;/span&gt;&lt;span style="color: #efefaf"&gt;Grid.Column=&lt;/span&gt;&lt;span style="color: #dca3a3"&gt;&amp;quot;0&amp;quot; &lt;/span&gt;&lt;span style="color: #efefaf"&gt;Text=&amp;quot;{&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;Binding &lt;/span&gt;&lt;span style="color: #efefaf"&gt;LanguageResource[&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;Login_UserNameLabel&lt;/span&gt;&lt;span style="color: #efefaf"&gt;]}&lt;/span&gt;&lt;span style="color: #dca3a3"&gt;&amp;quot; &lt;/span&gt;&lt;span style="color: #efefaf"&gt;/&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #efefaf"&gt;&lt;/span&gt;&amp;#160;&lt;/p&gt;&lt;/pre&gt;&lt;p&gt;其中Login_UserNameLabel则为资源文件中的Name。  &lt;br /&gt;&lt;/p&gt;&lt;p&gt;改变语言类型的示例（本例使用了EventToCommand，当然用其他方式也可）：&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #efefaf"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;ComboBox &lt;/span&gt;&lt;span style="color: #efefaf"&gt;SelectedItem=&amp;quot;{&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;Binding &lt;/span&gt;&lt;span style="color: #efefaf"&gt;SelectedLanguage}&lt;/span&gt;&lt;span style="color: #dca3a3"&gt;&amp;quot; &lt;/span&gt;&lt;span style="color: #efefaf"&gt;ItemsSource=&amp;quot;{&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;Binding &lt;/span&gt;&lt;span style="color: #efefaf"&gt;EdsLangList}&lt;/span&gt;&lt;span style="color: #dca3a3"&gt;&amp;quot; &lt;/span&gt;&lt;span style="color: #efefaf"&gt;x:Name=&lt;/span&gt;&lt;span style="color: #dca3a3"&gt;&amp;quot;cbLanguage&amp;quot;  &lt;/span&gt;&lt;span style="color: #efefaf"&gt;Width=&lt;/span&gt;&lt;span style="color: #dca3a3"&gt;&amp;quot;110&amp;quot; &lt;/span&gt;&lt;span style="color: #efefaf"&gt;Height=&lt;/span&gt;&lt;span style="color: #dca3a3"&gt;&amp;quot;30&amp;quot; &lt;/span&gt;&lt;span style="color: #efefaf"&gt;HorizontalAlignment=&lt;/span&gt;&lt;span style="color: #dca3a3"&gt;&amp;quot;Left&amp;quot;&lt;/span&gt;&lt;span style="color: #efefaf"&gt;&amp;gt;    &amp;lt;&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;i&lt;/span&gt;&lt;span style="color: #efefaf"&gt;:&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;Interaction.Triggers&lt;/span&gt;&lt;span style="color: #efefaf"&gt;&amp;gt;        &amp;lt;&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;i&lt;/span&gt;&lt;span style="color: #efefaf"&gt;:&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;EventTrigger &lt;/span&gt;&lt;span style="color: #efefaf"&gt;EventName=&lt;/span&gt;&lt;span style="color: #dca3a3"&gt;&amp;quot;SelectionChanged&amp;quot;&lt;/span&gt;&lt;span style="color: #efefaf"&gt;&amp;gt;            &amp;lt;&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;cmd&lt;/span&gt;&lt;span style="color: #efefaf"&gt;:&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;EventToCommand &lt;/span&gt;&lt;span style="color: #efefaf"&gt;Command=&amp;quot;{&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;Binding &lt;/span&gt;&lt;span style="color: #efefaf"&gt;ChangeLanguageCommand}&lt;/span&gt;&lt;span style="color: #dca3a3"&gt;&amp;quot; &lt;/span&gt;&lt;span style="color: #efefaf"&gt;CommandParameter=&amp;quot;{&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;Binding &lt;/span&gt;&lt;span style="color: #efefaf"&gt;ElementName=&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;cbLanguage&lt;/span&gt;&lt;span style="color: #efefaf"&gt;,Path=&lt;/span&gt;&lt;span style="color: #d7d7c8"&gt;SelectedItem&lt;/span&gt;&lt;span style="color: #efefaf"&gt;}&lt;/span&gt;&lt;span style="color: #dca3a3"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #efefaf"&gt;/&amp;gt;        &amp;lt;/&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;i&lt;/span&gt;&lt;span style="color: #efefaf"&gt;:&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;EventTrigger&lt;/span&gt;&lt;span style="color: #efefaf"&gt;&amp;gt;    &amp;lt;/&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;i&lt;/span&gt;&lt;span style="color: #efefaf"&gt;:&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;Interaction.Triggers&lt;/span&gt;&lt;span style="color: #efefaf"&gt;&amp;gt;    &amp;lt;&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;ComboBox.ItemTemplate&lt;/span&gt;&lt;span style="color: #efefaf"&gt;&amp;gt;        &amp;lt;&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;DataTemplate&lt;/span&gt;&lt;span style="color: #efefaf"&gt;&amp;gt;            &amp;lt;&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;StackPanel &lt;/span&gt;&lt;span style="color: #efefaf"&gt;Orientation=&lt;/span&gt;&lt;span style="color: #dca3a3"&gt;&amp;quot;Horizontal&amp;quot;&lt;/span&gt;&lt;span style="color: #efefaf"&gt;&amp;gt;                &amp;lt;&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;Image &lt;/span&gt;&lt;span style="color: #efefaf"&gt;Width=&lt;/span&gt;&lt;span style="color: #dca3a3"&gt;&amp;quot;28&amp;quot; &lt;/span&gt;&lt;span style="color: #efefaf"&gt;Height=&lt;/span&gt;&lt;span style="color: #dca3a3"&gt;&amp;quot;28&amp;quot; &lt;/span&gt;&lt;span style="color: #efefaf"&gt;Source=&amp;quot;{&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;Binding &lt;/span&gt;&lt;span style="color: #efefaf"&gt;FlagIcon}&lt;/span&gt;&lt;span style="color: #dca3a3"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #efefaf"&gt;/&amp;gt;                &amp;lt;&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;TextBlock &lt;/span&gt;&lt;span style="color: #efefaf"&gt;Text=&amp;quot;{&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;Binding &lt;/span&gt;&lt;span style="color: #efefaf"&gt;LanguageName}&lt;/span&gt;&lt;span style="color: #dca3a3"&gt;&amp;quot; &lt;/span&gt;&lt;span style="color: #efefaf"&gt;VerticalAlignment=&lt;/span&gt;&lt;span style="color: #dca3a3"&gt;&amp;quot;Center&amp;quot;&lt;/span&gt;&lt;span style="color: #efefaf"&gt;/&amp;gt;            &amp;lt;/&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;StackPanel&lt;/span&gt;&lt;span style="color: #efefaf"&gt;&amp;gt;        &amp;lt;/&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;DataTemplate&lt;/span&gt;&lt;span style="color: #efefaf"&gt;&amp;gt;    &amp;lt;/&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;ComboBox.ItemTemplate&lt;/span&gt;&lt;span style="color: #efefaf"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #dac6a5"&gt;ComboBox&lt;/span&gt;&lt;span style="color: #efefaf"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;示例源代码：&lt;a title="http://files.cnblogs.com/024hi/SwitchLanguageDemo.zip" href="http://files.cnblogs.com/024hi/SwitchLanguageDemo.zip"&gt;http://files.cnblogs.com/024hi/SwitchLanguageDemo.zip&lt;/a&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/024hi/aggbug/2091949.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/024hi/archive/2011/06/28/2091949.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/024hi/archive/2011/06/23/2088295.html</id><title type="text">Silverlight中服务通信方式的选择(WCF、Data Service、Ria Service)</title><summary type="text">WCF Service(WebService) Web Services是经实践考验证明的跨防火墙的通信方式，它很稳定且被广泛认可。总的来说你需要为分散的CRUD操作指定相应的接口并在Silverlight中忠实的调用他们 使用的原因：需要进行类似直接通过服务进行数据库交互操作的项目（弱化业务逻辑部分）。 避免使用的原因：必须始终自己监视数据的变化并调用相应的服务方法进行更新，任何需要并发的操作或...</summary><published>2011-06-23T09:13:00Z</published><updated>2011-06-23T09:13:00Z</updated><author><name>紫色永恒</name><uri>http://www.cnblogs.com/024hi/</uri></author><link rel="alternate" href="http://www.cnblogs.com/024hi/archive/2011/06/23/2088295.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/024hi/archive/2011/06/23/2088295.html"/><content type="html">&lt;p&gt;&lt;strong&gt;WCF Service(WebService)&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Web Services是经实践考验证明的跨防火墙的通信方式，它很稳定且被广泛认可。总的来说你需要为分散的CRUD操作指定相应的接口并在Silverlight中忠实的调用他们&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;使用的原因：需要进行类似直接通过服务进行数据库交互操作的项目（弱化业务逻辑部分）。&lt;/li&gt;    &lt;li&gt;避免使用的原因：必须始终自己监视数据的变化并调用相应的服务方法进行更新，任何需要并发的操作或事务变得较为沉重且需要处理大量的代码。&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;ADO.NET Data Services&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;ADO.NET Data Services是一套简单的基于Rest的数据通信方式。它依赖于Http定义服务接口，如Get操作定义为读写、Post操作定义为更新等。它使用ATOM或JSON作为序列化格式，所以可以被各种类型的客户端调用。&lt;/p&gt;  &lt;p&gt;他通过将基于URI的API转换为LINQ调用从而提供插入、更新、删除等操作。这意味着ADO.NET本身是很单薄的一层，它的目的是将URI模型翻译为数据通信代码。&lt;/p&gt;  &lt;p&gt;对于Silverlight来说，ADO.NET Data Services真正的亮点在于其提供的客户端类库。这个客户端类库允许开发者在客户端使用LINQ查询并在服务端执行。当然它支持的LINQ语法相比服务端有一些局限，大概覆盖80%的场景，当然ADO.NET Data Service也允许开发者在必要时自定义剩余的操作以适应其他场景。另外，客户端类库提供一个强大的Data上下文类用以监视和处理有事务支持的批量操作。&lt;/p&gt;  &lt;p&gt;使用ADO.NET Data Services公开数据通信实际上是宫公开查询终结点的方式替代定义接口，这就是它最特别的地方。比如，我们可以像这样使用LINQ查询   &lt;table border="1" cellspacing="0" cellpadding="0"&gt;&lt;tbody&gt;       &lt;tr&gt;         &lt;td valign="top" width="568"&gt;           &lt;p&gt;// Silverlight 代码&lt;/p&gt;            &lt;p&gt;// 使用 LINQ 创建擦汗寻&lt;/p&gt;            &lt;p&gt;var qry = (from g in ds.Games&lt;/p&gt;            &lt;p&gt;where g.Price &amp;lt; 50m&lt;/p&gt;            &lt;p&gt;orderby g.Name&lt;/p&gt;            &lt;p&gt;select g) as DataServiceQuery&amp;lt;Game&amp;gt;;&lt;/p&gt;            &lt;p&gt;// 执行查询&lt;/p&gt;            &lt;p&gt;qry.BeginExecute(new AsyncCallback(r =&amp;gt;&lt;/p&gt;            &lt;p&gt;{&lt;/p&gt;            &lt;p&gt;games2.ItemsSource = qry.EndExecute(r).ToList();&lt;/p&gt;            &lt;p&gt;games2.DisplayMemberPath = &amp;quot;Name&amp;quot;;&lt;/p&gt;            &lt;p&gt;}), null);&lt;/p&gt;         &lt;/td&gt;       &lt;/tr&gt;     &lt;/tbody&gt;&lt;/table&gt; &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;使用的原因：想要一个简单、安全的模型使得开发人员可以在代码中定义他们需要的查询（相对于基于接口的WCF Service）。得益于LINQ调用及上下文类，使用ADO.NET Data Services客户端类库会让你的客户端代码量适当减少。&lt;/li&gt;    &lt;li&gt;避免使用的原因：当你想要严格控制数据访问接口及不想让可发者直接在客户端使用LINQ查询的情况下应该避免使用ADO.NET Data Services。&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;WCF RIA Services&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/024hi/201106/201106231712561085.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="clip_image001" border="0" alt="clip_image001" src="http://images.cnblogs.com/cnblogs_com/024hi/201106/201106231712573202.png" width="498" height="235" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;RIA Services基于这样的思想：在服务端创建数据通信API同时在Silverlight中生成相应的客户端代码。它的着重点在于服务端和客户端共享代码（包括验证逻辑等）。另外他还允许开发者创建一系列接口，并且同样在客户端提供上下文对象在客户端监视数据（包括批量操作）的变化并反馈给服务端。从某种程度上来说，RIA Services是Web Services和ADO.NET Data的集大成者。&lt;/p&gt;  &lt;p&gt;由于RIA Services基于服务端查询接口定义，在客户端开发人员可以像这样调用其接口定义的查询：   &lt;table border="1" cellspacing="0" cellpadding="0"&gt;&lt;tbody&gt;       &lt;tr&gt;         &lt;td valign="top" width="568"&gt;           &lt;p&gt;// Silverlight代码&lt;/p&gt;            &lt;p&gt;// context 对象监视数据变化&lt;/p&gt;            &lt;p&gt;XBoxGamesContext ctx = new XBoxGamesContext();&lt;/p&gt;            &lt;p&gt;// RIA 查询，基于接口&lt;/p&gt;            &lt;p&gt;var qry = ctx.GetGamesByGenreQuery(&amp;quot;Shooter&amp;quot;);&lt;/p&gt;            &lt;p&gt;// 绑定数据&lt;/p&gt;            &lt;p&gt;theList.ItemsSource = ctx.Load&amp;lt;Game&amp;gt;(qry).AllEntities;&lt;/p&gt;         &lt;/td&gt;       &lt;/tr&gt;     &lt;/tbody&gt;&lt;/table&gt; &lt;/p&gt;  &lt;p&gt;在介绍ADO.NET Data Services时曾提到开发人员可以使用LINQ查询，RIA Services同样允许向查询终结点添加LINQ 约束。例如你可以这样对终结点添加LINQ表达式：   &lt;table border="1" cellspacing="0" cellpadding="0"&gt;&lt;tbody&gt;       &lt;tr&gt;         &lt;td valign="top" width="568"&gt;           &lt;p&gt;var riaQry = ctx.GetGamesQuery()&lt;/p&gt;            &lt;p&gt;.Where(g =&amp;gt; g.Price &amp;lt; 50m)&lt;/p&gt;            &lt;p&gt;.OrderBy(g =&amp;gt; g.Name);&lt;/p&gt;            &lt;p&gt;LoadOperation&amp;lt;Game&amp;gt; op = &lt;/p&gt;            &lt;p&gt;ctx.Load&amp;lt;Game&amp;gt;(riaQry);&lt;/p&gt;         &lt;/td&gt;       &lt;/tr&gt;     &lt;/tbody&gt;&lt;/table&gt; &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;使用的原因： RIA Services可以有力的减少应用程序层级数量，尤其适用于需要快速反应的应用程序开发场景。RIA Service同时提供了像WebService那样基于接口的支持及像ADO.NET Data Services中基于LINQ查询的支持。&lt;/li&gt;    &lt;li&gt;避免使用的原因：RIA Services中利用了很多系统自动生成的代码，调试时可能会碰到麻烦。&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;那么你的选择是？欢迎讨论~&lt;/p&gt;&lt;img src="http://www.cnblogs.com/024hi/aggbug/2088295.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/024hi/archive/2011/06/23/2088295.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/024hi/archive/2011/04/26/2029545.html</id><title type="text">你应该知道的，那些未在Silverlight5Beta中出现的特性</title><summary type="text">距离Silverlight5(beta)华丽丽的亮相已经有一段日子了，园子里也有同道陆续放出了beta版中新玩意的体验和介绍，比如乱世经典的这些文章，估计大家早也已经对beta版sl5带来的新特性了然于胸了。 而这篇文章的目的则是要向大家介绍一下那些没有赶上beta版末班车却又让我们“魂牵梦绕”的sl5新特性。废话少说，且听我一一道来。 DataContextChanged事件 顾名思义，当Dat...</summary><published>2011-04-26T09:14:00Z</published><updated>2011-04-26T09:14:00Z</updated><author><name>紫色永恒</name><uri>http://www.cnblogs.com/024hi/</uri></author><link rel="alternate" href="http://www.cnblogs.com/024hi/archive/2011/04/26/2029545.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/024hi/archive/2011/04/26/2029545.html"/><content type="html">&lt;p&gt;距离Silverlight5(beta)华丽丽的亮相已经有一段日子了，园子里也有同道陆续放出了beta版中新玩意的体验和介绍，比如&lt;a href="http://www.cnblogs.com/chenkai/"&gt;乱世经典&lt;/a&gt;的&lt;a href="http://www.cnblogs.com/chenkai/archive/2011/04/26/2029405.html"&gt;这些文章&lt;/a&gt;，估计大家早也已经对beta版sl5带来的新特性了然于胸了。&lt;/p&gt;  &lt;p&gt;而这篇文章的目的则是要向大家介绍一下那些没有赶上beta版末班车却又让我们“魂牵梦绕”的sl5新特性。废话少说，且听我一一道来。&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;DataContextChanged事件 &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;顾名思义，当DataContext发生变化时将会触发该事件。现在sl的fans不用再羡慕wpf的这个事件了吧。不过话说回来，其实sl的FrameworkElement本来是提供了这个事件的，不过因为被标记为internal而一直无法使用。&lt;/p&gt;  &lt;p&gt;来看一下示例代码：&lt;/p&gt;  &lt;pre class="code2"&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;&lt;span style="color: #535353"&gt;.DataContextChanged += View_DataContextChanged;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="code2"&gt;&lt;span style="color: blue"&gt;void &lt;/span&gt;&lt;span style="color: #535353"&gt;View_DataContextChanged(&lt;/span&gt;&lt;span style="color: blue"&gt;object &lt;/span&gt;&lt;span style="color: #535353"&gt;sender, &lt;/span&gt;&lt;/pre&gt;&lt;pre class="code2"&gt;&lt;span style="color: #535353"&gt;&lt;/span&gt;&lt;span style="color: #2b91af"&gt;                  DependencyPropertyChangedEventArgs &lt;/span&gt;&lt;span style="color: #535353"&gt;e) {    &lt;/span&gt;&lt;span style="color: #2b91af"&gt;INotifyPropertyChanged &lt;/span&gt;&lt;span style="color: #535353"&gt;customer;    customer = e.OldValue &lt;/span&gt;&lt;span style="color: blue"&gt;as &lt;/span&gt;&lt;span style="color: #2b91af"&gt;INotifyPropertyChanged&lt;/span&gt;&lt;span style="color: #535353"&gt;;    &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;&lt;span style="color: #535353"&gt;(customer != &lt;/span&gt;&lt;span style="color: blue"&gt;null&lt;/span&gt;&lt;span style="color: #535353"&gt;)        customer.PropertyChanged -= customer_PropertyChanged;    customer = e.NewValue &lt;/span&gt;&lt;span style="color: blue"&gt;as &lt;/span&gt;&lt;span style="color: #2b91af"&gt;INotifyPropertyChanged&lt;/span&gt;&lt;span style="color: #535353"&gt;;    &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;&lt;span style="color: #535353"&gt;(customer != &lt;/span&gt;&lt;span style="color: blue"&gt;null&lt;/span&gt;&lt;span style="color: #535353"&gt;)        customer.PropertyChanged += customer_PropertyChanged;}&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;DependencyPrpertyChangedEventArges有三个属性NewValue、OldValue及Property。利用这个事件我们更好处理引用提高内存使用效率。&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;ul&gt;  &lt;li&gt;UpdateSourceTrigger新增了对PropertyChanged的支持 &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;这个很有意义啊，人家WPF早就有这玩意而且在TextBox控件上是默认的UpdateSourceTrigger，而之前的sl就像个后娘养的…现在好了，做双向绑定的时候可以不再郁闷了。&lt;/p&gt;&lt;ul&gt;  &lt;li&gt;增强了文字清晰度 &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;在之前的版本中，文字的清晰度一直备受怨念。不过微软说sl5中会提高文本与像素图像捕捉并为小型的阅读设备提供更好的体验。官方ppt中提供了下面这几张老图（当年介绍wpf4时候用过的），这是否代表我们暂且可以认为sl5最起码会做到wpf4的程度？&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/024hi/201104/20110426171320459.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/024hi/201104/201104261713222246.png" width="542" height="206" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/024hi/201104/20110426171325454.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/024hi/201104/20110426171326322.png" width="543" height="29" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/024hi/201104/201104261713297582.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/024hi/201104/201104261713303023.png" width="543" height="33" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;ul&gt;  &lt;li&gt;矢量打印 &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;如果让诸位用一个流行的词形容当前sl的打印功能，你们会想到什么？没错，就是“坑爹”。我们都知道，当前sl打印是基于bitmap（位图）的，而位图打印的两大缺陷则分别为占地面积大和缩放会照成很大损失。让我们看一些位图和矢量图的性能、容量、缩放清晰度对比&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/024hi/201104/201104261713305432.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/024hi/201104/201104261713329760.png" width="539" height="201" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/024hi/201104/20110426171333218.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/024hi/201104/20110426171333675.png" width="538" height="183" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/024hi/201104/201104261713374216.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/024hi/201104/201104261713394574.png" width="292" height="296" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;好吧，我想你懂的，这就是为什么矢量打印在sl5的wishlist中占据那么高的位置的原因。&lt;/p&gt;&lt;ul&gt;  &lt;li&gt;Trick Play &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;这个东西我不大清楚，还望对媒体播放及TrickPlay有所了解的兄弟解惑。&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;暂时就这些吧，Silverlight5正式版将在2011年下半年登场，不过上文中提到的这些新特性会提前出现在Silverlight5的RC版中也是说不定的事哦~&lt;/p&gt;&lt;img src="http://www.cnblogs.com/024hi/aggbug/2029545.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/024hi/archive/2011/04/26/2029545.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/024hi/archive/2011/02/18/1957887.html</id><title type="text">记录来敦煌一周的情况</title><summary type="text">生活情况：从兰州机场出来我们都傻了，遍地的土黄色的山。从兰州机场坐大客到火车站的一路都不知道是什么感觉了。在火车站幸运的买到最后两张当天的卧铺票第二天早上10点多到达敦煌。在火车上看到的景色就更别提了，沙漠，骆驼草什么的。经过世界最长隧道（23公里）的时候出现轻微高原反映，第二天就好多了。 敦煌火车站很气派，不过这个好像是世界上距离市区最远的火车站，从火车站打车到达目的地除了一些葡萄架和奇奇怪怪的枯树外神马都没看到。 敦煌古镇咱们是没看到，据说繁华的地方和沈阳差不多，不繁华的地方那也不用说了。我们这地方是七里镇，基本都是油田的人。被安排在处理井下业务的一个办公楼的一楼。条件还算可以，不过缺了不</summary><published>2011-02-18T07:32:00Z</published><updated>2011-02-18T07:32:00Z</updated><author><name>紫色永恒</name><uri>http://www.cnblogs.com/024hi/</uri></author><link rel="alternate" href="http://www.cnblogs.com/024hi/archive/2011/02/18/1957887.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/024hi/archive/2011/02/18/1957887.html"/><content type="html">&lt;div&gt;&lt;strong&gt;生活情况：&lt;/strong&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;从兰州机场出来我们都傻了，遍地的土黄色的山。从兰州机场坐大客到火车站的一路都不知道是什么感觉了。在火车站幸运的买到最后两张当天的卧铺票第二天早上10点多到达敦煌。在火车上看到的景色就更别提了，沙漠，骆驼草什么的。经过世界最长隧道（23公里）的时候出现轻微高原反映，第二天就好多了。 &lt;/li&gt;&lt;li&gt;敦煌火车站很气派，不过这个好像是世界上距离市区最远的火车站，从火车站打车到达目的地除了一些葡萄架和奇奇怪怪的枯树外神马都没看到。 &lt;/li&gt;&lt;li&gt;敦煌古镇咱们是没看到，据说繁华的地方和沈阳差不多，不繁华的地方那也不用说了。我们这地方是七里镇，基本都是油田的人。被安排在处理井下业务的一个办公楼的一楼。条件还算可以，不过缺了不少东西，这挺愁人。厕所巨远，距离近的都是女厕。 &lt;/li&gt;&lt;li&gt;我俩用了半天时间去镇里最大的超市（我们挨着步行街，步行街超市连个盆都不卖！更不要说附近的小超市了，买个洗头膏都是假的）购置生活用品，不过人家压根不卖拖鞋，哦不，是只有棉布拖。。。 &lt;/li&gt;&lt;li&gt;这里的物价超贵，普通一个菜要20-30元，据说还是这里最便宜的饭店。 &lt;/li&gt;&lt;li&gt;这里的饭店可以自带酒水、可以打白条。 &lt;/li&gt;&lt;li&gt;这里的公交车竟然免费乘坐。 &lt;/li&gt;&lt;li&gt;第一天来的晚上和东哥的一个兄弟一起吃的饭，除了东哥外都喝多了。 &lt;/li&gt;&lt;li&gt;什么西出阳关无故人，西出阳关根本无人。 &lt;/li&gt;&lt;li&gt;这地方干燥到什么程度呢？袜子洗完放在屋子里一晚上就自动干了；如果有人被弃尸野外发现的时候基本是风干肠了；这里的葡萄干不是晒干的而是风干；每年降水20几毫米，蒸发量2000多毫米。基本是天高云淡阳光明媚，不时的来点沙尘暴。 &lt;/li&gt;&lt;li&gt;由于海拔原因，这的太阳感觉非常炫目，出门就不适应。 &lt;/li&gt;&lt;li&gt;这个季节来这儿其结果就是杯具。&lt;/li&gt;&lt;/ul&gt;&lt;img src="http://www.cnblogs.com/024hi/aggbug/1957887.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/024hi/archive/2011/02/18/1957887.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/024hi/archive/2011/01/07/1929441.html</id><title type="text">Silverlight奇技银巧7 - 巧用文件生成时间强制客户端载入最新xap文件</title><summary type="text">  像大多数的项目一样，即使在将Silverlight应用程序交付后，我们仍会根据客户的需求进行相应修改并将xap文件发送给客户，客户经过测试后再部署到生产环境。   这样经常会面临一个问题，客户更新xap后并未看到任何变化甚至由于我们wcf服务等相关文件的改动会让程序执行发生异常。这个原因倒是很明显--我们的xap文件被缓存了，当服务器上替换了新的xap文件时，本地并未重新从服务器上下...</summary><published>2011-01-07T02:12:00Z</published><updated>2011-01-07T02:12:00Z</updated><author><name>紫色永恒</name><uri>http://www.cnblogs.com/024hi/</uri></author><link rel="alternate" href="http://www.cnblogs.com/024hi/archive/2011/01/07/1929441.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/024hi/archive/2011/01/07/1929441.html"/><content type="html">&lt;p&gt;&amp;#160;&amp;#160;&amp;#160; 像大多数的项目一样，即使在将Silverlight应用程序交付后，我们仍会根据客户的需求进行相应修改并将xap文件发送给客户，客户经过测试后再部署到生产环境。&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; 这样经常会面临一个问题，客户更新xap后并未看到任何变化甚至由于我们wcf服务等相关文件的改动会让程序执行发生异常。这个原因倒是很明显--我们的xap文件被缓存了，当服务器上替换了新的xap文件时，本地并未重新从服务器上下载。这时候我们当然就要告知客户如何清理缓存等等，再碰到个电脑盲（大多情况下）更是苦不堪言。客户抱怨，项目经理哑巴吃黄连…&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; 那么有没有一种方法可以解决上面提到的问题呢？当然，且听分解。&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; 我们先看一段在html中签入Silverlight应用的标准代码示例&lt;/p&gt;  &lt;pre class="code code2"&gt;        &lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;object &lt;/span&gt;&lt;span style="color: red"&gt;data&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;data:application/x-silverlight-2,&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;application/x-silverlight-2&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;width&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;100%&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;height&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;100%&amp;quot;&amp;gt;          &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;param &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;source&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;ClientBin/MefSample.xap&amp;quot;/&amp;gt;          &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;param &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;onError&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;onSilverlightError&amp;quot; /&amp;gt;          &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;param &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;background&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;white&amp;quot; /&amp;gt;          &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;param &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;minRuntimeVersion&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;4.0.50826.0&amp;quot; /&amp;gt;          &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;param &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;autoUpgrade&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;true&amp;quot; /&amp;gt;          &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;a &lt;/span&gt;&lt;span style="color: red"&gt;href&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;http://go.microsoft.com/fwlink/?LinkID=149156&amp;amp;v=4.0.50826.0&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;style&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt;text-decoration&lt;/span&gt;&lt;span style="color: blue"&gt;:none&amp;quot;&amp;gt;               &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;img &lt;/span&gt;&lt;span style="color: red"&gt;src&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;http://go.microsoft.com/fwlink/?LinkId=161376&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;alt&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Get Microsoft Silverlight&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;style&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt;border-style&lt;/span&gt;&lt;span style="color: blue"&gt;:none&amp;quot;/&amp;gt;          &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;a&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;        &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;object&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160; 注意下面这行，我们就要从这里下手。&lt;/p&gt;&lt;pre class="code code2"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;param &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;source&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;ClientBin/MefSample.xap&amp;quot;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160; 我们知道，要防止浏览器自动缓存文件，经常用的一个做法就是在要加载的文件名后面加入一个随机字符串（比如验证码的刷新），如Guid、DateTime.Now.Ticks一类。&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160; 因此我们这里的思路就是通过判断xap文件的生成时间而决定是否重新载入xap包。&lt;/p&gt;&lt;p&gt;&amp;#160;&amp;#160;&amp;#160; 最终View的全部代码如下：&lt;/p&gt;&lt;pre class="code code2"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;object &lt;/span&gt;&lt;span style="color: red"&gt;data&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;data:application/x-silverlight-2,&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;application/x-silverlight-2&amp;quot;    &lt;/span&gt;&lt;span style="color: red"&gt;width&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;100%&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;height&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;100%&amp;quot;&amp;gt;    &lt;/span&gt;&lt;span style="background: yellow"&gt;@{&lt;/span&gt;        &lt;span style="color: blue"&gt;string &lt;/span&gt;xapFile = &lt;span style="color: #a31515"&gt;&amp;quot;ClientBin/MefSample.xap&amp;quot;&lt;/span&gt;;        &lt;span style="color: blue"&gt;string &lt;/span&gt;xapPath = &lt;span style="color: #2b91af"&gt;HttpContext&lt;/span&gt;.Current.Server.MapPath(&lt;span style="color: #a31515"&gt;&amp;quot;\\&amp;quot;&lt;/span&gt;) + xapFile;        &lt;span style="color: #2b91af"&gt;DateTime &lt;/span&gt;xapCreatedDate = System.IO.&lt;span style="color: #2b91af"&gt;File&lt;/span&gt;.GetLastWriteTime(xapPath);        xapFile += &lt;span style="color: #a31515"&gt;&amp;quot;?v=&amp;quot; &lt;/span&gt;+ xapCreatedDate;    &lt;span style="background: yellow"&gt;}&lt;/span&gt;    &lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;param &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;source&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="background: yellow"&gt;@&lt;/span&gt;&lt;span style="color: blue"&gt;xapFile&amp;quot; /&amp;gt;    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;param &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;onError&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;onSilverlightError&amp;quot; /&amp;gt;    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;param &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;background&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;white&amp;quot; /&amp;gt;    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;param &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;minRuntimeVersion&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;4.0.50826.0&amp;quot; /&amp;gt;    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;param &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;autoUpgrade&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;true&amp;quot; /&amp;gt;    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;a &lt;/span&gt;&lt;span style="color: red"&gt;href&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;http://go.microsoft.com/fwlink/?LinkID=149156&amp;amp;v=4.0.50826.0&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;style&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt;text-decoration&lt;/span&gt;&lt;span style="color: blue"&gt;: none&amp;quot;&amp;gt;        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;img &lt;/span&gt;&lt;span style="color: red"&gt;src&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;http://go.microsoft.com/fwlink/?LinkId=161376&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;alt&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Get Microsoft Silverlight&amp;quot;            &lt;/span&gt;&lt;span style="color: red"&gt;style&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt;border-style&lt;/span&gt;&lt;span style="color: blue"&gt;: none&amp;quot; /&amp;gt;    &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;a&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;object&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;注意，这里我是用ASP.NET MVC（Razor语法）承载xap，对WebForm或WebForm View同样适用，请自行更改。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/024hi/aggbug/1929441.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/024hi/archive/2011/01/07/1929441.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry></feed>
