2014-06-20 12 views
0

我正在將我的應用程序重新編寫爲適用於Windows(Phone)8.1的通用應用程序模型,並進行了優化。使用WP8.1通用應用程序在BackgroundTask(C#)中呈現自定義活動切片的最佳方式?

我創建了我的BackgroundTask(C#),它從外部源獲取一些數據,最後一步是渲染可以用作tile的自定義.PNG。

以前,對於Windows Phone 7.x和8.0,我使用了名爲TCD.Controls.LiveTiles.Light的第三方應用程序,它可以幫助您將XAML UserControls轉換爲.PNGs。這工作完美無瑕,但它似乎與通用應用程序模型有一些兼容性問題。

現在我想知道 - 在BackgroundTask中創建.PNGs的最佳方法是什麼?

我讀了關於XamlRenderingBackgroundTask and RenderTargetBitmap的C++實現,但由於我還沒有關於C++的知識,而且我的當前任務已經在C#中,我想要使用C#。

親切的問候, 尼爾斯Laute

+0

只需在C#中執行他們在C++示例中的操作。 :)我測試了它,它似乎工作正常。我不認爲內存或CPU時間是一個問題(當我測試它時,它們不是)。 – yasen

回答

0

我有同樣的問題,但發現在C#中呈現PNG的這個例子。我現在發現這個對https://social.msdn.microsoft.com/Forums/en-US/43295c90-43e8-4b08-8a25-958a1c3d0a0b/explanation-on-windowsuixamlmediaxamlrenderingbackgroundtask?forum=WindowsPhonePreviewSDK

using System; 
using System.Threading.Tasks; 
using Windows.ApplicationModel.Background; 
using Windows.Storage.Streams; 
using Windows.UI.Xaml.Controls; 
using Windows.UI.Xaml.Markup; 
using Windows.UI.Xaml.Media; 
using Windows.UI.Xaml.Media.Imaging; 
using Windows.Graphics.Imaging; 
using Windows.UI.Notifications; 
using Windows.Data.Xml.Dom; 

namespace BackgroundTask 
{ 
    public sealed class AppTileUpdater : XamlRenderingBackgroundTask 
    { 
     protected override void OnRun(Windows.ApplicationModel.Background.IBackgroundTaskInstance taskInstance) 
     { 
      BackgroundTaskDeferral _deferral = taskInstance.GetDeferral(); 
      System.Diagnostics.Debug.WriteLine("OnRun called!"); 
      UpdateTileAsync(_deferral); 
     } 

     private async Task<string> ReadFile() 
     { 
      var folder = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFolderAsync("Assets"); 
      var file = await folder.GetFileAsync("customTile.xml"); 
      string szCustomTileXML = await Windows.Storage.FileIO.ReadTextAsync(file); 
      return szCustomTileXML; 
     } 
     private async void UpdateTileAsync(BackgroundTaskDeferral deferral) 
     { 

      var folder = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFolderAsync("Assets"); 
      var file = await folder.GetFileAsync("customTile.xml"); 
      string szCustomTileXML = await Windows.Storage.FileIO.ReadTextAsync(file); 

      Border tile = XamlReader.Load(szCustomTileXML) as Border; 

      if (null != tile) 
      { 
       tile.Background = new SolidColorBrush(Windows.UI.Colors.Orange); 
       Grid grid = tile.Child as Grid; 
       TextBlock text = grid.FindName("Timestamp") as TextBlock; 
       text.Text = DateTime.Now.ToString("hh:mm:ss"); 
       text = grid.FindName("TimeZone") as TextBlock; 
       text.Text = TimeZoneInfo.Local.DisplayName; 

       Image logo = grid.FindName("LogoImage") as Image; 
       var img = new BitmapImage() { CreateOptions = BitmapCreateOptions.None }; 
       img.UriSource = new Uri("ms-appx:///Assets/acorn.png"); 

       RenderTargetBitmap rtb = new RenderTargetBitmap(); 
       await rtb.RenderAsync(tile, 150, 150); 
       IBuffer pixels = await rtb.GetPixelsAsync(); 
       DataReader dReader = Windows.Storage.Streams.DataReader.FromBuffer(pixels); 
       byte[] data = new byte[pixels.Length]; 
       dReader.ReadBytes(data); 

       var outputFile = await Windows.ApplicationModel.Package.Current.InstalledLocation.CreateFileAsync("UpdatedLiveTile.png", Windows.Storage.CreationCollisionOption.ReplaceExisting); 
       var outputStream = await outputFile.OpenAsync(Windows.Storage.FileAccessMode.ReadWrite); 
       BitmapEncoder enc = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, outputStream); 
       enc.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied, (uint)rtb.PixelWidth, (uint)rtb.PixelHeight, 96,96, data); 
       await enc.FlushAsync();     
      } 
      var TileMgr = TileUpdateManager.CreateTileUpdaterForApplication(); 
      TileMgr.Clear(); 
      var tileTemplate = TileUpdateManager.GetTemplateContent(TileTemplateType.TileSquare150x150Image); 
      var tileImageAttributes = tileTemplate.GetElementsByTagName("image"); 
      XmlElement tmp = tileImageAttributes[0] as XmlElement; 
      tmp.SetAttribute("src", "UpdatedLiveTile.png"); 
      var notification = new TileNotification(tileTemplate); 
      TileMgr.Update(notification); 
      deferral.Complete(); 
     } 

     public void Run(IBackgroundTaskInstance taskInstance) 
     { 
      System.Diagnostics.Debug.WriteLine("Run called!"); 
      OnRun(taskInstance); 
     } 
    } 
} 
0

最有效的方法是使用Win2D框架和一步繪製位圖的一步。這種方法將保持您的資源免費。

+0

有關如何執行此操作的任何示例? – Niels

相關問題