Windows Phone 是那个1%, 我也是那个1%, 不喜勿喷.
WP 向来给 android / ios 的粉们一个最直观的印象: 丑.
其实"丑"这个东西会一直下去,而且是个解不开的死循环.

WP 下, 做的华丽的, 目前我用过的只有少数几个, 网易云音乐 和 智机社区, 做的漂亮而且流畅, 其它的只能用渣渣来形容.

Xamarin.Form 的 APP 在 Android 和 IOS 下默认都会有一个"头", 用于显示页面名称和导航按钮.
在 WP 下却没有, 像这样:

Xamarin.Form 在 WP 的 MainPage.xaml.cs 中这样定义:

public partial class MainPage : FormsApplicationPage{
...
        public MainPage() {
            InitializeComponent();
            SupportedOrientations = SupportedPageOrientation.PortraitOrLandscape;

            global::Xamarin.Forms.Forms.Init();
            LoadApplication(new LBC.Mobi.App());
        }

FormsApplicationPage.LoadApplication 方法的定义:

     protected void LoadApplication(Xamarin.Forms.Application application)
     {
       Xamarin.Forms.Application.Current = application;
       application.PropertyChanged += new PropertyChangedEventHandler(this.ApplicationOnPropertyChanged);
       this.application = application;
       application.SendStart();
       this.SetMainPage();
     }

     private void SetMainPage()
     {
       if (this.platform == null)
         this.platform = new Platform((PhoneApplicationPage) this);
       this.platform.SetPage(this.application.MainPage);
       if (this.Content == this.platform)
         return;
       this.Content = (UIElement) this.platform;
     }

这样一个调用链:

LoadApplication -> SetMainPage -> 直接给整个页面的 Content 赋值.

所以, 无论你在 MainPage.xaml 中写什么内容, 最终都是无法显示的.

为了达成目的, 我们需要修改 SetMainPage 方法 , 使 this.platform 只作为 MainPage  的一部分, 而不是整个 Content.

但是反编译一下, 可以看到 Xamarin.Form 的封装很蛋疼, 很多都是 internal , private, 不带 virtual, 所以, 通过正常手段是无法对 Xamarin.Form 进行扩展的.

还好, Xamarin 对反射支持的很到位, 无法正常通过继承/重写来实现, 我们照样可以用反射来完成它.

1, 在 MainPage.xaml.cs 中新增方法 LoadApplication:

         new protected void LoadApplication(Xamarin.Forms.Application application) {
             //Xamarin.Forms.Application.Current = application;
             typeof(Xamarin.Forms.Application).GetProperty("Current", BindingFlags.Static | BindingFlags.Public)
                 .SetValue(Xamarin.Forms.Application.Current, application);

             application.PropertyChanged += new PropertyChangedEventHandler(this.ApplicationOnPropertyChanged);
             typeof(FormsApplicationPage).GetField("application", BindingFlags.NonPublic | BindingFlags.Instance)
                 .SetValue(this, application);

             //application.SendStart();
             application.GetType().GetMethod("SendStart", BindingFlags.NonPublic | BindingFlags.Instance)
                 .Invoke(application, null);

             this.SetMainPage();

17             var mp = (Xamarin.Forms.NavigationPage)application.MainPage;
18             mp.PropertyChanged += MainPage_PropertyChanged;
19             this.Title = mp.Title;
         }

为了能显示当前页的标题, 我在上面的方法中加了一段(红色标注), 实际中, 你的 application.MainPage 可能不是 NavigationPage,  需要自行修改.

2,

         void MainPage_PropertyChanged(object sender, PropertyChangedEventArgs e) {
             if (e.PropertyName.Equals("CurrentPage")) {
                 this.Title = ((Xamarin.Forms.NavigationPage)sender).CurrentPage.Title;
                 this.PropertyChanged(this, new PropertyChangedEventArgs("Title"));
             }
         }

3, 在 MainPage.xaml.cs 中添加 SetMainPage :

         private void SetMainPage() {
             if (this.Platform == null) {
                 this.Platform = new Platform((PhoneApplicationPage)this);
             }

             this.Platform.SetPage(Xamarin.Forms.Application.Current.MainPage);
             if (this.mainBody.Content != null && this.mainBody.Content.Equals(this.Platform))
                 return;
             this.mainBody.Content = (UIElement)this.Platform;
         }

4, 修改 MainPage.xaml

 <winPhone:FormsApplicationPage
     x:Class="Discuz.WinPhone.MainPage"
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
     xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
     xmlns:winPhone="clr-namespace:Xamarin.Forms.Platform.WinPhone;assembly=Xamarin.Forms.Platform.WP8"
     xmlns:local="clr-namespace:Discuz.WinPhone"
     mc:Ignorable="d"
     FontFamily="{StaticResource PhoneFontFamilyNormal}"
     FontSize="{StaticResource PhoneFontSizeNormal}"
     Foreground="{StaticResource PhoneForegroundBrush}"
     SupportedOrientations="Portrait" Orientation="Portrait"
     shell:SystemTray.IsVisible="True"
     shell:SystemTray.Opacity="0"
     Background="#1e5263"
     >
     <!--shell:SystemTray.BackgroundColor="#2ba9d3"-->

     <Grid>
         <Grid.RowDefinitions>
             <RowDefinition Height="15" /><!-- for SystemTray -->
             <RowDefinition Height="auto" />
             <RowDefinition Height="*" />
         </Grid.RowDefinitions>
         <local:TilePanel TileWidth="5" TileHeight="5" Height="65" Grid.Row="0" Grid.RowSpan="2">
             <local:TilePanel.Image>
                 <ImageBrush ImageSource="texture.png" />
             </local:TilePanel.Image>
         </local:TilePanel>
         <StackPanel Orientation="Horizontal" Margin="10,0" Grid.Row="1" VerticalAlignment="Center">
             <Image Source="icon.png" Width="40" Height="40" Margin="0,0,10,0" />
             <TextBlock Text="{Binding Title}" VerticalAlignment="Center" />
         </StackPanel>

         <ContentPresenter x:Name="mainBody" Grid.Row="2" />
     </Grid>

 </winPhone:FormsApplicationPage>

好啦, 一个带标题的 XF For WP 的 APP 改造完了.

最终效果:

具体参见:

https://github.com/gruan01/Discuz.Mobi/tree/master/Discuz/Discuz.WinPhone

--------------------

OK, 完

给 Xamarin.Form For Windows Phone APP 加个漂亮的 "头"的更多相关文章

  1. FlipView For Xamarin.Form 之 IOS

    之前写过两篇博文 是关于 Android 和 Windows Phone 下的 FlipView 的实现. 上上周,有个印度佬通过 GitHub 找到我, 问我有没有打算个 ios 端的,还说比较了相 ...

  2. Xamarin.Form 实例: Discuz BBS 客户端 源码分享

    感谢台风, 这个十一长假让我好好的休息了一回, 睡觉到腰酸背疼, 看电影看到眼发红. 今天最后一天, 不敢出去逛, 不知道哪会还会下暴雨... 嗯嗯..这个项目其实在十一之前就开始了, 工作无聊,没有 ...

  3. Visual Studio + C# + Xamarin = iOS/Android/Windows Apps

    Visual Studio 跨平台開發實戰 (1) -- Hello Xamarin! 前言 應用程式發展的腳步,從來沒有停過.從早期的 Windows 應用程式, 到網路時代的 web 應用程式,再 ...

  4. Windows Phone App的dump 文件分析

    前言 我们在发布了自己的App以后,Windows Phone的Error Report机制会帮助我们收集程序的崩溃信息并发送到微软的服务器上,这可以辅助开发者提高App的稳定性. 那么如何利用这些d ...

  5. [Windows Phone] APP上架,遇到错误2001的解决方案。(Error:2001)

    [Windows Phone] APP上架,遇到错误2001的解决方案.(Error:2001) 问题情景 最近在开始玩Windows Phone的开发,开发的过程中虽然有点小挫折,但是参考网络许多前 ...

  6. Xamarin Android Fragment的两种加载方式

    android Fragment的重点: 3.0版本后引入,即minSdk要大于11 Fragment需要嵌套在Activity中使用,当然也可以嵌套到另外一个Fragment中,但这个被嵌套的Fra ...

  7. Xamarin.Form怎么调用原生方法

    ---恢复内容开始--- Xamarin.Form怎么调用原生包 今天我想和大家分享的是有关Xamarin如何调用安卓的原生代码,下面的例子以大家可能会经常用到的微信WX方法的调用. 首先我们新建一个 ...

  8. Xamarin.Form与Xamarin.Android或Xamarin.IOS的区别简述

    Xamarin.Form与Xamarin.Android或Xamarin.IOS的区别简述: 可能刚刚接触Xamarin的人来说,对于这个概念比较的模糊,认为这说的不都是同一个东西吗?事实并不是这样的 ...

  9. 在桌面程序上和Metro/Modern/Windows store app的交互(相互打开,配置读取)

    这个标题真是取得我都觉得蛋疼..微软改名狂魔搞得我都不知道要叫哪个好.. 这边记录一下自己的桌面程序跟windows store app交互的过程. 由于某些原因,微软的商店应用的安全沙箱导致很多事情 ...

随机推荐

  1. JavaScript Patterns 4.2 Callback Pattern

    function writeCode(callback) { // do something... callback(); // ... } function introduceBugs() { // ...

  2. olacle数据库员工表的创建,及插入数据,添加约束,删除列,查询数据的sql语句

    ---删除原有的员工表drop TABLE employee;---创建员工表CREATE TABLE employee       (       empno NUMBER(4) NOT NULL, ...

  3. Bootstrap(转)

    Bootstrap 随着互联网的不断成熟以及我们越来越多的用各种移动端的设备访问互联网,Web设计师和Web开发者的工作也变得越来越复杂. 十年前,一切都还简单得多.那个时候,大部分用户都是坐在桌子前 ...

  4. maven中把依赖的JAR包一起打包(转)

    转自:http://lvjun106.iteye.com/blog/1849803 这里所用到的MAVEN-PLUGIN是MAVNE-ASSEMBLY-PLUGIN 官方网站是:http://mave ...

  5. linux动态网络和静态网络和克隆后的网络配置

    建议设置网卡NAT模式 动态网络配置:1.一定要开启本地DHCP服务 2.在虚拟网络编辑器中选择NAT模式选中DHCP项如下图 3.ifup eth0 静态网络配置 : 注释:ifcfg-eth0部分 ...

  6. jenkins忘记管理密码处理方式

    进入/var/lib/jenkins/  用vim编辑 config.xml文件 找到useSecurity部分 将true改成false      并且删除下面的 授权部分 保存推出 3.从新进入 ...

  7. 10901 Missile

    10901 Missile 时间限制:1000MS  内存限制:65535K提交次数:40 通过次数:7 Description Long, long ago, country A invented ...

  8. [编]IoT The Internet of Things (IoT) 物联网

    物联网是新一代信息技术的重要组成部分.其英文名称是“The Internet of things”.由此,顾名思义,“物联网就是物物相连的互联网”.这有两层意思:第一,物联网的核心和基础仍然是互联网, ...

  9. 【软件使用】GitHub使用教程for VS2012

    一直以来都想使用Git来管理自己平时积累的小代码,就是除了工作之外的代码了.有时候自己搞个小代码,在公司写了,就要通过U盘或者网盘等等一系列工具进行Copy,然后回家才能继续在原来的基础上作业.Cop ...

  10. 记忆化搜索 codevs 2241 排序二叉树

    codevs 2241 排序二叉树 ★   输入文件:bstree.in   输出文件:bstree.out   简单对比时间限制:1 s   内存限制:128 MB [问题描述] 一个边长为n的正三 ...