<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">博客园_Mr. Write</title><subtitle type="text">always</subtitle><id>http://feed.cnblogs.com/blog/u/21593/rss</id><updated>2012-01-31T10:29:19Z</updated><author><name>董超</name><uri>http://www.cnblogs.com/dc10101/</uri></author><generator>CNBlogs BlogServer</generator><link rel="alternate" type="text/html" href="http://www.cnblogs.com/dc10101/"/><link rel="self" type="application/atom+xml" href="http://feed.cnblogs.com/blog/u/21593/rss"/><entry><id>http://www.cnblogs.com/dc10101/archive/2012/01/03/2310622.html</id><title type="text">Windows Phone 7监测网络环境变化</title><summary type="text">有些应用是跟网络环境敏感的，WiFi快且免费，3G走流量，GSM慢，所以我们需要知道如何判断当前的网络类型，以及当网络类型发生改变时如何得到通知。 MSDN相关文章：How To: Detect Network Changes 下面我简单介绍一下。 当网络发生变化时，会引发网络地址发生变化，要监测这一事件，需要用到位于System.Net.NetworkInformation命名空间下的Netw...</summary><published>2012-01-02T17:24:00Z</published><updated>2012-01-02T17:24:00Z</updated><author><name>董超</name><uri>http://www.cnblogs.com/dc10101/</uri></author><link rel="alternate" href="http://www.cnblogs.com/dc10101/archive/2012/01/03/2310622.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/dc10101/archive/2012/01/03/2310622.html"/><content type="html">&lt;p&gt;有些应用是跟网络环境敏感的，WiFi快且免费，3G走流量，GSM慢，所以我们需要知道如何判断当前的网络类型，以及当网络类型发生改变时如何得到通知。&lt;/p&gt; &lt;p&gt;MSDN相关文章：&lt;a href="http://msdn.microsoft.com/en-us/library/hh487166(v=VS.92).aspx"&gt;How To: Detect Network Changes&lt;/a&gt;&lt;/p&gt; &lt;p&gt;下面我简单介绍一下。&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;当网络发生变化时，会引发网络地址发生变化，要监测这一事件，需要用到位于&lt;a href="http://msdn.microsoft.com/en-us/library/system.net.networkinformation.aspx"&gt;&lt;strong&gt;System.Net.NetworkInformation&lt;/strong&gt;&lt;/a&gt;命名空间下的&lt;a href="http://msdn.microsoft.com/en-us/library/system.net.networkinformation.networkchange.aspx"&gt;NetworkChange&lt;/a&gt;类。&lt;/p&gt; &lt;p&gt;要查看网络连接的类型和状态，用到的类都在&lt;a href="http://msdn.microsoft.com/en-us/library/microsoft.phone.net.networkinformation(v=VS.92).aspx"&gt;&lt;b&gt;Microsoft.Phone.Net.NetworkInformation&lt;/b&gt;&lt;/a&gt;这个命名空间里。&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;注意上面两个不同的命名空间，&lt;a href="http://msdn.microsoft.com/en-us/library/microsoft.phone.net.networkinformation(v=VS.92).aspx"&gt;&lt;b&gt;Microsoft.Phone.Net.NetworkInformation&lt;/b&gt;&lt;/a&gt;是专门用于手机，&lt;a href="http://msdn.microsoft.com/en-us/library/system.net.networkinformation.aspx"&gt;&lt;strong&gt;System.Net.NetworkInformation&lt;/strong&gt;&lt;/a&gt;用于各种场合。由于这两个类中的名字冲突很多，一起用的时候注意区分好。&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;网络环境变化时得到通知&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;只需要监听一个事件：&lt;/p&gt;&lt;pre &gt;&lt;span style="color: #2b91af"&gt;NetworkChange&lt;/span&gt;.NetworkAddressChanged += &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;NetworkAddressChangedEventHandler&lt;/span&gt;(NetworkChange_NetworkAddressChanged);&#xD;
&lt;/pre&gt;&#xD;
&lt;p&gt;&lt;span style="color: blue"&gt;……&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;br&gt;&lt;pre &gt;&lt;span style="color: blue"&gt;void &lt;/span&gt;NetworkChange_NetworkAddressChanged(&lt;span style="color: blue"&gt;object &lt;/span&gt;sender, &lt;span style="color: #2b91af"&gt;EventArgs &lt;/span&gt;e)&#xD;
{&#xD;
    &lt;span style="color: blue"&gt;string &lt;/span&gt;content = &lt;span style="color: blue"&gt;string&lt;/span&gt;.Format(&#xD;
            &lt;span style="color: #a31515"&gt;@"CellularMobileOperator        {0}&#xD;
            IsCellularDataEnabled           {1}&#xD;
            IsCellularDataRoamingEnabled    {2}&#xD;
            IsNetworkAvailable              {3}&#xD;
            IsWiFiEnabled                   {4}"&lt;/span&gt;,&#xD;
            &lt;span style="color: #2b91af"&gt;DeviceNetworkInformation&lt;/span&gt;.CellularMobileOperator, &lt;span style="color: green"&gt;// 运营商名字，例如“中国移动”&#xD;
            &lt;/span&gt;&lt;span style="color: #2b91af"&gt;DeviceNetworkInformation&lt;/span&gt;.IsCellularDataEnabled,&#xD;
            &lt;span style="color: #2b91af"&gt;DeviceNetworkInformation&lt;/span&gt;.IsCellularDataRoamingEnabled,&#xD;
            &lt;span style="color: #2b91af"&gt;DeviceNetworkInformation&lt;/span&gt;.IsNetworkAvailable,&#xD;
            &lt;span style="color: #2b91af"&gt;DeviceNetworkInformation&lt;/span&gt;.IsWiFiEnabled);&#xD;
 &#xD;
    &lt;span style="color: #2b91af"&gt;NetworkInterfaceList &lt;/span&gt;list = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;NetworkInterfaceList&lt;/span&gt;(); &lt;span style="color: green"&gt;// 获得所有NetworkInterfaces&#xD;
&#xD;
    &lt;/span&gt;&lt;span style="color: blue"&gt;foreach &lt;/span&gt;(&lt;span style="color: blue"&gt;var &lt;/span&gt;item &lt;span style="color: blue"&gt;in &lt;/span&gt;list)&#xD;
    {&#xD;
        &lt;span style="color: blue"&gt;string &lt;/span&gt;text = &lt;span style="color: blue"&gt;string&lt;/span&gt;.Format(&#xD;
            &lt;span style="color: #a31515"&gt;@"&#xD;
            Bandwidth       {0}&#xD;
            InterfaceName   {1}&#xD;
            InterfaceState  {2}&#xD;
            InterfaceType   {3}&#xD;
            "&lt;/span&gt;,&#xD;
            item.Bandwidth, &lt;span style="color: green"&gt;// 单位是Kbps（千比特每秒）&#xD;
            &lt;/span&gt;item.InterfaceName, &lt;span style="color: green"&gt;// 网络连接的名字&#xD;
            &lt;/span&gt;item.InterfaceState, &lt;span style="color: green"&gt;// 枚举 Connected/Disconnected&#xD;
            &lt;/span&gt;item.InterfaceType); &lt;span style="color: green"&gt;// 网络类型的枚举&#xD;
        &#xD;
        &lt;/span&gt;content += text;&#xD;
    }&#xD;
&#xD;
    textBlock_NetworkInfo.Text = content;&#xD;
}&#xD;
&lt;/pre&gt;&lt;/p&gt;&#xD;
&lt;p&gt;经过我的测试，应用被切换到后台时网络环境发生了变化，在切换回前台运行后，也一样能立即侦测到这个事件。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;在Microsoft.Phone.Net.NetworkInformation.NetworkInterface命名空间下的&lt;a href="http://msdn.microsoft.com/en-us/library/microsoft.phone.net.networkinformation.networkinterface.networkinterfacetype(v=VS.92).aspx"&gt;NetworkInterfaceType&lt;/a&gt;枚举，比较典型的值有：&lt;/p&gt;&#xD;
&lt;ul&gt;&#xD;
&lt;li&gt;Wireless80211&amp;nbsp; -- WiFi&lt;/li&gt;&#xD;
&lt;li&gt;Ethernet&amp;nbsp;&amp;nbsp; -- USB&lt;/li&gt;&#xD;
&lt;li&gt;MobileBroadbandGSM&lt;/li&gt;&#xD;
&lt;li&gt;MobileBroadbandCDMA&lt;/li&gt;&#xD;
&lt;li&gt;None&lt;/li&gt;&lt;/ul&gt;&lt;img src="http://www.cnblogs.com/dc10101/aggbug/2310622.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/dc10101/archive/2012/01/03/2310622.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/dc10101/archive/2011/12/19/2293057.html</id><title type="text">Blend制作动画</title><summary type="text">在Blend中，有两种WorkSpace：Design和Animation。 Design是默认的，也是最常用的。 设计动画时最好切换到Animation。切换的快捷键是F6。 点+号创建一个StoryBoard，起一个名字，确定后，XAML中该StoryBoard会作为该页面的资源。 点击这个像一个椭圆小蛋右下角一个加号的按钮（record keyframe button），会在当前的时间...</summary><published>2011-12-19T03:19:00Z</published><updated>2011-12-19T03:19:00Z</updated><author><name>董超</name><uri>http://www.cnblogs.com/dc10101/</uri></author><link rel="alternate" href="http://www.cnblogs.com/dc10101/archive/2011/12/19/2293057.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/dc10101/archive/2011/12/19/2293057.html"/><content type="html">&lt;p&gt;在Blend中，有两种WorkSpace：Design和Animation。&lt;/p&gt; &lt;p&gt;Design是默认的，也是最常用的。&lt;/p&gt; &lt;p&gt;设计动画时最好切换到Animation。切换的快捷键是F6。&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;点+号创建一个StoryBoard，起一个名字，确定后，XAML中该StoryBoard会作为该页面的资源。&lt;/p&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/dc10101/201112/201112191118582517.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/dc10101/201112/20111219111858914.png" width="253" height="129"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;点击这个像一个椭圆小蛋右下角一个加号的按钮（record keyframe button），会在当前的时间点添加一个keyframe。第一个keyframe不必一定在0秒，可以拖动黄线上面的倒三角来移动黄线，也可以直接输入来修改时间。下面红色标出来的100%，可以直接输入修改，可以调节时间轴的精度。&lt;/p&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/dc10101/201112/201112191118596487.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/dc10101/201112/201112191118599552.png" width="142" height="213"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;开始录制后，ArtBoard的边框变成红色。右上角有个圆钮，可以toggle录制状态。&lt;/p&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/dc10101/201112/201112191118592616.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/dc10101/201112/201112191118598505.png" width="248" height="31"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;这时候你可以将控件拖拖拽拽、改个颜色之类的，修改后的状态表示在当前时间点（黄线标注处）的状态。关键帧动画就是从一个关键帧过渡到另一个关键帧，在一个storyboard里可以在不同时间点上设置不同的关键帧。&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;当创建好一个storyboard后如何选中它呢，方法是单击下图中红框的位置。&lt;/p&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/dc10101/201112/201112191119007699.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/dc10101/201112/201112191119001635.png" width="307" height="149"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;选中后的storyboard可以在属性面板上进行设置：&lt;/p&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/dc10101/201112/201112191119002748.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/dc10101/201112/20111219111901273.png" width="283" height="161"&gt;&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;AutoReverse表示自动返回到原状态。&lt;/p&gt; &lt;p&gt;RepeatBehavior用于设置重复多长时间，这个下拉框里可以输入多种格式：&lt;/p&gt; &lt;p&gt;Nx 表示重复N遍，这个N可以随意写，也可以永远重复下去。&lt;/p&gt; &lt;p&gt;还可以写成 days.hours:minutes:seconds.fractionalSeconds 的格式，其中days和fractionalSeconds是可选的。&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;上面这些工作完成后，在代码中加入启动动画的操作：&lt;/p&gt;&lt;pre &gt;&lt;span style="color: #2b91af"&gt;Storyboard &lt;/span&gt;storyboard = (&lt;span style="color: #2b91af"&gt;Storyboard&lt;/span&gt;)&lt;span style="color: blue"&gt;this&lt;/span&gt;.Resources[&lt;span style="color: #a31515"&gt;"AnimateCircle"&lt;/span&gt;];&#xD;
storyboard.Begin();&#xD;
&lt;/pre&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;在keyframe动画里，任何变化都可以是变速的。选中一个keyframe之后，会在属性面板看到下面的Easing界面。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/dc10101/201112/201112191119014766.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/dc10101/201112/201112191119016751.png" width="285" height="358"&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;Easing是缓和、缓冲的意思，不是easy，但这里理解成easy倒也歪打正着，因为它的确让你的工作变得更容易，在EasingFunction里内置了很多已有的效果。&lt;/p&gt;&#xD;
&lt;p&gt;KeySpline的平滑曲线可以这样理解：X表示时间，Y表示位置（总变化过程中的百分比），上图如果用于一个transform动画，就是对象“慢-快-慢”的一个移动效果。&lt;/p&gt;&#xD;
&lt;p&gt;Hold In是取消掉该关键帧之前所有的easing效果，造成一种间断的跳跃式的效果，例如对象瞬间移动，颜色突然变化，没有过渡。&lt;/p&gt;&#xD;
&lt;p&gt;拿变色动画举例：&lt;/p&gt;&#xD;
&lt;p&gt;如果是用KeySpline，在XAML里关键帧就叫SplineColorKeyFrame。&lt;/p&gt;&#xD;
&lt;p&gt;如果是用Easing Function，在XAML里关键帧就叫EasingColorKeyFrame。&lt;/p&gt;&#xD;
&lt;p&gt;如果是用Hold In，在XAML里关键帧就叫DiscreteColorKeyFrame。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/dc10101/201112/201112191119013196.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/dc10101/201112/201112191119022357.png" width="518" height="185"&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;最后要注意的是，在Object And Timeline的object面板中，一个storyboard是可以树状展开的。展开后每个keyframe都对应timeline上的一个小蛋，这些小蛋可以沿时间轴拖动。&lt;/p&gt;&#xD;
&lt;p&gt;注意object面板上没有垂直滚动条，在timeline面板的右侧。&lt;/p&gt;&#xD;
&lt;p&gt;object面板每个对象右侧有眼睛按钮，用来toggle该对象在设计时是否可见，锁按钮用来toggle在设计时是否可改动。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/dc10101/aggbug/2293057.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/dc10101/archive/2011/12/19/2293057.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/dc10101/archive/2011/12/16/2289605.html</id><title type="text">用OpacityMask快速制作theme friendly UI</title><summary type="text">首先，要好好解释一下OpacityMask，先来回答几个问题： OpacityMask能做什么呢？ 它只能把它所属的控件变得更加透明。 透过来的是什么呢？ 透明嘛，当然是挡在所属控件后面的东西了。 它是通过减小所属控件的Opacity属性做到的吗？ 不是。控件最终的透明度是由OpacityMask和Opacity共同决定的，它们各司其职。 为什么是Mask？ 是为了让所属控件更加灵活更有目的性地...</summary><published>2011-12-15T16:21:00Z</published><updated>2011-12-15T16:21:00Z</updated><author><name>董超</name><uri>http://www.cnblogs.com/dc10101/</uri></author><link rel="alternate" href="http://www.cnblogs.com/dc10101/archive/2011/12/16/2289605.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/dc10101/archive/2011/12/16/2289605.html"/><content type="html">&lt;p&gt;首先，要好好解释一下OpacityMask，先来回答几个问题：&lt;/p&gt; &lt;ol&gt; &lt;li&gt;OpacityMask能做什么呢？ 它只能把它所属的控件变得更加透明。&lt;/li&gt; &lt;li&gt;透过来的是什么呢？ 透明嘛，当然是挡在所属控件后面的东西了。&lt;/li&gt; &lt;li&gt;它是通过减小所属控件的Opacity属性做到的吗？ 不是。控件最终的透明度是由OpacityMask和Opacity共同决定的，它们各司其职。&lt;/li&gt; &lt;li&gt;为什么是Mask？ 是为了让所属控件更加灵活更有目的性地变透明，而非改变控件的整体透明效果。整体透明不如直接改控件的Opacity属性。&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;总结一下OpacityMask的特性：&lt;/p&gt; &lt;ol&gt; &lt;li&gt;它的brush（无论是何种类型的brush）完全忽略RGB颜色，只看A（也就是Alpha）的值。也就是说它只能改变透明度，无法改变颜色。&lt;/li&gt; &lt;li&gt;OpacityMask的brush的Alpha值越小，则所属控件越透明，这与我们通常理解的Alpha值的含义一致。&lt;/li&gt; &lt;li&gt;它的Alpha值不会覆盖控件本身的透明度，而是叠加上。例如控件本身的opacity=50%，如果OpacityMask的Alpha是40%，那么最终的opacity就是50%*40%=20%的透明度；如果OpacityMask的Alpha是100%（FF），那么最终的opacity就是50%*100%=50%的透明度（也就是说控件丝毫不受它的影响）；如果OpacityMask的Alpha是0%（00），那么最终的opacity就是50%*0%=0%的透明度(也就是说控件本身被完全透明化，看不到了)。&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;&lt;strong&gt;&lt;font size="5"&gt;实际用处&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;windows phone开发要注意兼容dark theme和light theme，难道非要给两种主题配不同的图片资源不可？其实可以用OpacityMask巧妙地解决。&lt;/p&gt; &lt;p&gt;在网上找到的icon，颜色经常与我们想要的不一样，就算是单色的图形，你给它用另外一种单色填充往往会产生锯齿，因为填充的时候，边缘的一些透明机器处理不好。比如我有一个白色的图案（该图案的背景是透明的）想用于一个按钮，但想把它变成红色，该如何做呢？&lt;/p&gt; &lt;p&gt;只要把按钮的背景色改成红色。&lt;/p&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/dc10101/201112/201112160020534388.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/dc10101/201112/201112160020538881.png" width="58" height="61"&gt;&lt;/a&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/dc10101/201112/201112160020531389.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 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/dc10101/201112/201112160020539993.png" width="58" height="63"&gt;&lt;/a&gt;&lt;/p&gt;&lt;pre &gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Button &lt;/span&gt;&lt;span style="color: red"&gt;Background&lt;/span&gt;&lt;span style="color: blue"&gt;="Red"&amp;gt;&#xD;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Button.OpacityMask&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&#xD;
        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;ImageBrush &lt;/span&gt;&lt;span style="color: red"&gt;Stretch&lt;/span&gt;&lt;span style="color: blue"&gt;="None" &lt;/span&gt;&lt;span style="color: red"&gt;ImageSource&lt;/span&gt;&lt;span style="color: blue"&gt;="icons/appbar.delete.rest.png"/&amp;gt;&#xD;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Button.OpacityMask&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&#xD;
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Button&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre &gt;这样任意变颜色也不会产生锯齿了。&lt;/pre&gt;&lt;pre &gt;&lt;/pre&gt;&lt;pre &gt;那怎样设置dark和light主题下都适当的颜色呢？&lt;/pre&gt;&lt;pre &gt;在两种主题下，背景色是不一样的，同名的资源也不尽相同，例如PhoneContrastBackgroundBrush，在不同主题下有着不同的颜色。&lt;/pre&gt;&lt;pre &gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/dc10101/201112/201112160020548914.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 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/dc10101/201112/201112160020549470.png" width="52" height="63"&gt;&lt;/a&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/dc10101/201112/201112160020548390.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 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/dc10101/201112/201112160020545359.png" width="50" height="57"&gt;&lt;/a&gt;&lt;/pre&gt;&#xD;
&lt;p&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Button &lt;/span&gt;&lt;span style="color: red"&gt;Background&lt;/span&gt;&lt;span style="color: blue"&gt;="{&lt;/span&gt;&lt;span style="color: #a31515"&gt;StaticResource &lt;/span&gt;&lt;span style="color: red"&gt;PhoneContrastBackgroundBrush&lt;/span&gt;&lt;span style="color: blue"&gt;}"&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Button.OpacityMask&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;ImageBrush &lt;/span&gt;&lt;span style="color: red"&gt;Stretch&lt;/span&gt;&lt;span style="color: blue"&gt;="None" &lt;/span&gt;&lt;span style="color: red"&gt;ImageSource&lt;/span&gt;&lt;span style="color: blue"&gt;="icons/appbar.delete.rest.png"/&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Button.OpacityMask&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Button&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br&gt;&lt;/span&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/dc10101/aggbug/2289605.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/dc10101/archive/2011/12/16/2289605.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/dc10101/archive/2011/12/15/2288235.html</id><title type="text">用gradient brush和OpacityMask实现fade edge效果</title><summary type="text">看下面一个gradient brush效果： &amp;lt;Ellipse.Fill&amp;gt; &amp;lt;RadialGradientBrush GradientOrigin=&amp;quot;0.3,0.3&amp;quot;&amp;gt; &amp;lt;GradientStop Color=&amp;quot;White&amp;quot;/&amp;gt; &amp;lt;GradientStop Color=&amp;quot;Transparent&amp;quot; Offset=&amp;quot;1&amp;quot;/&amp;gt; &amp;lt;/RadialGradientBrush&amp;gt; &amp;lt;/Ellipse.Fil...</summary><published>2011-12-14T16:03:00Z</published><updated>2011-12-14T16:03:00Z</updated><author><name>董超</name><uri>http://www.cnblogs.com/dc10101/</uri></author><link rel="alternate" href="http://www.cnblogs.com/dc10101/archive/2011/12/15/2288235.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/dc10101/archive/2011/12/15/2288235.html"/><content type="html">&lt;p&gt;看下面一个gradient brush效果：&lt;/p&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/dc10101/201112/201112150002354933.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/dc10101/201112/201112150002366635.png" width="137" height="134"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;span style="color: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Ellipse.Fill&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;RadialGradientBrush &lt;/span&gt;&lt;span style="color: red"&gt;GradientOrigin&lt;/span&gt;&lt;span style="color: blue"&gt;="0.3,0.3"&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;GradientStop &lt;/span&gt;&lt;span style="color: red"&gt;Color&lt;/span&gt;&lt;span style="color: blue"&gt;="White"/&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;GradientStop &lt;/span&gt;&lt;span style="color: red"&gt;Color&lt;/span&gt;&lt;span style="color: blue"&gt;="Transparent" &lt;/span&gt;&lt;span style="color: red"&gt;Offset&lt;/span&gt;&lt;span style="color: blue"&gt;="1"/&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;RadialGradientBrush&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Ellipse.Fill&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br&gt;&lt;/p&gt;&lt;/span&gt;&lt;/span&gt;&lt;pre &gt;我们看到，transparent也可以作为stop的颜色，其实每个颜色都可以通过设置alpha值来设置透明度。&lt;/pre&gt;&lt;pre &gt;&lt;/pre&gt;&#xD;
&lt;p&gt;再介绍一下OpacityMask，在很多UI控件中都有这个属性，用来配合着brush做出透明等光影效果。在OpacityMaskbrush中的brush，只有alpha值有效果，RGB值无论是什么，都是被忽略的。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/dc10101/201112/201112150002364160.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/dc10101/201112/201112150002367540.png" width="231" height="23"&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/dc10101/201112/201112150002364749.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 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/dc10101/201112/201112150002384914.png" width="212" height="208"&gt;&lt;/a&gt;&lt;/p&gt;&lt;pre &gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Image.OpacityMask&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&#xD;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;RadialGradientBrush &lt;/span&gt;&lt;span style="color: red"&gt;GradientOrigin&lt;/span&gt;&lt;span style="color: blue"&gt;="0.3,0.3"&amp;gt;&#xD;
        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;GradientStop &lt;/span&gt;&lt;span style="color: red"&gt;Color&lt;/span&gt;&lt;span style="color: blue"&gt;="White" /&amp;gt;&#xD;
        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;GradientStop &lt;/span&gt;&lt;span style="color: red"&gt;Color&lt;/span&gt;&lt;span style="color: blue"&gt;="#99000000" &lt;/span&gt;&lt;span style="color: red"&gt;Offset&lt;/span&gt;&lt;span style="color: blue"&gt;="0.7" /&amp;gt;&#xD;
        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;GradientStop &lt;/span&gt;&lt;span style="color: red"&gt;Color&lt;/span&gt;&lt;span style="color: blue"&gt;="Transparent" &lt;/span&gt;&lt;span style="color: red"&gt;Offset&lt;/span&gt;&lt;span style="color: blue"&gt;="1.04" /&amp;gt;&#xD;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;RadialGradientBrush&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&#xD;
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Image.OpacityMask&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;注意，上面第一个GradientStop颜色是White，但其实只有前两位alpha值有意义，White的alpha值是FF，所以哪怕这里换成Red，Blue，Black，由于它们的alpha值都是FF，所以效果都是一样的。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;下面看一个LinearGradient的例子：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/dc10101/201112/201112150002386343.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/dc10101/201112/201112150002381359.png" width="117" height="132"&gt;&lt;/a&gt;&lt;/p&gt;&lt;pre &gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Button &lt;/span&gt;&lt;span style="color: red"&gt;Content&lt;/span&gt;&lt;span style="color: blue"&gt;="Button"&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&#xD;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Button.OpacityMask&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&#xD;
        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;LinearGradientBrush &lt;/span&gt;&lt;span style="color: red"&gt;EndPoint&lt;/span&gt;&lt;span style="color: blue"&gt;="0.5,1" &lt;/span&gt;&lt;span style="color: red"&gt;StartPoint&lt;/span&gt;&lt;span style="color: blue"&gt;="0.5,0"&amp;gt;&#xD;
            &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;GradientStop &lt;/span&gt;&lt;span style="color: red"&gt;Offset&lt;/span&gt;&lt;span style="color: blue"&gt;="0"/&amp;gt;&#xD;
            &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;GradientStop &lt;/span&gt;&lt;span style="color: red"&gt;Color&lt;/span&gt;&lt;span style="color: blue"&gt;="Black" &lt;/span&gt;&lt;span style="color: red"&gt;Offset&lt;/span&gt;&lt;span style="color: blue"&gt;="0.5"/&amp;gt;&#xD;
            &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;GradientStop &lt;/span&gt;&lt;span style="color: red"&gt;Offset&lt;/span&gt;&lt;span style="color: blue"&gt;="1"/&amp;gt;&#xD;
        &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;LinearGradientBrush&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&#xD;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Button.OpacityMask&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&#xD;
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Button&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&#xD;
&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Button &lt;/span&gt;&lt;span style="color: red"&gt;Content&lt;/span&gt;&lt;span style="color: blue"&gt;="Button"&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&#xD;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Button.OpacityMask&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&#xD;
        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;LinearGradientBrush &lt;/span&gt;&lt;span style="color: red"&gt;EndPoint&lt;/span&gt;&lt;span style="color: blue"&gt;="0,0.5" &lt;/span&gt;&lt;span style="color: red"&gt;StartPoint&lt;/span&gt;&lt;span style="color: blue"&gt;="1,0.5"&amp;gt;&#xD;
            &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;GradientStop &lt;/span&gt;&lt;span style="color: red"&gt;Offset&lt;/span&gt;&lt;span style="color: blue"&gt;="0"/&amp;gt;&#xD;
            &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;GradientStop &lt;/span&gt;&lt;span style="color: red"&gt;Color&lt;/span&gt;&lt;span style="color: blue"&gt;="Black" &lt;/span&gt;&lt;span style="color: red"&gt;Offset&lt;/span&gt;&lt;span style="color: blue"&gt;="0.5"/&amp;gt;&#xD;
            &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;GradientStop &lt;/span&gt;&lt;span style="color: red"&gt;Offset&lt;/span&gt;&lt;span style="color: blue"&gt;="1"/&amp;gt;&#xD;
        &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;LinearGradientBrush&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&#xD;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Button.OpacityMask&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&#xD;
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Button&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&#xD;
&lt;/span&gt;&lt;/pre&gt;&lt;pre &gt;再来一个两端渐变的例子：&lt;/pre&gt;&lt;pre &gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/dc10101/201112/20111215000239836.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/dc10101/201112/201112150002395046.png" width="284" height="498"&gt;&lt;/a&gt;&lt;/pre&gt;&#xD;
&#xD;
&lt;pre &gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Image.OpacityMask&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&#xD;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;LinearGradientBrush &lt;/span&gt;&lt;span style="color: red"&gt;EndPoint&lt;/span&gt;&lt;span style="color: blue"&gt;="0.5,1" &lt;/span&gt;&lt;span style="color: red"&gt;StartPoint&lt;/span&gt;&lt;span style="color: blue"&gt;="0.5,0"&amp;gt;&#xD;
        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;GradientStop &lt;/span&gt;&lt;span style="color: red"&gt;Offset&lt;/span&gt;&lt;span style="color: blue"&gt;="0"/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre &gt;&lt;span style="color: blue"&gt;        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;GradientStop &lt;/span&gt;&lt;span style="color: red"&gt;Color&lt;/span&gt;&lt;span style="color: blue"&gt;="#AA000000" &lt;/span&gt;&lt;span style="color: red"&gt;Offset&lt;/span&gt;&lt;span style="color: blue"&gt;="0.02"/&amp;gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&#xD;
        &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;GradientStop &lt;/span&gt;&lt;span style="color: red"&gt;Color&lt;/span&gt;&lt;span style="color: blue"&gt;="Black" &lt;/span&gt;&lt;span style="color: red"&gt;Offset&lt;/span&gt;&lt;span style="color: blue"&gt;="0.05"/&amp;gt;&#xD;
        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;GradientStop &lt;/span&gt;&lt;span style="color: red"&gt;Color&lt;/span&gt;&lt;span style="color: blue"&gt;="Black" &lt;/span&gt;&lt;span style="color: red"&gt;Offset&lt;/span&gt;&lt;span style="color: blue"&gt;="0.95"/&amp;gt;&#xD;
&lt;/span&gt;&lt;span style="color: blue"&gt;        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;GradientStop &lt;/span&gt;&lt;span style="color: red"&gt;Color&lt;/span&gt;&lt;span style="color: blue"&gt;="#AA000000" &lt;/span&gt;&lt;span style="color: red"&gt;Offset&lt;/span&gt;&lt;span style="color: blue"&gt;="0.98"/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre &gt;&lt;span style="color: blue"&gt;        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;GradientStop &lt;/span&gt;&lt;span style="color: red"&gt;Offset&lt;/span&gt;&lt;span style="color: blue"&gt;="1"/&amp;gt; &lt;/span&gt;&lt;span style="color: blue"&gt;&#xD;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;LinearGradientBrush&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&#xD;
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Image.OpacityMask&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;从上面的XAML代码可以看到，如果不给Color设置值，默认是Transparent。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/dc10101/aggbug/2288235.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/dc10101/archive/2011/12/15/2288235.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/dc10101/archive/2011/12/13/2286851.html</id><title type="text">blend 画图</title><summary type="text">选择 select(快捷键V)，用来选择图形整体，进行整体的transform（旋转、平移、缩放等）。 select direct(快捷键A)，用来选择图形，进行局部的调整。 笔刷 pencil(快捷键Y)，记录鼠标的每一个细微变动，生成的图形表达式比较复杂，不推荐使用。 pen(快捷键P)，是下面重点要学习的。 在学习钢笔前，先选中钢笔，在右边属性面板将Fill属性reset成no brush...</summary><published>2011-12-13T13:40:00Z</published><updated>2011-12-13T13:40:00Z</updated><author><name>董超</name><uri>http://www.cnblogs.com/dc10101/</uri></author><link rel="alternate" href="http://www.cnblogs.com/dc10101/archive/2011/12/13/2286851.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/dc10101/archive/2011/12/13/2286851.html"/><content type="html">&lt;p&gt;&lt;strong&gt;选择&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;select(快捷键V)，用来选择图形整体，进行整体的transform（旋转、平移、缩放等）。&lt;/p&gt; &lt;p&gt;select direct(快捷键A)，用来选择图形，进行局部的调整。&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;笔刷&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;pencil(快捷键Y)，记录鼠标的每一个细微变动，生成的图形表达式比较复杂，不推荐使用。&lt;/p&gt; &lt;p&gt;pen(快捷键P)，是下面重点要学习的。&lt;/p&gt; &lt;p&gt;在学习钢笔前，先选中钢笔，在右边属性面板将Fill属性reset成no brush，把stroke属性改成与背景不同的颜色，这样有利于理解钢笔的本质。&lt;/p&gt; &lt;p&gt;每点一下鼠标添加一条新线（hold住是曲线，直接松开是直线），直到按下回车不再添加。&lt;/p&gt; &lt;p&gt;钢笔有个start point的概念，即你画下的新点会与start point连成线。start point是蓝色的，是你最近画的那个点，之前的点是白色的。&lt;/p&gt; &lt;p&gt;点下鼠标后按下alt键，会看到鼠标变成了一个箭头，拖动已有的线调整弧线。&lt;/p&gt; &lt;p&gt;在已有线上加一个新点：鼠标悬停在线上，光标会变成一个钢笔头右边一个+号。&lt;/p&gt; &lt;p&gt;删除一个点：鼠标悬停在点上，光标会变成一个钢笔头右边一个-号。&lt;/p&gt; &lt;p&gt;将两条path合并成一条：选中两条path（用select，按下ctrl选中第二条，被选中的path会变粗），然后工具切换到钢笔，点其中一条path的点，鼠标移到要连接的另一条path的点上，这时光标会变成钢笔后面一个连接符号，点击即可。&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;在选择模式下调整画好的钢笔图形：&lt;/p&gt; &lt;p&gt;快捷键A选中后，&lt;/p&gt; &lt;p&gt;移动边和点：鼠标移动到一条边上，光标会变成箭头+弧线，按住拖动即移动这条边。鼠标移动到点上，光标变成箭头+点，按住拖动即移动这个点。&lt;/p&gt; &lt;p&gt;删除边和点：选中一个点或一条边，相应的点或边会加粗变蓝，然后按delete键。（如果增加点只能在钢笔模式下添加）&lt;/p&gt; &lt;p&gt;选择多条边和点：按住ctrl依次选多个，或者按住ctrl后拖动一个长方框选多个。&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;基本图形&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;rectangle, ellipse, line&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;常用技巧：&lt;/p&gt; &lt;p&gt;快捷键：rectangle(M)&amp;nbsp; ellipse(L)&amp;nbsp;&amp;nbsp; line(\) &lt;/p&gt; &lt;p&gt;按住Alt后再画，则你按下鼠标的那一点是图形的中心点，而非图形的左上角。&lt;/p&gt; &lt;p&gt;按下Shift后绘图会让图形变得整齐：&lt;/p&gt; &lt;p&gt;按住Shift后再画rectangle和ellipse，长和宽会一样，在画正方或正圆的时候非常有用。&lt;/p&gt; &lt;p&gt;按住Shift画line，角度会是15度的倍数。&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;其他简单图形&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;在Assets标签页的Shapes里面，有很多简单的图形，有了这些作图基本就够了。&lt;/p&gt; &lt;p&gt;其中的Star类型可通过右侧Appearance面板中的PointCount和InnerRadius属性定制多角形，非常方便。&lt;/p&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/dc10101/201112/201112132139444722.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 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/dc10101/201112/201112132139451757.png" width="244" height="171"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Appearance面板上的属性会根据当前选中的类型而变化，尝试新控件时有必要多留意一下Appearance面板。&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;组合/取消组合（Group/Ungroup）&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;按ctrl选中多个图形后，右键菜单中有个Group Into，可以选择Group进不同的layout，一般用Grid就成，而且Group Into Grid有个方便的快捷键（ctrl+G）。&lt;/p&gt; &lt;p&gt;在组合后的图形上，右键菜单里会有ungroup。&lt;/p&gt; &lt;p&gt;&lt;strong&gt;合成（Combine）&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;按ctrl选中多个图形后，右键菜单中有个Combine，例如可以取两个图形的并集、交集等，合成后原来的多个图形变成了一个Path，注意没有uncombine操作，即该过程不可逆。&lt;/p&gt; &lt;p&gt;&lt;strong&gt;将Shape变成Path&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;如果你的图形是基本图形，要在线段层级修改（用A选中拖拽端点）是不可以的，这时候要将图形变成Path，方法是在这个图形上右键菜单中选择Convert to path.&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;填充&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;渐变填充&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/dc10101/201112/201112132139485991.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/dc10101/201112/20111213213951715.png" width="585" height="283"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;如何增加stop？在stop bar上点击鼠标左键。&lt;/p&gt; &lt;p&gt;如何删除stop？鼠标向下拖拽stop使其脱离bar，就会自动消失。&lt;/p&gt; &lt;p&gt;如何设置stop颜色？可以在调色板中选一个颜色点，可以用eyedropper（位于调色板右下角），也可以直接输入ARGB值。&lt;/p&gt; &lt;p&gt;如何设置渐变类型是线型还是放射型？在stop bar左下方，有linear和radial两种，第三个按钮是倒置stop点的顺序。&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;如何设置渐变的方向（对于线型而言）或中心（对于放射型而言）&lt;a href="http://images.cnblogs.com/cnblogs_com/dc10101/201112/20111213213952465.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/dc10101/201112/20111213213952531.png" width="598" height="220"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/dc10101/201112/201112132139537566.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/dc10101/201112/201112132139546095.png" width="592" height="245"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;StartPoint/EndPoint和GradientOrigin的值是坐标点（X，Y）在单位1中的位置，一般来说取值范围在0到1之间，但也可以超过1的限制。&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Gradient Tool&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;在左侧工具栏里有一个强大的Gradient Tool，选择后，渐变色上会出现一个矢量箭头，拖动一下它就明白什么意思了，很直观。&lt;/p&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/dc10101/201201/201201311146001434.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/dc10101/201201/201201311146038633.png" width="205" height="116"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;拖动矢量箭头的头和尾，可以调节起始点以及方向。&lt;/p&gt; &lt;p&gt;拖动矢量箭头上的圆点，相当于调节stop。&lt;/p&gt; &lt;p&gt;拖动矢量箭头整体（光标变成鼠标+加号），可以进行偏移。&lt;/p&gt; &lt;p&gt;用以上方法制作一个渐变条纹填充，注意SpreadMethod选成Reflect。&lt;/p&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/dc10101/201201/201201311146091802.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/dc10101/201201/201201311146217517.png" width="849" height="481"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;对于radial型的Gradient Tool，除了矢量箭头之外，还有一个圆，可以操作放射的中心和半径等。&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;用外部图片填充&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;选择tile brush，修改ImageSource属性。&lt;/p&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/dc10101/201112/201112132139553096.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/dc10101/201112/201112132139551733.png" width="266" height="132"&gt;&lt;/a&gt;&lt;/p&gt;   &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;如何丧心病狂地画出彩虹渐变？&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;画彩虹渐变不难，设置赤橙黄绿青蓝紫这些stop，不就行了？No, No, it works but一点都不丧心病狂。&lt;/p&gt; &lt;p&gt;要达到丧心病狂之效果，我们要用到gradient eyedropper这件神器。&lt;/p&gt; &lt;p&gt;打开gradient tool后，点击eyedropper，然后如下图画一条竖线：&lt;/p&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/dc10101/201201/201201311829166328.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/dc10101/201201/201201311829165522.png" width="160" height="199"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;然后就是见证奇迹的时刻了：&lt;/p&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/dc10101/201201/201201311829172033.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/dc10101/201201/201201311829185720.png" width="629" height="375"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;eyedropper真是个好东西，怎么样，丧心病狂吧！&lt;/p&gt;&lt;img src="http://www.cnblogs.com/dc10101/aggbug/2286851.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/dc10101/archive/2011/12/13/2286851.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/dc10101/archive/2011/12/08/2280117.html</id><title type="text">ControlTemplate &amp;amp; DataTemplate</title><summary type="text">ControlTemplate和DataTemplate都是用于定制控件的外观，但两者有着很大的区别。 ControlTemplate服务于Control（有形的控件），而DataTemplate服务于Data（无形的数据）。 换句话说，ControlTemplate用于将已有的外观进行改造，DataTemplate是从无到有地构建外观。 ContentControl、ItemsControl类型 ContentControl，它的Content属性包含单个元素，例如Button ItemsControl，它的Items属性包含多个元素，例如Listbox ContentPresent...</summary><published>2011-12-07T16:31:00Z</published><updated>2011-12-07T16:31:00Z</updated><author><name>董超</name><uri>http://www.cnblogs.com/dc10101/</uri></author><link rel="alternate" href="http://www.cnblogs.com/dc10101/archive/2011/12/08/2280117.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/dc10101/archive/2011/12/08/2280117.html"/><content type="html">&lt;p&gt;ControlTemplate和DataTemplate都是用于定制控件的外观，但两者有着很大的区别。&lt;/p&gt; &lt;p&gt;ControlTemplate服务于Control（有形的控件），而DataTemplate服务于Data（无形的数据）。&lt;/p&gt; &lt;p&gt;换句话说，ControlTemplate用于将已有的外观进行改造，DataTemplate是从无到有地构建外观。&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;ContentControl、ItemsControl类型&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;ContentControl，它的Content属性包含单个元素，例如Button  &lt;/li&gt;&lt;li&gt;ItemsControl，它的Items属性包含多个元素，例如Listbox&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;ContentPresenter、ItemsPresenter类型&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;平常的使用中，可以认为这些Presenter是占位符，用于ControlTemplate的定义中，代表了控件原本的Content。&lt;/p&gt; &lt;p&gt;以ContentControl为例，它有一个ContentPresenter类型的属性，如果其值是一个UIElement，那就直接显示这个UIElement，但如果是某个无形的数据，就要让ContentPresenter的值是一个DataTemplate。&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;ControlTemplate类型&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;ControlTemplate的代表：&lt;/p&gt; &lt;ul&gt; &lt;li&gt;ContentControl类型的Template属性  &lt;/li&gt;&lt;li&gt;ItemsControl类型的Template属性&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;ControlTemplate类型中常见到{TemplateBinding 属性名}，一般表示与原有控件的属性绑定。&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;DataTemplate类型&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;DataTemplate的典型代表：&lt;/p&gt; &lt;ul&gt; &lt;li&gt;ContentControl类型的ContentTemplate属性  &lt;/li&gt;&lt;li&gt;ItemsControl类型的ItemTemplate属性&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;DataTemplate类型中常见到{Binding &amp;#8230;}，表示数据绑定。&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;以下不属于Template，但是经常会与Template一起出现，所以写在这里。&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;ItemsPanel类型&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;表示ItemsControl各个Item是如何布局的，常用的也就是StackPanel横过来竖过来这些。&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;ItemContainerStyle类型&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;定制ItemsControl中各个Item的Style。如果要定制ItemsControl总框架的Style，就直接用ItemsControl的Style属性。&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;我的体会&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;DataTemplate比ControlTemplate更常用。&lt;/p&gt; &lt;p&gt;了解一个控件的Template(ControlTemplate类型)，需要用blend查看控件的VisualTree，查起来改起来都比较麻烦。但有些情况下用ControlTemplate很有效率，例如把所有的TextBox都换成圆角的、给button改个形状加个图片。对于伤筋动骨的改造，需要ControlTemplate，而对于一般的描眉画眼（给现有的属性赋新值），只需要在Style的Setter里给要改变的属性赋值就可以了。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/dc10101/aggbug/2280117.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/dc10101/archive/2011/12/08/2280117.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/dc10101/archive/2011/12/01/2271224.html</id><title type="text">PhoneApplicationFrame以及设置Obscured/Unobscured的event handler</title><summary type="text">简单描述Sliverlight程序，就是在一个Frame里不停地换Page。在App.xaml.cs里，那个RootFrame(VisualRoot)就是PhoneApplicationFrame类型。 MSDN上关于PhoneApplicationFrame的解释已经做得简洁易读：http://msdn.microsoft.com/en-us/library/ff402536%28v=VS....</summary><published>2011-12-01T14:06:00Z</published><updated>2011-12-01T14:06:00Z</updated><author><name>董超</name><uri>http://www.cnblogs.com/dc10101/</uri></author><link rel="alternate" href="http://www.cnblogs.com/dc10101/archive/2011/12/01/2271224.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/dc10101/archive/2011/12/01/2271224.html"/><content type="html">&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/dc10101/201112/201112012206075322.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/dc10101/201112/20111201220613234.png" width="533" height="431"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;简单描述Sliverlight程序，就是在一个Frame里不停地换Page。在App.xaml.cs里，那个RootFrame(VisualRoot)就是PhoneApplicationFrame类型。&lt;/p&gt; &lt;p&gt;MSDN上关于PhoneApplicationFrame的解释已经做得简洁易读：&lt;a title="http://msdn.microsoft.com/en-us/library/ff402536%28v=VS.92%29.aspx" href="http://msdn.microsoft.com/en-us/library/ff402536%28v=VS.92%29.aspx"&gt;http://msdn.microsoft.com/en-us/library/ff402536%28v=VS.92%29.aspx&lt;/a&gt;&lt;/p&gt; &lt;p&gt;我就不再赘述了，只简单总结一下：&lt;/p&gt; &lt;p&gt;PhoneApplicationFrame掌管着：&lt;/p&gt; &lt;p&gt;页面上方的Status Bar和下方的Application Bar&lt;/p&gt; &lt;p&gt;监听事件：页面方向的切换(Portrait/Landscape)，Back按钮被按下，由来电等触发的Obscured/UnObscured等。其中大多事件都能由Page监听，在XAML里直接指定event handler就很方便，但是Obscured/UnObscured事件无法在Page中找到，这才需要在code behind里用到PhoneApplicationFrame，代码如下：&lt;/p&gt;&lt;pre &gt;&lt;span style="color: #2b91af"&gt;PhoneApplicationFrame &lt;/span&gt;frame = (&lt;span style="color: #2b91af"&gt;PhoneApplicationFrame&lt;/span&gt;)&lt;span style="color: #2b91af"&gt;Application&lt;/span&gt;.Current.RootVisual;&#xD;
frame.Obscured += &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;EventHandler&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;ObscuredEventArgs&lt;/span&gt;&amp;gt;(frame_Obscured);&#xD;
frame.Unobscured += &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;EventHandler&lt;/span&gt;(frame_Unobscured);&#xD;
&lt;/pre&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;当Obscured发生时，无法知道具体由什么中断的，只能知道是不是由锁屏中断的：&lt;/p&gt;&lt;pre &gt;&lt;span style="color: blue"&gt;void &lt;/span&gt;frame_Obscured(&lt;span style="color: blue"&gt;object &lt;/span&gt;sender, &lt;span style="color: #2b91af"&gt;ObscuredEventArgs &lt;/span&gt;e)&#xD;
{&#xD;
    &lt;span style="color: blue"&gt;if &lt;/span&gt;(e.IsLocked) &lt;span style="color: green"&gt;// 仅能判断是否是锁屏&#xD;
    &lt;/span&gt;{&#xD;
    }&#xD;
}&#xD;
&lt;strong&gt;&lt;/strong&gt;&lt;/pre&gt;&lt;pre &gt;&lt;strong&gt;Obscured事件触发的时机&lt;/strong&gt;&lt;/pre&gt;&#xD;
&lt;p&gt;例如当电话来的时候就会触发Obscured事件，如果你正在玩游戏之类的，便可以在obscured的hander中使游戏暂停。这时候还没触发Deactived事件，只有当用户按下接听按钮时，才会触发Deactived事件。如果是锁屏的话，Obscured事件也会先于Deactivated事件发生。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/dc10101/aggbug/2271224.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/dc10101/archive/2011/12/01/2271224.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/dc10101/archive/2011/12/01/2269913.html</id><title type="text">Windows Phone 7 短信表情</title><summary type="text">至于Metro UI，怎么说呢……不要让它看起来有歧义，否则总有大仙能曲解你的意思。 再来张图，不要让网络耽误了你的正事</summary><published>2011-11-30T16:30:00Z</published><updated>2011-11-30T16:30:00Z</updated><author><name>董超</name><uri>http://www.cnblogs.com/dc10101/</uri></author><link rel="alternate" href="http://www.cnblogs.com/dc10101/archive/2011/12/01/2269913.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/dc10101/archive/2011/12/01/2269913.html"/><content type="html">&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/dc10101/201112/201112010030078940.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/dc10101/201112/201112010030131312.png" width="604" height="811"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;至于Metro UI，怎么说呢……不要让它看起来有歧义，否则总有大仙能曲解你的意思。&lt;/p&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/dc10101/201112/201112010211063112.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/dc10101/201112/201112010211166483.png" width="454" height="468"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;再来张图，不要让网络耽误了你的正事&lt;img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none"  alt="Smile" src="http://images.cnblogs.com/cnblogs_com/dc10101/201112/201112010145058825.png"&gt;&lt;/p&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/dc10101/201112/201112010145129212.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/dc10101/201112/20111201014519404.png" width="466" height="724"&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/dc10101/aggbug/2269913.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/dc10101/archive/2011/12/01/2269913.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/dc10101/archive/2011/11/29/2266923.html</id><title type="text">WP7应用程序生命周期，以及各个event handler分别该做什么</title><summary type="text">在看这篇文章之前，首先应该对下面的图足够了解，并且动手写过WP7程序。 如果有时间，这篇文章值得一看：http://blog.csdn.net/cc_net/article/details/6665737 上图中要注意，在Launch和Close的时候，并不会触发Activated和Deactived事件。 下文中的State泛指Application的State字典和Page的State...</summary><published>2011-11-28T16:16:00Z</published><updated>2011-11-28T16:16:00Z</updated><author><name>董超</name><uri>http://www.cnblogs.com/dc10101/</uri></author><link rel="alternate" href="http://www.cnblogs.com/dc10101/archive/2011/11/29/2266923.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/dc10101/archive/2011/11/29/2266923.html"/><content type="html">&lt;p&gt;在看这篇文章之前，首先应该对下面的图足够了解，并且动手写过WP7程序。&lt;/p&gt; &lt;p&gt;如果有时间，这篇文章值得一看：&lt;a title="http://blog.csdn.net/cc_net/article/details/6665737" href="http://blog.csdn.net/cc_net/article/details/6665737"&gt;http://blog.csdn.net/cc_net/article/details/6665737&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/dc10101/201111/201111282149384163.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 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/dc10101/201111/20111128214944471.png" width="532" height="676"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;上图中要注意，在Launch和Close的时候，并不会触发Activated和Deactived事件。&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;下文中的State泛指Application的State字典和Page的State字典。&lt;/p&gt; &lt;p&gt;本文主要针对的是，程序在进入到生命周期中的某一环节时，如何判断是否需要保存数据。&lt;/p&gt; &lt;p&gt;Mango中引入了Dormant状态，它与tombstoned的区别在于：&lt;/p&gt; &lt;p&gt;Dormant的程序，内存中的所有数据是完好的，activated后无须重新载入，而tombstoned除了在State里保留的数据，其余内存空间全部释放。&lt;/p&gt; &lt;p&gt;所以最容易出问题的地方就是：当内存被释放后，程序从tombstoned状态恢复到运行状态，很多之前创建的对象都是null了，这时候要重新创建这些对象。&lt;/p&gt; &lt;p&gt;至于程序获得的其他系统资源，无论是从dormant还是从tombstoned恢复运行，都需要重新获得这些资源。&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;下图详解了running和dormant状态间切换时发生的事。&lt;/p&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/dc10101/201111/201111290015131122.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/dc10101/201111/201111290015255930.png" width="965" height="614"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/dc10101/201111/201111290015329664.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 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/dc10101/201111/201111290015379102.png" width="961" height="617"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;下面根据MSDN上的建议以及我自己的理解，说一说每个事件处理方法中分别应该做些什么。&lt;/p&gt; &lt;p&gt;注意，需要保存的数据，应该在程序运行时恰当的时机立即保存，而不要等到离开页面或程序的时候才想到保存。如果在离开页面时没有需要保存的东西，那样最好。每个事件处理方法的执行时间都被限制在10秒，如果超过10秒程序会被强制关掉，所以应该尽量减少这些事件处理函数中的工作。&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;font size="4"&gt;Application_Launching&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;&lt;pre &gt;MSDN上对Launching事件的解释：&lt;/pre&gt;&lt;pre &gt;The &lt;a href="http://msdn.microsoft.com/en-us/library/microsoft.phone.shell.phoneapplicationservice.launching%28v=VS.92%29.aspx"&gt;Launching&lt;/a&gt; event is raised when a new application instance is launched by the user from the installed applications list or from a Tile on Start in addition to other means, such as tapping on a toast notification associated with an application or selecting an application from the Photos Extras menu. When an application is launched this way, it should appear to the user to be a new instance, not a continuation of a previous instance. To help ensure that your application loads quickly, you should execute as little code as possible in the handler for this event. In particular, avoid resource-intensive tasks like file and network operations. You should perform these tasks on a background thread after your application has loaded for the best user experience.&lt;/pre&gt;&lt;pre &gt;&lt;/pre&gt;&#xD;
&lt;p&gt;MSDN给的建议：Execute very little code. Do not do resource-intensive operations like accessing isolated storage.&lt;/p&gt;&#xD;
&lt;p&gt;所以还是不要在这个函数中有动作了。&lt;/p&gt;&lt;pre &gt;&lt;span style="color: green"&gt;// Code to execute when the application is launching (eg, from Start)&#xD;
// This code will not execute when the application is reactivated&#xD;
&lt;/span&gt;&lt;span style="color: blue"&gt;private void &lt;/span&gt;Application_Launching(&lt;span style="color: blue"&gt;object &lt;/span&gt;sender, &lt;span style="color: #2b91af"&gt;LaunchingEventArgs &lt;/span&gt;e)&#xD;
{&#xD;
}&lt;/pre&gt;&#xD;
&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;&lt;font size="4"&gt;Application_Activated&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;MSDN对Activated事件的解释：&lt;/p&gt;&#xD;
&lt;p&gt;The &lt;a href="http://msdn.microsoft.com/en-us/library/microsoft.phone.shell.phoneapplicationservice.activated%28v=VS.92%29.aspx"&gt;Activated&lt;/a&gt; event is called when the user returns to a dormant or tombstoned application. Applications should check the &lt;a href="http://msdn.microsoft.com/en-us/library/microsoft.phone.shell.activatedeventargs.isapplicationinstancepreserved%28v=VS.92%29.aspx"&gt;IsApplicationInstancePreserved&lt;/a&gt; property of the event args to determine whether the application is returning from being dormant or tombstoned. If IsApplicationInstancePreserved is true, then the application was dormant and state was automatically preserved by the operating system. If it is false, then the application was tombstoned and the application should use the state dictionary to restore application state. Applications should not perform resource-intensive tasks such as loading from isolated storage or a network resource during the Activated event handler because it increase the time it takes for the application to resume. Instead, these operations should be performed on a background thread after the application has loaded.&lt;/p&gt;&#xD;
&lt;p&gt;MSND的建议是：Check &lt;a href="http://msdn.microsoft.com/en-us/library/microsoft.phone.shell.activatedeventargs.isapplicationinstancepreserved%28v=VS.92%29.aspx"&gt;IsApplicationInstancePreserved&lt;/a&gt;. If true, do nothing. If false, use data in &lt;a href="http://msdn.microsoft.com/en-us/library/microsoft.phone.shell.phoneapplicationservice.state%28v=VS.92%29.aspx"&gt;State&lt;/a&gt; to restore application state.&lt;/p&gt;&#xD;
&lt;p&gt;虽然MSDN上不让这不让那，但我个人认为Application_Activated方法调用过后，要保证程序运行所需基本数据加载到位，非常大的数据可以等到页面加载后再异步获取。&lt;/p&gt;&#xD;
&lt;p&gt;需要注意：判断一下是从dormant还是从tombstoned状态恢复的，如果是从tombstoned恢复的，要根据需要从Application的state恢复数据。&lt;/p&gt;&#xD;
&lt;p&gt;还需要注意：由于从tombstoned状态恢复，是全新的一个实例，一切的对象甚至App这个对象都是要重新new的，内存重新分配，所以保存在State中的之前对象的引用（也就是指针）别指望仍然好用。也就是说，之前你有两个引用指向同一个对象，一个存放在state中，一个没有存放在state中，从tombstoned恢复过来以后，它们指向的就是两个不同的对象了。&lt;/p&gt;&lt;pre &gt;&lt;span style="color: green"&gt;// Code to execute when the application is activated (brought to foreground)&#xD;
// This code will not execute when the application is first launched&#xD;
&lt;/span&gt;&lt;span style="color: blue"&gt;private void &lt;/span&gt;Application_Activated(&lt;span style="color: blue"&gt;object &lt;/span&gt;sender, &lt;span style="color: #2b91af"&gt;ActivatedEventArgs &lt;/span&gt;e)&#xD;
{&#xD;
    &lt;span style="color: green"&gt;// 处理保存在State中的数据&#xD;
    &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(e.IsApplicationInstancePreserved == &lt;span style="color: blue"&gt;false&lt;/span&gt;)&#xD;
    {&#xD;
        &lt;span style="color: blue"&gt;if &lt;/span&gt;(&lt;span style="color: #2b91af"&gt;PhoneApplicationService&lt;/span&gt;.Current.State.ContainsKey(&lt;span style="color: #a31515"&gt;"ViewModel"&lt;/span&gt;))&#xD;
        {&#xD;
            viewModel = (&lt;span style="color: #2b91af"&gt;MainViewModel&lt;/span&gt;)&lt;span style="color: #2b91af"&gt;PhoneApplicationService&lt;/span&gt;.Current.State[&lt;span style="color: #a31515"&gt;"ViewModel"&lt;/span&gt;];&#xD;
        }&#xD;
    }&#xD;
&#xD;
    &lt;span style="color: green"&gt;// 处理保存在IsolatedStorage中的数据&#xD;
    // ...&#xD;
&lt;/span&gt;}&#xD;
&lt;/pre&gt;&#xD;
&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;&lt;font size="4"&gt;Application_Deactivated&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;MSDN对Deactivated事件的解释：&lt;/p&gt;&#xD;
&lt;p&gt;The &lt;a href="http://msdn.microsoft.com/en-us/library/microsoft.phone.shell.phoneapplicationservice.deactivated%28v=VS.92%29.aspx"&gt;Deactivated&lt;/a&gt; event is raised when the user navigates forward, away from your application, by pressing the Start button or by launching another application. The Deactivated event is also raised if your application launches a Chooser. For more information about Choosers, see &lt;a href="http://msdn.microsoft.com/en-us/library/ff769542%28v=VS.92%29.aspx"&gt;Launchers and Choosers Overview for Windows Phone&lt;/a&gt;. This event is also raised if the device’s lock screen is engaged, unless application idle detection is disabled. &#xD;
&lt;p&gt;In the handler for the Deactivated event, your application should save any application state so that it could be restored at a later time. Windows Phone applications are provided with the &lt;a href="http://msdn.microsoft.com/en-us/library/microsoft.phone.shell.phoneapplicationservice.state%28v=VS.92%29.aspx"&gt;State&lt;/a&gt; object, which is a dictionary you can use to store application state. If the application is tombstoned and then reactivated, this state dictionary will be populated with the data you saved in Deactivated. Because this data is present in memory, you can use it to restore state without resource-intensive file operations. &#xD;
&lt;p&gt;It is possible for an application to be completely terminated after Deactivated is called. When an application is terminated, its state dictionary is not preserved. For this reason, you should also store any unsaved state that should be persisted across application instances to isolated storage during the Deactivated event. &#xD;
&lt;p&gt;对应Deactivated事件handler中所做的事情，就是把该保存的都保存好，以便下次恢复的时候使用，当然也有可能永远不会恢复而是被close掉，所以在deactivated时保存的数据一定要涵盖所有close时应保存的数据。&lt;/p&gt;&lt;pre &gt;&lt;span style="color: green"&gt;// Code to execute when the application is deactivated (sent to background)&#xD;
// This code will not execute when the application is closing&#xD;
&lt;/span&gt;&lt;span style="color: blue"&gt;private void &lt;/span&gt;Application_Deactivated(&lt;span style="color: blue"&gt;object &lt;/span&gt;sender, &lt;span style="color: #2b91af"&gt;DeactivatedEventArgs &lt;/span&gt;e)&#xD;
{&#xD;
    &lt;span style="color: green"&gt;// 处理保存在State中的数据&#xD;
    &lt;/span&gt;&lt;span style="color: #2b91af"&gt;PhoneApplicationService&lt;/span&gt;.Current.State[&lt;span style="color: #a31515"&gt;"ViewModel"&lt;/span&gt;] = viewModel;&#xD;
&#xD;
    &lt;span style="color: green"&gt;// 处理保存在IsolatedStorage中的数据&#xD;
    // ...&#xD;
&lt;/span&gt;}&#xD;
&lt;/pre&gt;&#xD;
&lt;p&gt;&lt;p&gt;&lt;strong&gt;&lt;font size="4"&gt;Application_Closing&lt;/font&gt;&lt;/strong&gt; &#xD;
&lt;p&gt;MSDN对Closing事件的解释： &#xD;
&lt;p&gt;The &lt;a href="http://msdn.microsoft.com/en-us/library/microsoft.phone.shell.phoneapplicationservice.closing%28v=VS.92%29.aspx"&gt;Closing&lt;/a&gt; event is raised when the user navigates backwards past the first page of an application. In this case, the application is terminated and no state is saved. In the Closing event handler, your application can save data that should persist across instances. There is a limit of 10 seconds for applications to complete all application and page navigation events. If this limit is exceeded, the application is terminated. For this reason, it is a good idea to save persistent state throughout the lifetime of the application and avoid having to do large amounts of file I/O in the Closing event handler. &#xD;
&lt;p&gt;只有用户在应用程序首页按back时触发Closing事件，其他情况下则都不会触发这个事件。有些时候应用程序被终止也不会触发close事件，例如当超过了5个程序被打开（dormant和tombstoned都算是被打开）系统为节省资源会强制终止掉最早打开的程序，不触发Closing事件，再例如重新启动了该应用程序则会终止掉之前的程序而不触发closing，也就是说，Closing事件不见得一定会被触发。如果要保存数据的话，应当写一个方法，让closing和deactived的handler都调用这个方法。&lt;pre &gt;&lt;span style="color: green"&gt;// Code to execute when the application is closing (eg, user hit Back)&#xD;
// This code will not execute when the application is deactivated&#xD;
&lt;/span&gt;&lt;span style="color: blue"&gt;private void &lt;/span&gt;Application_Closing(&lt;span style="color: blue"&gt;object &lt;/span&gt;sender, &lt;span style="color: #2b91af"&gt;ClosingEventArgs &lt;/span&gt;e)&#xD;
{&#xD;
    &lt;span style="color: green"&gt;// 处理保存在IsolatedStorage中的数据&#xD;
    // ...&#xD;
&lt;/span&gt;}&#xD;
&lt;/pre&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;&lt;font size="4"&gt;OnNavigatedFrom&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;MSDN上解释得非常好：&lt;/p&gt;&#xD;
&lt;p&gt;Whenever this method is called, your application should store the page state so that it can be restored if the user returns to the page. The exception to this is backward navigation. The NavigationMode property can be used to determine if the navigation is a backward navigation, in which case there is no need to save state because the page will be re-created the next time it is visited. &#xD;
&lt;p&gt;In some cases, you may want to save state in the &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.page.onnavigatingfrom%28v=VS.92%29.aspx"&gt;OnNavigatingFrom(NavigatingCancelEventArgs)&lt;/a&gt; method as well. In particular, you will need to do this to store the state of a &lt;a href="http://go.microsoft.com/fwlink/?LinkID=225897"&gt;MediaElement&lt;/a&gt; control.&lt;pre &gt;&lt;span style="color: blue"&gt;protected override void &lt;/span&gt;OnNavigatedFrom(System.Windows.Navigation.&lt;span style="color: #2b91af"&gt;NavigationEventArgs &lt;/span&gt;e)&#xD;
{&#xD;
    &lt;span style="color: blue"&gt;base&lt;/span&gt;.OnNavigatedFrom(e);&#xD;
&#xD;
    &lt;span style="color: blue"&gt;if &lt;/span&gt;(e.NavigationMode != System.Windows.Navigation.&lt;span style="color: #2b91af"&gt;NavigationMode&lt;/span&gt;.Back)&#xD;
&lt;span style="color: blue"&gt;    &lt;/span&gt;{&#xD;
        &lt;span style="color: green"&gt;// 保存UI相关数据到本页面的State中&#xD;
        &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.State[&lt;span style="color: #a31515"&gt;"someText"&lt;/span&gt;] = textBox1.Text;&#xD;
    }&#xD;
}&#xD;
&lt;/pre&gt;&lt;pre &gt;可以在OnNavigatingFrom方法中取消这次导航，例如通过事件参数的属性，我们让可以取消的、并且是打开一个新的页面而不是Back到上个页面的、并且Uri中包含某个字符串的，并且阻止这次导航。&lt;/pre&gt;&lt;pre &gt;&lt;span style="color: blue"&gt;protected override void &lt;/span&gt;OnNavigatingFrom(System.Windows.Navigation.&lt;span style="color: #2b91af"&gt;NavigatingCancelEventArgs &lt;/span&gt;e)&#xD;
{&#xD;
    &lt;span style="color: blue"&gt;if &lt;/span&gt;(e.IsCancelable &#xD;
        &amp;amp;&amp;amp; e.NavigationMode == System.Windows.Navigation.&lt;span style="color: #2b91af"&gt;NavigationMode&lt;/span&gt;.New&#xD;
        &amp;amp;&amp;amp; e.Uri.ToString().Contains(&lt;span style="color: #a31515"&gt;"SomePage.xaml"&lt;/span&gt;))&#xD;
    {&#xD;
        e.Cancel = &lt;span style="color: blue"&gt;true&lt;/span&gt;;&#xD;
    }&#xD;
&#xD;
    &lt;span style="color: blue"&gt;base&lt;/span&gt;.OnNavigatingFrom(e);&#xD;
}&#xD;
如果要取消按Back键的行为，则一般不在OnNavigatingFrom方法中取消，而是在OnBackKeyPress方法中令e.Cancel = true。&lt;/pre&gt;&lt;pre &gt;&lt;/pre&gt;&#xD;
&lt;p&gt;&lt;strong&gt;&lt;font size="4"&gt;OnNavigatedTo&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;MSDN上的解释：&lt;/p&gt;&#xD;
&lt;p&gt;The &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.page.onnavigatedto%28v=VS.92%29.aspx"&gt;OnNavigatedTo(NavigationEventArgs)&lt;/a&gt; method is called when the user navigates to a page. This includes when the application is first launched, when the user navigates between the pages of the application, and when the application is relaunched after being made dormant or tombstoned. In this method, applications should check to see whether the page is a new instance. If it is not, state does not need to be restored. If the page is a new instance, and there is data in the state dictionary for the page, then the data should be used to restore the state of the page’s UI.&lt;/p&gt;&#xD;
&lt;p&gt;在OnNavigatedTo方法中，MSDN的建议是：&lt;/p&gt;&#xD;
&lt;p&gt;Check whether the page is a new instance. If not, the state is automatically intact. Otherwise, if there is data in &lt;a href="http://msdn.microsoft.com/en-us/library/microsoft.phone.controls.phoneapplicationpage.state%28v=VS.92%29.aspx"&gt;State&lt;/a&gt;, use it to restore UI. &#xD;
&lt;p&gt;&lt;font color="#ff0000"&gt;但我觉得MSDN上说得有问题！如果是我理解错了，多谢指正。&lt;/font&gt; &#xD;
&lt;p&gt;按照我的理解，OnNavigatedTo方法应该是以下逻辑：&lt;/p&gt;&#xD;
&lt;p&gt;if 是程序内的GoBack操作或者是从dormant状态恢复，都无需读取State，因为这两种情况内存都是完好的。&lt;/p&gt;&#xD;
&lt;p&gt;else if 是从tombstoned状态恢复，则需要读取State，因为这个page是新建的实例了，对象需要初始化。&lt;/p&gt;&#xD;
&lt;p&gt;但这里有个问题，通过什么来判断是从dormant状态恢复还是从dormant状态恢复的，两者的e.NavigationMode都是Back。解决方法是：给页面类加一个isNewPageInstance成员变量，默认置为true表明是新建的实例，在OnNavigateTo里置为false表示已经不是新实例了。&lt;/p&gt;&#xD;
&lt;p&gt;代码如下：&lt;/p&gt;&lt;pre &gt;&lt;span style="color: blue"&gt;bool &lt;/span&gt;isNewPageInstance = &lt;span style="color: blue"&gt;true&lt;/span&gt;;&#xD;
&#xD;
&lt;span style="color: blue"&gt;protected override void &lt;/span&gt;OnNavigatedTo(System.Windows.Navigation.&lt;span style="color: #2b91af"&gt;NavigationEventArgs &lt;/span&gt;e)&#xD;
{&#xD;
    &lt;span style="color: blue"&gt;base&lt;/span&gt;.OnNavigatedTo(e);&#xD;
&#xD;
    &lt;span style="color: blue"&gt;if &lt;/span&gt;(isNewPageInstance &amp;amp;&amp;amp; e.NavigationMode != System.Windows.Navigation.&lt;span style="color: #2b91af"&gt;NavigationMode&lt;/span&gt;.New)&#xD;
    {&#xD;
        &lt;span style="color: green"&gt;// 既不是新实例，又不是打开一个新页面的navigation操作，只能是从tombstoned状态恢复的了&#xD;
         &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(&lt;span style="color: blue"&gt;this&lt;/span&gt;.State.ContainsKey(&lt;span style="color: #a31515"&gt;"text"&lt;/span&gt;))&#xD;
        {&#xD;
            textBox1.Text = (&lt;span style="color: blue"&gt;string&lt;/span&gt;)&lt;span style="color: blue"&gt;this&lt;/span&gt;.State[&lt;span style="color: #a31515"&gt;"text"&lt;/span&gt;];&#xD;
        }&#xD;
    }&lt;/pre&gt;&lt;pre &gt;&lt;/pre&gt;&lt;pre &gt;isNewPageInstance = &lt;span style="color: blue"&gt;false;&lt;/span&gt;&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
&lt;p&gt;&lt;font size="4"&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/font&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;font size="4"&gt;&lt;strong&gt;关于Task&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;&#xD;
&lt;p&gt;Launcher, Chooser这些Task也会使得当前应用被deactivated，之后如果从tombstoned状态恢复，要特别注意，因为如果这些Task是局部变量，那么恢复之后就不复存在了。因此要让Task是成员变量，并且在构造函数中或声明的时候初始化它，这样才能在正确的时机调用Completed事件handler。例如像下面这样：&lt;/p&gt;&lt;pre &gt;&lt;span style="color: #2b91af"&gt;PhoneNumberChooserTask &lt;/span&gt;phoneNumberChooserTask = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;PhoneNumberChooserTask&lt;/span&gt;();&#xD;
&#xD;
&lt;span style="color: blue"&gt;public &lt;/span&gt;MainPage()&#xD;
{&#xD;
    InitializeComponent();&#xD;
    phoneNumberChooserTask.Completed += &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;EventHandler&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;PhoneNumberResult&lt;/span&gt;&amp;gt;(phoneNumberChooserTask_Completed);&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;font size="4"&gt;&lt;strong&gt;一些先后顺序的总结&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;&#xD;
&lt;table style="color: #000000" border="0" cellspacing="0" cellpadding="2" width="517"&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td valign="top" width="71"&gt;&#xD;
&lt;p align="center"&gt;&lt;strong&gt;顺序&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&#xD;
&lt;td valign="top" width="195"&gt;&#xD;
&lt;p align="center"&gt;&lt;strong&gt;来到页面&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&#xD;
&lt;td valign="top" width="249"&gt;&#xD;
&lt;p align="center"&gt;&lt;strong&gt;离开页面&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td valign="top" width="71"&gt;1&lt;/td&gt;&#xD;
&lt;td valign="top" width="195"&gt;NavigatedTo事件触发&lt;/td&gt;&#xD;
&lt;td valign="top" width="249"&gt;&#xD;
&lt;p&gt;NavigatedFrom事件触发&lt;/td&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td valign="top" width="71"&gt;2&lt;/td&gt;&#xD;
&lt;td valign="top" width="195"&gt;&#xD;
&lt;p&gt;控件Loaded事件触发&lt;br&gt;（先子元素后父元素）&lt;/p&gt;&lt;/td&gt;&#xD;
&lt;td valign="top" width="249"&gt;&#xD;
&lt;p&gt;控件UnLoaded事件触发&lt;br&gt;（先父元素后子元素）&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&#xD;
&lt;p&gt;比较有意思的是，多层嵌套控件的load以及unload顺序和我原来想的不一样，是子控件先load，然后是父控件load。父控件先unload，然后是子控件load。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/dc10101/aggbug/2266923.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/dc10101/archive/2011/11/29/2266923.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/dc10101/archive/2011/11/22/2258641.html</id><title type="text">第一个WP7程序 开发总结</title><summary type="text">终于做完了一个完整的应用，code name叫Whisper，以后有机会发到marketplace上。 先不说这个应用是干什么的了，把开发过程中突破的技术问题总结一下。 难题1：Listbox控件自动回弹无法停留，看不到最底下的items 原因：这是因为把Listbox放在了StackPanel布局下，因为StackPanel是动态的，不知道自己占多大空间。而Listbox使用数据绑定时也不知道...</summary><published>2011-11-22T05:03:00Z</published><updated>2011-11-22T05:03:00Z</updated><author><name>董超</name><uri>http://www.cnblogs.com/dc10101/</uri></author><link rel="alternate" href="http://www.cnblogs.com/dc10101/archive/2011/11/22/2258641.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/dc10101/archive/2011/11/22/2258641.html"/><content type="html">&lt;p&gt;终于做完了一个完整的应用，code name叫Whisper，以后有机会发到marketplace上。&lt;/p&gt; &lt;p&gt;先不说这个应用是干什么的了，把开发过程中突破的技术问题总结一下。&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;难题1：Listbox控件自动回弹无法停留，看不到最底下的items&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;原因：这是因为把Listbox放在了StackPanel布局下，因为StackPanel是动态的，不知道自己占多大空间。而Listbox使用数据绑定时也不知道自己占多大空间。他俩都不知道，于是就导致了这个悲剧。&lt;/p&gt; &lt;p&gt;解决：把StackPanel换成Grid，让Grid的Height属性="*"&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;难题2：ContextMenu用了数据绑定后，ContextMenuItem中原本可以显示的图片无法显示&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;原因：和ApplicationBar里的按钮图片无法显示的原因一样，微软真是应该解决这个问题，至少把图片的默认BuildAction改成Content。&lt;/p&gt; &lt;p&gt;解决：把BuildAction改成Content就好了。&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;难题3：实现了INotifyPropertyChanged接口，但绑定目标的数据未更新&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;原因：调式发现PropertyChanged事件的值为null，因此不会走下面通知属性变化的流程。&lt;/p&gt; &lt;p&gt;解决：一开始是在页面构造函数里给DataContext赋值的，后来放到页面的Load事件处理函数中，问题解决。&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;难题4：TextBox中文字透明度渐变不能及时响应&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;原因：如果你改了TextBox的文字，会实时响应，但如果是Foreground.Opacity属性，则要等到再有TextBox控件获得焦点后才会响应。&lt;/p&gt; &lt;p&gt;解决：让TextBox控件获得焦点，透明度渐变就会开始。但是这样会使得SIP（Soft Input Panel）弹出来，即便你立刻再把Focus移到别的控件上，SIP也会闪一下，影响体验。&lt;/p&gt; &lt;p&gt;解决：让TextBox.IsReadOnly=true，就不会弹出SIP了。只要以下三行代码：&lt;/p&gt; &lt;p&gt;textBox1.IsReadOnly=true;&lt;/p&gt; &lt;p&gt;textBox1.Focus(); &lt;/p&gt; &lt;p&gt;textBox1.IsReadOnly=false; &lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;难题5：TextBox的滚动条失效&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;原因：这应该是微软的一个设计缺陷。&lt;/p&gt; &lt;p&gt;解决：那么在需要编辑长文本时怎么办呢。另一个缺陷也不得不提，就是RichTextBox的IsReadOnly不能设置为true，否则会在运行时解析XAML失败。或换用webbrower打开一个自制的内嵌input的页面，这种做法太费周折。&lt;/p&gt; &lt;p&gt;最终也没有完美解决。给TextBox外层套一个ScrollViewer，但滑动后会弹回到输入光标所在的位置，即还原到滑动之前的视图。网上说如果是TextBlock的话，给TextBlock外层套上一个Grid就行了。&amp;lt;ScrollViewer&amp;gt;&amp;lt;Grid&amp;gt;&amp;lt;TextBlock/&amp;gt;&amp;lt;/Grid&amp;gt;&amp;lt;/ScrollViewer&amp;gt;，但是TextBox试过不成功。哪位高人知道多谢指点。不过也由此可见，在移动应用上还是不要让用户输入太多文字。&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;难题6：在TextBox中输入英文没有单词自动提示&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;原因：没有设置InputScope属性。但奇怪的是中文是有词提示的。&lt;/p&gt; &lt;p&gt;解决：将InputScope属性设为Text。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/dc10101/aggbug/2258641.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/dc10101/archive/2011/11/22/2258641.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry></feed>
