我正在创建一个与标志性图 block 类似的动态图 block ,但允许我使用自定义计数值(即非整数字符串)。
我最接近的是我必须使用位图创建内容,然后使用该图像作为图 block 。不幸的是我不知道这通常是如何完成的。
我正在寻找创建类似于此问题中描述的图 block (尽管此问题与我的问题正交):Custom live tile rendering issue on Windows Phone (7/8)
简而言之,
- WriteableBitmap 是创建动态磁贴布局的最佳方式吗?
- 是否有一种机制可以将 XAML 转换为动态磁贴?
我想要实现的布局示例在 Skype Live Tile 中有所显示,如 here .
最佳答案
据我所知,创建自定义位图是正确的方法。我发现this answer以及this article当我制作动态瓷砖时非常有帮助。
如果您不介意购买第三方控件,您可以查看 Telerik 的 LiveTileHelper 控件(如果您是诺基亚开发者计划的成员,则已经可以访问该控件)。
对于我的第一个应用程序,我选择根据前两个链接推出自己的解决方案。我有一个基类,它处理获取 FrameworkElement
的工作(每个派生类负责生成包含要渲染的信息的 FrameworkElement
)并创建相应的 >WritableBitmap
实例,然后使用 ToolStack C# PNG Writer Library 将其保存为 .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;
}
这是一个 super 简单的控件,只有一个 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
方法基于链接文章中的代码。
希望这有帮助。
关于windows-phone-8 - 如何创建具有自定义布局的 WP8 动态磁贴?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16258758/