[Windows Phone 8 | Dev Tech]_使用UserControl自訂Live Tile

在設計開發Windows Phone的時候,Tile只能用官方提供的三種嗎?...
本文教你如何自訂化Windows Phone的Tile,讓你的Tile能更夠能自由掌控呈現的資料!

在開發Windows Phone的App,有些情況是很適合用Windows Phone特色:Live Tile

做資訊上的呈現,那麼官方其實只提供幾個預設的API跟格式,讓你自己塞相關的資料到Tile物件裏頭使用

 

那麼各位有經驗的開發者一定都知道微軟有提供三種Tile形式,跟斯斯感冒膠囊有三種一樣(拖走

問我哪三種...來~微軟文件看一下:http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh202948%28v=vs.105%29.aspx

 

 

而實作這三種其實也不難,網路上中文文獻相對也多了,我就不RE這一部分的相關文章

 

那…千遍一律只能用這三種嗎T_T!!!

 

當然不!,前陣子我在做郵遞區號App的時候因為想要自訂Tile,網路海撈搜尋了一陣子

 

最簡單且最直接的解就是「產生圖片」,直接當作Tile的背景

好懂易了解

 

所以我特別把Nokia這篇翻譯整理了一下,若本文有不詳盡之處,可以參考原文~~:

http://developer.nokia.com/Community/Wiki/Custom_Live_Tile_Layout_with_UserControl_as_image_source

 

 

▼首先你必須要創立一個UserControl,加入到你要自訂的專案中,我這裡取名為CustomTile

2013-11-18 下午 05-32-13

 

然後要開始設計這個UserControl的相關Layout以及配置,以下Xaml Code可以閱讀理解完之後再自行修改成自己要的配置

   1: <UserControl x:Class="TWZIP_VST.CustomTile"
   2:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   3:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   4:     xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
   5:     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
   6:     mc:Ignorable="d"
   7:     FontFamily="{StaticResource PhoneFontFamilyNormal}"
   8:     FontSize="{StaticResource PhoneFontSizeNormal}"
   9:     Foreground="{StaticResource PhoneForegroundBrush}"
  10:     d:DesignHeight="336" d:DesignWidth="336">
  11:  
  12:     <Grid x:Name="LayoutRoot" Background="{StaticResource PhoneAccentBrush}">
  13:         <StackPanel>
  14:             <TextBlock x:Name="tb_add" HorizontalAlignment="Left"   TextWrapping="Wrap" 
  15:            VerticalAlignment="Top" Height="183" Width="337" FontSize="50" Text="Address" 
  16:            TextAlignment="Center" Margin="0,0,-1,0"/>
  17:             <TextBlock x:Name="tb_post" Text="POST" HorizontalAlignment="Left"   
  18:            TextWrapping="Wrap" VerticalAlignment="Top" Width="335" Height="123" 
  19:            TextAlignment="Center"  FontSize="80"/>
  20:         </StackPanel>
  21:     </Grid>
  22: </UserControl>

 

稍微解說一下第一行的className自行修改為你專案的內容,這裡是我郵遞區號App專案的名稱

而第10行的部分,d:DesignHeight以及d:DesignWidth數值為336代表正常大小Tile的寬跟高各為336pixel,

在設計時期,d:標籤可以依照這個標籤去改變旁邊預覽畫面的大小

 

那Grid裡面的東西就是很理所當然是你要去設計的內容,記得如果你要更新資料的UI項目要給名稱~,

這樣等下在BEHIDE CODE的部分你在能控制前端的控制項~~

當然它可以放下任何XAML的控制項,例如Image阿等,所以你不一定只能丟文字上去喔~可以自己摸看看

 

▼上面的XMAL CODE產生以下畫面,主要為有兩個TEXTBLOCK,分別要塞入我專案要呈現的地址以及郵遞區號

2013-11-18 下午 05-40-17

 

▼在BEHIND CODE的部分,我依照我上頭設計的控制項,在副程式上面做了一些調整

   1: private void createTile(string Add, string Post)
   2:         {
   3:             var customTile = new CustomTile();//創建一個Tile物件
   4:             customTile.Measure(new Size(336, 336));//把這個Tile物件New出一個UI SIZE)
   5:             customTile.Arrange(new Rect(0, 0, 336, 336));//在上頭放一個跟UI SIZE一樣大小的矩形)
   6:             customTile.tb_add.Text = Add;//然後開始塞資料到剛剛創立的兩個控制項上頭
   7:             customTile.tb_post.Text = Post;
   8:  
   9:             var bmp = new WriteableBitmap(336, 336);//NEW一張點陣圖
  10:             bmp.Render(customTile, null);//把這個點陣圖物件丟到customTile物件裡面
  11:             bmp.Invalidate();//重新繪製一次這張點陣圖
  12:  
  13:             const string filename = "/Shared/ShellContent/CustomTile.jpg";//要把這張點陣圖存到ISOLATEDSTORAGE裡面
  14:  
  15:             using (var isf = IsolatedStorageFile.GetUserStoreForApplication())
  16:             {
  17:                 //NOKIA原文說明有這段判斷式,但其實根本沒用到這個資料夾,可以不用加入
  18:                 //if (!isf.DirectoryExists("/CustomLiveTiles"))
  19:                 //{
  20:                 //    isf.CreateDirectory("/CustomLiveTiles");
  21:                 //}
  22:                 using (var stream = isf.OpenFile(filename, System.IO.FileMode.Create))
  23:                 {
  24:                     bmp.SaveJpeg(stream, 336, 366, 0, 100);
  25:                 }
  26:             }
  27:  
  28:             FlipTileData tileData = new FlipTileData //創建一個系統內的FLIPTILE
  29:             {
  30:                 //如果你這邊只有加入一個屬性,其實他就不會有FLIP翻轉的效果喔~~就是靜態的
  31:                 BackgroundImage = new Uri("isostore:" + filename, UriKind.Absolute),
  32:             };
  33:  
  34:             //下面是我用來判斷現有tile存不存在,如果已經有tile就直接更新他就好
  35:             string tileUri = "/MainPage.xaml";
  36:  
  37:             ShellTile tile = ShellTile.ActiveTiles.FirstOrDefault(x => x.NavigationUri.ToString().Contains("MainPage".ToString()));
  38:  
  39:             if (tile != null)
  40:             {
  41:                 tile.Update(tileData);
  42:                 MessageBox.Show("磚已更新");
  43:             }
  44:             else
  45:             {
  46:                 ShellTile.Create(new Uri(tileUri, UriKind.Relative), tileData, false);
  47:             }
  48:  
  49:         }

 

wp_ss_20131022_0007

 

跟著上面做並且微調一些code,你就能簡單獲得一個野生的客製化TILE

不過這個作法有個缺點,就是如果你的手機佈景主題的顏色一旦更換,就會變成那個TILE的背景顏色還是舊的顏色

提供幾種作法解決:

 

1.利用BACKGROUD AGENT去RUN,隨時判斷背景主題的顏色並且在改變的時候更新TILE

這個部份我就直接延伸閱讀給我另外一個PARTNER SUKI的文章做搭配閱讀,我這裡就不覆述了!

當然BACKGROUND AGENT不是只能換顏色,它可以做很多背景的程序搭配~~~

搭配物件的交換使用就可以做到更新TILE上面的資料等等,可以呼叫上文所說的createTile副程式

但要小心如果是BACKGROUND AGENT呼叫,不能有MSGBOX,這點要注意使用~建議在自己去修改成適合的物件

BACKGROUND AGENT:http://www.dotblogs.com.tw/holiestar/archive/2013/10/29/126112.aspx

 

2.直接塞一個你喜歡的顏色在LayoutRoot Grid控制項背景,把背景色寫死

 

3.pou網友的回覆,利用WriteableBitmapEx這個套件,

讓WriteableBitmap能擴充方法獲得.WritePNG()這個方法然後再把上面UserControl的XAML GRID中的BACKGROUND移除

<Grid x:Name="LayoutRoot" Background="{StaticResource PhoneAccentBrush}">

 

並把上方C# CODE第24行的

bmp.SaveJpeg(stream, 336, 366, 0, 100);

改為

bmp.WritePNG(stream);

 

還有13行的

const string filename = "/Shared/ShellContent/CustomTile.jpg";

副檔名改成.png即可!

 

來源:

http://www.dotblogs.com.tw/pou/archive/2013/10/08/123396.aspx

 


 

最後我要低調置入性行銷一下...之前做了一個可以查中華民國3+2郵遞區號的App,可以線上查詢也可以離線查詢~~

很方便~~裡面就有實作這個自訂Tile的效果,各位可以抓來使用優 <3

App Deep Link:http://www.windowsphone.com/s?appid=cec6624b-1c4d-465b-b45f-eb1d3549c00d