簡體   English   中英

如何創建具有自定義布局的WP8動態圖塊?

[英]How do I create a WP8 Live Tile with a custom layout?

我正在尋找創建一個與“ Iconic”磁貼類似的“ Live Tile”,但允許我使用自定義Count值(即非整數字符串)。

最接近的是,我必須使用位圖創建內容,然后使用該圖像作為圖塊。 不幸的是,我不知道這通常是怎么做的。

我正在尋求創建類似於此問題中描述的圖塊(盡管此問題與我的問題正交): Windows Phone(7/8)上的自定義實時圖塊渲染問題

簡而言之,

  • WriteableBitmap是創建Live Tile布局的最佳方法嗎?
  • 有沒有可以將XAML轉換為Live Tile的機制?

我想實現的布局示例在此處顯示的Skype Live Tile中有所顯示。

據我所知,創建自定義位圖是必經之路。 當我做活動瓷磚時,我發現此答案以及本文非常有用。

如果您不介意購買第三方控件,則可以查看Telerik的LiveTileHelper控件(如果您是諾基亞開發人員計划的成員,則已經可以訪問此控件)。

對於我的第一個應用程序,我選擇根據前兩個鏈接推出自己的解決方案。 我有一個基類,負責處理采用FrameworkElement的工作(每個派生類負責生成包含要渲染的信息的FrameworkElement )並創建相應的WritableBitmap實例,然后使用ToolStack C#PNG Writer將其保存為.PNG。圖書館。

舉例來說,這是我的代碼,用於生成代表我的一個應用程序中的固定小圖塊的控件:

    /// <summary>
    /// Returns the fully populated and initialized control that displays
    /// the information that should be included in the tile image.
    /// </summary>
    /// <remarks>
    /// We manually create the control in code instead of using a user control
    /// to avoid having to use the XAML parser when we do this work in our
    /// background agent.
    /// </remarks>
    /// <returns>
    /// The fully populated and initialized control that displays
    /// the information that should be included in the tile image.
    /// </returns>
    protected override FrameworkElement GetPopulatedTileImageControl()
    {
        var layoutRoot = new Grid()
                            {
                                Background          = new System.Windows.Media.SolidColorBrush( System.Windows.Media.Color.FromArgb( 0, 0, 0, 0 ) ),
                                HorizontalAlignment = HorizontalAlignment.Stretch,
                                VerticalAlignment   = VerticalAlignment.Stretch,
                                Height              = TileSize.Height,
                                Width               = TileSize.Width,
                                Margin              = new Thickness( 0, 12, 0, 0 )
                            };
        var stopName = new TextBlock()
                            {
                                Text                = Stop.Description,
                                TextTrimming        = TextTrimming.WordEllipsis,
                                TextWrapping        = TextWrapping.Wrap,
                                Margin              = new Thickness( 7, 0, 7, 12 ),
                                MaxHeight           = 135,
                                Width               = TileSize.Width - 14,
                                VerticalAlignment   = VerticalAlignment.Bottom,
                                HorizontalAlignment = HorizontalAlignment.Stretch,
                                FontFamily          = (System.Windows.Media.FontFamily) Application.Current.Resources[ "PhoneFontFamilySemiBold" ],
                                FontSize            = (double) Application.Current.Resources[ "PhoneFontSizeMediumLarge" ],
                                Style               = (Style) Application.Current.Resources[ "PhoneTextNormalStyle" ]
                            };

        Grid.SetColumn( stopName, 0 );
        Grid.SetRow( stopName, 0 );

        layoutRoot.Children.Add( stopName );
        return layoutRoot;
    }

這是一個只有TextBlock的超簡單控件,但是您可以輕松地對此進行擴展。 請注意,在這里我不使用UserControl ,因為我也在有大量內存限制的后台代理中運行此代碼。

一旦有了控件,我將生成一個WritableBitmap如下所示:

    /// <summary>
    /// Renders the tile image to a <see cref="WritableBitmap"/> instance.
    /// </summary>
    /// <returns>
    /// A <see cref="WritableBitmap"/> instance that contains the rendered
    /// tile image.
    /// </returns>
    private WriteableBitmap RenderTileImage()
    {
        var tileControl = GetPopulatedTileImageControl();
        var controlSize = new Size( TileSize.Width, TileSize.Height );
        var tileImage   = new WriteableBitmap( (int) TileSize.Width, (int) TileSize.Height );

        // The control we're rendering must never be smaller than the tile
        // we're generating.
        tileControl.MinHeight   = TileSize.Height;
        tileControl.MinWidth    = TileSize.Width;

        // Force layout to take place.
        tileControl.UpdateLayout();
        tileControl.Measure( TileSize );
        tileControl.Arrange( new Rect( new Point( 0, 0 ), TileSize ) );
        tileControl.UpdateLayout();

        tileImage.Render( tileControl, null );
        tileImage.Invalidate();

        tileControl = null;
        GC.Collect( 2, GCCollectionMode.Forced, true );

        // Adjust the rendered bitmap to handle the alpha channel better.
        CompensateForRender( tileImage );

        return tileImage;
    }

再次,我對GC.Collect進行了顯式調用,以幫助在運行此代碼作為后台代理的一部分時控制內存消耗。 CompensateForRender方法基於鏈接文章中的代碼。

希望這可以幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM