Windows Phone


Windows Phone 个人开发者一年回顾

今天是2015年1月25日,距我的第一个WP应用上架正好一年。这一年里,因为选择Windows Phone,开发Windows Phone,我收获了很多。我虽然工作是ASP.NET网站开发,WP只是业余的新手,但短短一年来,它带给我太多的美好。有技术上的成就,有许多新的朋友。 我想回顾一年来我和WP的点点滴滴。同时也向和我一样始终坚守在这个平台的个人开发者们致敬。 最早开始写WP应用其实是2013年7月,在我买了第一部WP手机以后,看着Channel  9上的视频边学边写。那时候安卓和苹果早就平分天下了,几乎没有WP什么事。当时我选择Windows Phone开发,仅仅是因为我在Windows平台上已经掌握的编程技能可以用于WP开发,不会耗费太大的学习成本,比如C#、Silverlight等技术。和我最早研究计算机一样,我并没有把赚钱当作目的和目标,而是纯粹的兴趣,所以至今我 …


Windows Phone Runtime 8.1如何设置最小化的工具栏

以前在Silverlight Runtime下,要设置一个最小化(缩紧)的工具栏,给ApplicationBar设置Mode属性为Minimized就行 <shell:ApplicationBar IsMenuEnabled="False" Mode="Minimized"> 到了Windows Phone 8.1运行时下,这个Mode属性木有了。就算你不加任何按钮或菜单,在XAML设计器里起来是最小化了,运行时还是会展开的。比如这段代码: <Page.BottomAppBar> <CommandBar Background="#0072BC" Foreground="White" /> </Page.BottomAppBar> 在XAML设计器里的效果: 运行时的效果: 草草草草草。。。 查了下 …


Windows Phone Runtime 8.1 按返回键彻底关闭App

Windows Phone Runtime 8.1里面的坑不止一点点,最明显的是很多应用以前可以通过按返回键关闭,但是在8.1之后,如果你用了WinRT的runtime写程序,就会发现返回键的行为仅仅是返回WP的主屏幕,而不是关闭App。长按返回键你会发现你的App是被“最小化”在后台了。WP8.1的新版日历应用也是这样。 虽然这对系统性能没有什么影响,但是让处女座用户看见了就会感觉不爽,所以我们还是把它改掉吧。 WinRT里面这个硬件返回按钮是有专门的事件的:HardwareButtons.BackPressed。我们需要处理的情况仅仅是在应用的主页面上,按手机返回按钮关闭App,所以不需要override全局的HardwareButtons.BackPressed事件。只需要在主页面(通常是MainPage.xaml.cs)里override两个导航事件 …


Windows Phone Runtime 8.1 如何显示系统状态栏(以前的SystemTray)

首先。。。虽然我文章写的2,但是国内愿意主动分享WP开发经验的博客太少了,大家都是粉,为了这个平台不容易,所以我有点什么都会拿出来分享,觉得文章菜的请不要喷。。。 开发WP8.1的小伙伴们如果选择了WinRT的runtime,可能会被坑:如果你的手机主题是黑色的,但是你的应用选择了白色主题,就像这样 RequestedTheme="Light" 那你会发现,虽然你在写UI配色方面偷懒了许多,但是WP的系统状态栏(显示信号、时间的地方),也就是Silverlight Runtime里称作SystemTray的,配色并不会因为你选择了“Light”而变成黑色这种对比色,它始终是跟着手机系统设置走的(黑色主题则为白色,白色主题则为黑色),于是你的应用就会出现一条白色的状态栏在手机顶端,用户再也不能愉快的看时间了。草草草草草。 当你想修这个问题的时候,你又会发现微软 …


Windows Phone 8.1 Silverlight运行时StorageFolder.GetFolderFromPathAsync爆掉的问题

微软说好的一键Target WP8.1的神话终究还是个坑。不少朋友发现有些API虽然编译通过,但依然是爆炸的。比如 await StorageFolder.GetFolderFromPathAsync(); 运行时会就直接爆炸了: 这个坑留在我的几个应用里好久了,今天刚解决。方法是换个API。。。。。 原来是这样子: var path = await StorageFolder.GetFolderFromPathAsync("Assets/StationFloorMaps/"); var imgTemplate = await path.GetFileAsync(_imgPath.Replace("Assets/StationFloorMaps/", string.Empty)); 现在是这样子: var package = Windows. …


Windows Phone 8.1 (WinRT) 如何实现Timer

最近在用WinRT重写以前的一个应用,需要显示一个时钟,结果发现没有Timer控件。。。 看来只能自己写代码实现了。屌丝的做法是Thread.Sleep,但那个会卡UI线程,用户会操作不了任何东西。正确的思路应该是用.NET 4.5的async await,不会卡UI线程。替代Thread.Sleep的方法是Task.Delay,它是awaitable的,所以代码是这样的: while (true) { // 要做的操作 await Task.Delay(毫秒); } 为了增加逼格和可重用性,我们需要进一步封装。注意观察本高(diao)手(si)是如何一步步提高逼格的。 首先是循环条件和毫秒数,要能被控制,所以加入属性: public int Interval { get; set; } public bool IsEnabled { get; …


Windows Phone 8.1 DatePicker和TimePicker控件的数据绑定

Windows Phone Runtime 8.1 (WinRT) 自带了DatePicker和TimePicker控件。妈妈再也不用担心我装WPToolkit了。但是和WPToolkit里面的两个Picker不同,WinRT的控件在MVVM模式里做data binding的时候是要爆的。 首先是DatePicker。 具体的情况表现为:ViewModel里的属性是DateTime类型,并且VM正确实现了INotifyPropertyChanged接口,前台直接用Binding语法绑定这个属性,但VM变化,界面不变。界面变化,VM不变。代码看起来就像是这样: Xaml: <DatePicker Date="{Binding SelectedDate, Mode=TwoWay}" /> ViewModel: private DateTime _ …


我在《上海轨道交通》中是如何解决Windows Phone拼音分组bug的

我的App《上海轨道交通》有个很坑的bug,按拼音首字母分组的站点列表会出现分组错误的情况,比如“莘庄”应该在X下,而WP的SortedLocaleGrouping居然把它分在了S下。这是因为“莘庄”的“莘”是多音字。同理,应该在C下的“长江南路”也到了“Z”下。类似的还有: 分组的代码用的是MSDN的范例改的:http://msdn.microsoft.com/library/windows/apps/jj244365(v=vs.105).aspx 这个范例对于英文来说是没问题的,中文就会出现多音字的问题。 为了解决这个坑爹问题,我写了个PinYinGroupResolver,用的时候可以写出很装逼的代码,比如这样: GroupedStations …


Windows Phone 8 开发:地图应用测试正常发布后爆掉的解决办法

最近更新了一次我的《上海轨道交通》App,结果爆了。为了加入街区图功能我用了WP自带的Map控件,并且也申请了正确的API Key,发布之前在模拟器和真机上测试一切OK,结果发布后就是这个样子的: 具体的异常信息是: Cannot create instance of type 'Microsoft.Phone.Maps.Controls.Map' [Line: 84 Position: 38]Exception from HRESULT: 0xD0000022 根据之前的经验,这像是没有在AppManifest中打开需要的权限。可是我分明已经勾选了ID_CAP_MAP了,还需要什么权限呢?最后经过一番苦逼的研究,在MSDN上看到了这样一个警告: 你TM在逗我?VS居然在我部署测试程序的时候偷偷把这个capability选上了而不告诉我一下!我的App设计的目的就在于尽量不 …


Live to Code: Windows Phone开发,让我感受不一样的天地

本文首发于大微软Live to Code活动官网:http://www.microsoft.com/china/livetocode/91.html 我是一个疯狂的软粉,也是微软产品十几年的老用户,2012年毕业参加工作之后接触到了许多微软的前沿技术,对微软产品更加爱不释手。在用Windows Phone以前,我用的是一款中端的Android手机,Android系统虽然软件丰富多样,但它非常耗电,系统也经常卡得受不了,还中过两次毒,于是忍无可忍之下我换了一部诺基亚720,终于凑齐了微软的三个代表:Surface,Office和Windows Phone。 其实我的主要工作是开发ASP.NET网站,自己的博客(diaosbook.com)也是一路走来从WebForm 2.0维护到现在的MVC 5.1,然而相比ASP.NET开发,WP让我感觉更贴近普通用户。开发免费、无广告、注重界面和交互 …


Windows Phone 8 开发:应用崩溃时给作者发送错误报告邮件

我们的应用难免会爆,但是手工在各个方法上加try...catch...未必能cover到所有场景,有时候我们不希望应用吞掉错误,发生严重异常时,我们应当允许应用在用户面前爆掉。如果没有处理这些异常,应用程序的表现就是闪退。比较好的做法是在应用崩溃时给用户一个选择是否发送邮件告诉应用作者崩溃的详细日志。对于作者来说,等待DevCenter的异常报告相对而言比较被动。如果能在应用崩溃之后立即得到回馈那就可以尽早修复问题。 做法很简单,和ASP.NET网站在Global.asax中使用的全局错误处理类似,WP应用也有个全局错误处理的事件。 打开App.xaml.cs,定位到Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)事件处理函数上。 当任何未处理的异常产生时 …


Windows Phone 8 开发:如何判断用户手机是否更新了GDR3

有时候我们开发的软件需要用到GDR3更新的功能,比如调用屏幕旋转的设置之前就先得确定用户已经安装了GDR3。但是WP SDK没有提供直接的方法,所以我们只能通过判断操作系统版本号来确定用户的系统是否安装了GDR3。 GDR3的特征是:系统版本号大于8.0.10492(Developer Preview包含在内)。在手机的关于页面中可以看到当前版本号,安装了GDR3的通常是8.0.10512: 所以,判断GDR3的代码如下: static bool IsGDR3() { return Environment.OSVersion.Version >= new Version(8, 0, 10492); } 下面是有图有真相环节: MessageBox.Show(IsGDR3() ? "This Phone has GDR3 installed" : " …


Windows Phone 8 LongListSelector按拼音首字母分组

Windows Phone 8的LongListSelector控件按拼音分组主要有两种方法,一个是在数据源里手工指定拼音首字母字段,作为index,这种方法效率高但会造成数据冗余不宜维护。另一个就是我今天介绍的方法,来自MSDN,虽然官网例子是针对是英文数据的首字母分组,但其实稍微改一下还是是支持中文的。首先给大家看看分组的效果,和WP人脉应用按联系人拼音首字母分组的意思是一样的: 实现方法很简单。首先你需要一个来自MSDN的AlphaKeyGroup类,代码如下(我稍作了代码风格上的改动,编译结果和MSDN官网是一样的,不要在意这些细节):public class AlphaKeyGroup<T> : List<T> { /// <summary> /// The delegate that is used to get …


Use GB2312 encoding on Windows Phone 8

如果你在WP开发中遇到过中文乱码,多数原因就是编码问题。比如用webclient获取远程网页的内容,如果目标网页是GB2312编码的,那你取得的很可能是乱码。就像这样: 虽然webclient的构造函数支持传递编码方式进去,但WP默认Encoding枚举中没有GB2312编码: 聪明的你可能会用Encoding.GetEncoding(“GB2312”)强撸,结果灰飞烟灭: 好在这个问题已经有高手给解决了。只要添加这三个文件到项目中去就能直接使用。 big5.bingb2312.binDBCSEncoding.cs 这些文件在我的SkyDrive共享上都能下载到。https://skydrive.live.com/?mkt=zh-CN#cid=E0A43B71445444C5&id=E0A43B71445444C5!10177 之后, …


Windows Phone 8中使用FontAwesome图标库

FontAwesome是Web开发人猿常用的一套图标库,它将369个图标制成了字体,能够矢量缩放、自由配置颜色。但是Windows Phone开发常用的界面技术是xaml,不是html,是不是就无法体验FontAwesome了?当然不是!由于FontAwesome是个字体库,WP是可以整合字体的,所以通过简单的步骤依旧能在WP上用FontAwesome的图标。首先,和在网站中使用一样,要去FontAwesome官网(http://fontawesome.io/)下载最新的包,解压后得到5个字体文件,我们只需要“FontAwesome.otf”。将它复制到你的WP项目中,一般作为资源文件,我们习惯将它放到Resource文件夹下。然后选中FontAwesome.otf,在属性窗格中,把Build Action改成Resource 之后要立即 …


Windows Phone 8开发: 如何让图片自适应黑色、白色主题

前几天发现我的App有个bug,即某个页面的电话图标在白底黑字的主题下会消失。我的电话图标用的是一个白色的PNG图片,在WP默认的黑底白字主题下,就像是这样: 然而换了白底黑字,图就看不到了: 要解决这个问题我们固然可以准备两张图片然后用编程的方法去加载,但最简单的做法是通过Brush来搞: 原先的代码是这样的: <Image Source="Assets/appbar.phone.png" Height="84" Width="84" Tap="ImgPhone_OnTap" /> 用了Brush给它刷上WP当前主题的前景色(PhoneForegroundBrush): <Rectangle Fill="{StaticResource PhoneForegroundBrush}" Height="84" …


Windows Phone 8: 如何自定义Pivot头部样式

WP的Pivot控件很牛逼,但想要调整样式没有什么比较直观的方法。许多少年只会改HeaderTemplate,但要做到下面这种效果,HeaderTemplate是不够的。 首先,正确的方法是通过模板的样式来做。比如上面这张图的样式,就需要在App.xaml里定义自己的Pivot控件样式。下面的代码加在Application.Resources节点下,这样你的每一个页面就都能用到这个样式了。 <Style x:Key="DiaosbookPivotStyle" TargetType="phone:Pivot"> <Setter Property="Margin" Value="0"/> <Setter Property="Padding" Value="0"/> < …


我的第一个Windows Phone应用:《上海影城排片查询》已发布

上海影城排片查询免费 在应用商店中查看 查询上海几所影城最新上映的电影。 - 显示票价、放映厅、放映时间 - 保存到日历并定时提醒 - 查看影院地址 - 直接呼叫影院电话 - 邮件、短信分享 数据来自上海影城官网,一般只更新未来3天的排片表。 这个App采用了微软哥 @韦恩卑鄙 的 MVVM-Sidekick框架开发。很多基友问我数据怎么来的,由于官方不提供SOAP或REST服务,所以我是解析官网排片表的HTML得到的,大家不要在意这些细节。下个版本我会在Windows Azure上构建专门的服务以保证官网的改动不会要求更新App。    


Windows Phone 8 检查网络状态、打开网络设置

开发WP应用的时候,如果你的应用需要互联网连接,那么检测当前网络是否可用并给出提示是非常必要的。Windows Phone 8 检查网络是否可用的 API如下: System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable() 这个API会检查手机网络或WIFI是否可用,返回bool类型结果。 转到网络设置用的是ConnectionSettingsTask对象,ConnectionSettingsType属性决定了打开的设置页面是哪种连接类型,如果要打开WLAN设置,代码如下: var connectionSettingsTask = new ConnectionSettingsTask { ConnectionSettingsType = ConnectionSettingsType. …


Windows Phone 8: MVVM-Sidekick框架如何绑定ProgressIndicator

MVVM(Model-View-ViewModel)是xaml开发者常用的装逼模式,WP应用也不例外,除了我们常用的Prism和MVVM Light,现在还有个后起之秀叫做MVVM-Sidekick。用了它,就可以充分利用.NET4.5的async await来提升逼格了,这个轻量级框架也提供了非常便捷的代码模板,同样完成一个功能需要花费的精力比同类框架要少。具体介绍可以看它的官网:https://github.com/waynebaby/mvvM-Sidekick 但是,在DataContext的处理上,这个框架有些特殊。前几天我就爆掉了。 简单的说,我的需求就是在Windows Phone页面上显示一个进度指示器,把后台的Busy和Message属性绑定到ProgressIndicator上面。这个简单的任务在MVVM Light框架中与其他UI控件的绑定完全一致,可以这么写: …


如何在设计器中显示Windows Phone 8的菜单栏(ApplicationBar)

最近正式开始玩WP开发,把一些小技巧和经验写成单独的一篇篇文章,虽然很菜, 通常,我们新建一个Windows Phone应用程序后,菜单栏的代码默认是在MainPage.xaml.cs文件中的。只要取消模板里的这些注释就能在运行时看到菜单栏。 但是这么做有个缺点,就是无法在设计器里直观的看到菜单栏,不便于我们设计和调整UI。其实我们不必使用后台代码来实现菜单栏。它可以直接定义在xaml文件里。打开MainPage.xaml,在LayoutRoot的Grid之外(注意不要定义在Grid里边),加入代码: <phone:PhoneApplicationPage.ApplicationBar> <shell:ApplicationBar StateChanged="ApplicationBarStateChanged"> < …


Windows Phone 8 文本框如何限定软键盘类型

在开发Windows Phone应用时,一个非常通用的需求就是限定文本框的输入内容。最直接的办法是限定弹出的软键盘的类型。比如有些文本框只允许输入数字,那就弹出数字键盘,不让用户选择其他键盘。这样做的好处有两个:节省后台验证逻辑、方便用户交互。 要限定键盘类型,做法很简单,就是设置TextBox控件的InputScope属性。比如输入电话号码的文本框可以这样写: <TextBox InputScope="Number" Name="txtPhoneNumber" /> 这样弹出的文本框就是数字键盘: 所有的InputScope类型见下表: 翻译自MSDN:http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh393998%28v=vs.105%29.aspx 键盘 备注 …


Windows Phone 8 列表控件(LongListSelector)分组

Windows Phone 8的列表控件天生支持分组,就像人脉应用中的类似,可以快速根据拼音首字母定位。在列表视图中点击分组标题后显示所有的组名,点击组名即可定位到这个组。我们自己开发的WP应用也能做到这样的分组功能,但需要一些额外的代码。下面的例子来自我的一个WP应用,有图有真相: 分组视图: 实现LongListSelector分组其实很简单。 1. 首先,你需要一个分组的助手类,这是一个相对标准的类,MSDN上抄来的: public class Group<T> : List<T> { public Group(string name, IEnumerable<T> items) : base(items) { this.Title = name; } …