随笔 - 85  文章 - 0 评论 - 21 trackbacks - 0

有些应用是跟网络环境敏感的,WiFi快且免费,3G走流量,GSM慢,所以我们需要知道如何判断当前的网络类型,以及当网络类型发生改变时如何得到通知。

MSDN相关文章:How To: Detect Network Changes

下面我简单介绍一下。

 

当网络发生变化时,会引发网络地址发生变化,要监测这一事件,需要用到位于System.Net.NetworkInformation命名空间下的NetworkChange类。

要查看网络连接的类型和状态,用到的类都在Microsoft.Phone.Net.NetworkInformation这个命名空间里。

 

注意上面两个不同的命名空间,Microsoft.Phone.Net.NetworkInformation是专门用于手机,System.Net.NetworkInformation用于各种场合。由于这两个类中的名字冲突很多,一起用的时候注意区分好。

 

网络环境变化时得到通知

只需要监听一个事件:

NetworkChange.NetworkAddressChanged += new NetworkAddressChangedEventHandler(NetworkChange_NetworkAddressChanged);

……


void NetworkChange_NetworkAddressChanged(object sender, EventArgs e)
{
    string content = string.Format(
            @"CellularMobileOperator        {0}
            IsCellularDataEnabled           {1}
            IsCellularDataRoamingEnabled    {2}
            IsNetworkAvailable              {3}
            IsWiFiEnabled                   {4}",
            DeviceNetworkInformation.CellularMobileOperator, // 运营商名字,例如“中国移动”
            DeviceNetworkInformation.IsCellularDataEnabled,
            DeviceNetworkInformation.IsCellularDataRoamingEnabled,
            DeviceNetworkInformation.IsNetworkAvailable,
            DeviceNetworkInformation.IsWiFiEnabled);
 
    NetworkInterfaceList list = new NetworkInterfaceList(); // 获得所有NetworkInterfaces

    foreach (var item in list)
    {
        string text = string.Format(
            @"
            Bandwidth       {0}
            InterfaceName   {1}
            InterfaceState  {2}
            InterfaceType   {3}
            ",
            item.Bandwidth, // 单位是Kbps(千比特每秒)
            item.InterfaceName, // 网络连接的名字
            item.InterfaceState, // 枚举 Connected/Disconnected
            item.InterfaceType); // 网络类型的枚举
        
        content += text;
    }

    textBlock_NetworkInfo.Text = content;
}

经过我的测试,应用被切换到后台时网络环境发生了变化,在切换回前台运行后,也一样能立即侦测到这个事件。

 

在Microsoft.Phone.Net.NetworkInformation.NetworkInterface命名空间下的NetworkInterfaceType枚举,比较典型的值有:

  • Wireless80211  -- WiFi
  • Ethernet   -- USB
  • MobileBroadbandGSM
  • MobileBroadbandCDMA
  • None
posted @ 2012-01-03 01:24 董超 阅读(75) 评论(0) 编辑

在Blend中,有两种WorkSpace:Design和Animation。

Design是默认的,也是最常用的。

设计动画时最好切换到Animation。切换的快捷键是F6。

 

点+号创建一个StoryBoard,起一个名字,确定后,XAML中该StoryBoard会作为该页面的资源。

image

 

点击这个像一个椭圆小蛋右下角一个加号的按钮(record keyframe button),会在当前的时间点添加一个keyframe。第一个keyframe不必一定在0秒,可以拖动黄线上面的倒三角来移动黄线,也可以直接输入来修改时间。下面红色标出来的100%,可以直接输入修改,可以调节时间轴的精度。

image

开始录制后,ArtBoard的边框变成红色。右上角有个圆钮,可以toggle录制状态。

image

 

这时候你可以将控件拖拖拽拽、改个颜色之类的,修改后的状态表示在当前时间点(黄线标注处)的状态。关键帧动画就是从一个关键帧过渡到另一个关键帧,在一个storyboard里可以在不同时间点上设置不同的关键帧。

 

当创建好一个storyboard后如何选中它呢,方法是单击下图中红框的位置。

image

 

选中后的storyboard可以在属性面板上进行设置:

image

AutoReverse表示自动返回到原状态。

RepeatBehavior用于设置重复多长时间,这个下拉框里可以输入多种格式:

Nx 表示重复N遍,这个N可以随意写,也可以永远重复下去。

还可以写成 days.hours:minutes:seconds.fractionalSeconds 的格式,其中days和fractionalSeconds是可选的。

 

上面这些工作完成后,在代码中加入启动动画的操作:

Storyboard storyboard = (Storyboard)this.Resources["AnimateCircle"];
storyboard.Begin();

 

在keyframe动画里,任何变化都可以是变速的。选中一个keyframe之后,会在属性面板看到下面的Easing界面。

image

Easing是缓和、缓冲的意思,不是easy,但这里理解成easy倒也歪打正着,因为它的确让你的工作变得更容易,在EasingFunction里内置了很多已有的效果。

KeySpline的平滑曲线可以这样理解:X表示时间,Y表示位置(总变化过程中的百分比),上图如果用于一个transform动画,就是对象“慢-快-慢”的一个移动效果。

Hold In是取消掉该关键帧之前所有的easing效果,造成一种间断的跳跃式的效果,例如对象瞬间移动,颜色突然变化,没有过渡。

拿变色动画举例:

如果是用KeySpline,在XAML里关键帧就叫SplineColorKeyFrame。

如果是用Easing Function,在XAML里关键帧就叫EasingColorKeyFrame。

如果是用Hold In,在XAML里关键帧就叫DiscreteColorKeyFrame。

 

 

image

最后要注意的是,在Object And Timeline的object面板中,一个storyboard是可以树状展开的。展开后每个keyframe都对应timeline上的一个小蛋,这些小蛋可以沿时间轴拖动。

注意object面板上没有垂直滚动条,在timeline面板的右侧。

object面板每个对象右侧有眼睛按钮,用来toggle该对象在设计时是否可见,锁按钮用来toggle在设计时是否可改动。

posted @ 2011-12-19 11:19 董超 阅读(20) 评论(0) 编辑

首先,要好好解释一下OpacityMask,先来回答几个问题:

  1. OpacityMask能做什么呢? 它只能把它所属的控件变得更加透明。
  2. 透过来的是什么呢? 透明嘛,当然是挡在所属控件后面的东西了。
  3. 它是通过减小所属控件的Opacity属性做到的吗? 不是。控件最终的透明度是由OpacityMask和Opacity共同决定的,它们各司其职。
  4. 为什么是Mask? 是为了让所属控件更加灵活更有目的性地变透明,而非改变控件的整体透明效果。整体透明不如直接改控件的Opacity属性。

总结一下OpacityMask的特性:

  1. 它的brush(无论是何种类型的brush)完全忽略RGB颜色,只看A(也就是Alpha)的值。也就是说它只能改变透明度,无法改变颜色。
  2. OpacityMask的brush的Alpha值越小,则所属控件越透明,这与我们通常理解的Alpha值的含义一致。
  3. 它的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%的透明度(也就是说控件本身被完全透明化,看不到了)。

实际用处

windows phone开发要注意兼容dark theme和light theme,难道非要给两种主题配不同的图片资源不可?其实可以用OpacityMask巧妙地解决。

在网上找到的icon,颜色经常与我们想要的不一样,就算是单色的图形,你给它用另外一种单色填充往往会产生锯齿,因为填充的时候,边缘的一些透明机器处理不好。比如我有一个白色的图案(该图案的背景是透明的)想用于一个按钮,但想把它变成红色,该如何做呢?

只要把按钮的背景色改成红色。

imageimage

<Button Background="Red">
    <Button.OpacityMask>
        <ImageBrush Stretch="None" ImageSource="icons/appbar.delete.rest.png"/>
    </Button.OpacityMask>
</Button>
这样任意变颜色也不会产生锯齿了。
 
那怎样设置dark和light主题下都适当的颜色呢?
在两种主题下,背景色是不一样的,同名的资源也不尽相同,例如PhoneContrastBackgroundBrush,在不同主题下有着不同的颜色。
imageimage

<Button Background="{StaticResource PhoneContrastBackgroundBrush}">
    <
Button.OpacityMask>
        <
ImageBrush Stretch="None" ImageSource="icons/appbar.delete.rest.png"/>
    </
Button.OpacityMask>
</
Button>

posted @ 2011-12-16 00:21 董超 阅读(62) 评论(0) 编辑

看下面一个gradient brush效果:

image

            <Ellipse.Fill>
                <
RadialGradientBrush GradientOrigin="0.3,0.3">
                    <
GradientStop Color="White"/>
                    <
GradientStop Color="Transparent" Offset="1"/>
                </
RadialGradientBrush>
            </
Ellipse.Fill>

我们看到,transparent也可以作为stop的颜色,其实每个颜色都可以通过设置alpha值来设置透明度。
 

再介绍一下OpacityMask,在很多UI控件中都有这个属性,用来配合着brush做出透明等光影效果。在OpacityMaskbrush中的brush,只有alpha值有效果,RGB值无论是什么,都是被忽略的。

image

image

<Image.OpacityMask>
    <RadialGradientBrush GradientOrigin="0.3,0.3">
        <GradientStop Color="White" />
        <GradientStop Color="#99000000" Offset="0.7" />
        <GradientStop Color="Transparent" Offset="1.04" />
    </RadialGradientBrush>
</Image.OpacityMask>

注意,上面第一个GradientStop颜色是White,但其实只有前两位alpha值有意义,White的alpha值是FF,所以哪怕这里换成Red,Blue,Black,由于它们的alpha值都是FF,所以效果都是一样的。

 

下面看一个LinearGradient的例子:

image

<Button Content="Button">
    <Button.OpacityMask>
        <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
            <GradientStop Offset="0"/>
            <GradientStop Color="Black" Offset="0.5"/>
            <GradientStop Offset="1"/>
        </LinearGradientBrush>
    </Button.OpacityMask>
</Button>
<Button Content="Button">
    <Button.OpacityMask>
        <LinearGradientBrush EndPoint="0,0.5" StartPoint="1,0.5">
            <GradientStop Offset="0"/>
            <GradientStop Color="Black" Offset="0.5"/>
            <GradientStop Offset="1"/>
        </LinearGradientBrush>
    </Button.OpacityMask>
</Button>
再来一个两端渐变的例子:
image
<Image.OpacityMask>
    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
        <GradientStop Offset="0"/>
        <GradientStop Color="#AA000000" Offset="0.02"/>
        <GradientStop Color="Black" Offset="0.05"/>
        <GradientStop Color="Black" Offset="0.95"/>
        <GradientStop Color="#AA000000" Offset="0.98"/>
        <GradientStop Offset="1"/> 
    </LinearGradientBrush>
</Image.OpacityMask>

从上面的XAML代码可以看到,如果不给Color设置值,默认是Transparent。

posted @ 2011-12-15 00:03 董超 阅读(31) 评论(0) 编辑

选择

select(快捷键V),用来选择图形整体,进行整体的transform(旋转、平移、缩放等)。

select direct(快捷键A),用来选择图形,进行局部的调整。

 

笔刷

pencil(快捷键Y),记录鼠标的每一个细微变动,生成的图形表达式比较复杂,不推荐使用。

pen(快捷键P),是下面重点要学习的。

在学习钢笔前,先选中钢笔,在右边属性面板将Fill属性reset成no brush,把stroke属性改成与背景不同的颜色,这样有利于理解钢笔的本质。

每点一下鼠标添加一条新线(hold住是曲线,直接松开是直线),直到按下回车不再添加。

钢笔有个start point的概念,即你画下的新点会与start point连成线。start point是蓝色的,是你最近画的那个点,之前的点是白色的。

点下鼠标后按下alt键,会看到鼠标变成了一个箭头,拖动已有的线调整弧线。

在已有线上加一个新点:鼠标悬停在线上,光标会变成一个钢笔头右边一个+号。

删除一个点:鼠标悬停在点上,光标会变成一个钢笔头右边一个-号。

将两条path合并成一条:选中两条path(用select,按下ctrl选中第二条,被选中的path会变粗),然后工具切换到钢笔,点其中一条path的点,鼠标移到要连接的另一条path的点上,这时光标会变成钢笔后面一个连接符号,点击即可。

 

在选择模式下调整画好的钢笔图形:

快捷键A选中后,

移动边和点:鼠标移动到一条边上,光标会变成箭头+弧线,按住拖动即移动这条边。鼠标移动到点上,光标变成箭头+点,按住拖动即移动这个点。

删除边和点:选中一个点或一条边,相应的点或边会加粗变蓝,然后按delete键。(如果增加点只能在钢笔模式下添加)

选择多条边和点:按住ctrl依次选多个,或者按住ctrl后拖动一个长方框选多个。

 

基本图形

rectangle, ellipse, line

常用技巧:

快捷键:rectangle(M)  ellipse(L)   line(\)

按住Alt后再画,则你按下鼠标的那一点是图形的中心点,而非图形的左上角。

按下Shift后绘图会让图形变得整齐:

按住Shift后再画rectangle和ellipse,长和宽会一样,在画正方或正圆的时候非常有用。

按住Shift画line,角度会是15度的倍数。

 

其他简单图形

在Assets标签页的Shapes里面,有很多简单的图形,有了这些作图基本就够了。

其中的Star类型可通过右侧Appearance面板中的PointCount和InnerRadius属性定制多角形,非常方便。

image

Appearance面板上的属性会根据当前选中的类型而变化,尝试新控件时有必要多留意一下Appearance面板。

 

组合/取消组合(Group/Ungroup)

按ctrl选中多个图形后,右键菜单中有个Group Into,可以选择Group进不同的layout,一般用Grid就成,而且Group Into Grid有个方便的快捷键(ctrl+G)。

在组合后的图形上,右键菜单里会有ungroup。

合成(Combine)

按ctrl选中多个图形后,右键菜单中有个Combine,例如可以取两个图形的并集、交集等,合成后原来的多个图形变成了一个Path,注意没有uncombine操作,即该过程不可逆。

将Shape变成Path

如果你的图形是基本图形,要在线段层级修改(用A选中拖拽端点)是不可以的,这时候要将图形变成Path,方法是在这个图形上右键菜单中选择Convert to path.

 

填充

渐变填充

image

如何增加stop?在stop bar上点击鼠标左键。

如何删除stop?鼠标向下拖拽stop使其脱离bar,就会自动消失。

如何设置stop颜色?可以在调色板中选一个颜色点,可以用eyedropper(位于调色板右下角),也可以直接输入ARGB值。

如何设置渐变类型是线型还是放射型?在stop bar左下方,有linear和radial两种,第三个按钮是倒置stop点的顺序。

 

如何设置渐变的方向(对于线型而言)或中心(对于放射型而言)image

image

StartPoint/EndPoint和GradientOrigin的值是坐标点(X,Y)在单位1中的位置,一般来说取值范围在0到1之间,但也可以超过1的限制。

Gradient Tool

在左侧工具栏里有一个强大的Gradient Tool,选择后,渐变色上会出现一个矢量箭头,拖动一下它就明白什么意思了,很直观。

image

拖动矢量箭头的头和尾,可以调节起始点以及方向。

拖动矢量箭头上的圆点,相当于调节stop。

拖动矢量箭头整体(光标变成鼠标+加号),可以进行偏移。

用以上方法制作一个渐变条纹填充,注意SpreadMethod选成Reflect。

image

 

对于radial型的Gradient Tool,除了矢量箭头之外,还有一个圆,可以操作放射的中心和半径等。

 

用外部图片填充

选择tile brush,修改ImageSource属性。

image

 

如何丧心病狂地画出彩虹渐变?

画彩虹渐变不难,设置赤橙黄绿青蓝紫这些stop,不就行了?No, No, it works but一点都不丧心病狂。

要达到丧心病狂之效果,我们要用到gradient eyedropper这件神器。

打开gradient tool后,点击eyedropper,然后如下图画一条竖线:

image

然后就是见证奇迹的时刻了:

image

eyedropper真是个好东西,怎么样,丧心病狂吧!

posted @ 2011-12-13 21:40 董超 阅读(45) 评论(0) 编辑
摘要: ControlTemplate和DataTemplate都是用于定制控件的外观,但两者有着很大的区别。 ControlTemplate服务于Control(有形的控件),而DataTemplate服务于Data(无形的数据)。 换句话说,ControlTemplate用于将已有的外观进行改造,DataTemplate是从无到有地构建外观。 ContentControl、ItemsControl类型 ContentControl,它的Content属性包含单个元素,例如Button ItemsControl,它的Items属性包含多个元素,例如Listbox ContentPresent...阅读全文
posted @ 2011-12-08 00:31 董超 阅读(44) 评论(0) 编辑
摘要: 简单描述Sliverlight程序,就是在一个Frame里不停地换Page。在App.xaml.cs里,那个RootFrame(VisualRoot)就是PhoneApplicationFrame类型。 MSDN上关于PhoneApplicationFrame的解释已经做得简洁易读:http://msdn.microsoft.com/en-us/library/ff402536%28v=VS....阅读全文
posted @ 2011-12-01 22:06 董超 阅读(38) 评论(0) 编辑
摘要: 至于Metro UI,怎么说呢……不要让它看起来有歧义,否则总有大仙能曲解你的意思。 再来张图,不要让网络耽误了你的正事阅读全文
posted @ 2011-12-01 00:30 董超 阅读(31) 评论(0) 编辑
摘要: 在看这篇文章之前,首先应该对下面的图足够了解,并且动手写过WP7程序。 如果有时间,这篇文章值得一看:http://blog.csdn.net/cc_net/article/details/6665737 上图中要注意,在Launch和Close的时候,并不会触发Activated和Deactived事件。 下文中的State泛指Application的State字典和Page的State...阅读全文
posted @ 2011-11-29 00:16 董超 阅读(58) 评论(0) 编辑
摘要: 终于做完了一个完整的应用,code name叫Whisper,以后有机会发到marketplace上。 先不说这个应用是干什么的了,把开发过程中突破的技术问题总结一下。 难题1:Listbox控件自动回弹无法停留,看不到最底下的items 原因:这是因为把Listbox放在了StackPanel布局下,因为StackPanel是动态的,不知道自己占多大空间。而Listbox使用数据绑定时也不知道...阅读全文
posted @ 2011-11-22 13:03 董超 阅读(108) 评论(1) 编辑