我将UserControl另存为JPG时遇到了一个奇怪的问题。基本上我想要做的是创建一个Live Tile,我可以使用后台代理(以及应用程序本身)更新。
我已经按照this blog post中的步骤进行操作,这些步骤在创建磁贴时效果很好;我有一个带有一些TextBlocks的自定义UserControl,它被保存为一个JPG到IsolatedStorage,就像帖子所说的那样。
创建磁贴没有问题 - UserControl的渲染效果非常好。但是,当我尝试更新磁贴时(使用完全相同的方法 - 将新控件保存为JPG,然后将该JPG用作BackgroundImage),事情就会崩溃。
放置在磁贴上的结果图像(并保存在IsolatedStorage中)如下所示:squished tile(使用Isolated Storage Explorer工具从IsolatedStorage中拉出)
背景为黑色,所有文字都沿着图像的一侧向下(并且相互重叠) - 预期的结果是背景是手机的强调色,而文字在顶部附近显得水平
用于生成和保存图像的代码在两个实例中完全相同 - 我将其抽象为一个返回StandardTileData
的静态方法。唯一的区别在于调用它的位置:在创建磁贴的工作情况下,它从主应用程序中的页面调用;在非工作情况下(更新磁贴),从一个只能通过磁贴本身深层链接访问的页面调用它。
有什么想法?我猜测将控制渲染到JPG会出现问题,因为实际图像是这样出现的。
生成图像的代码片段在这里:
StandardTileData tileData = new StandardTileData();
// Create the Control that we'll render into an image.
TileImage image = new TileImage(textA, textB);
image.Measure(new Size(173, 173));
image.Arrange(new Rect(0, 0, 173, 173));
// Render and save it as a JPG.
WriteableBitmap bitmap = new WriteableBitmap(173, 173);
bitmap.Render(image, null);
bitmap.Invalidate();
IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication();
String imageFileName = "/Shared/ShellContent/tile" + locName + ".jpg";
using (IsolatedStorageFileStream stream = storage.CreateFile(imageFileName))
{
bitmap.SaveJpeg(stream, 173, 173, 0, 100);
}
tileData.BackgroundImage = new Uri("isostore:" + imageFileName, UriKind.Absolute);
return tileData;
我尝试转换的控件的XAML在这里:
<UserControl x:Class="Fourcast.TileImage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
d:DesignHeight="173" d:DesignWidth="173" FontStretch="Normal" Height="173" Width="173">
<Border Background="{StaticResource PhoneAccentBrush}">
<StackPanel>
<TextBlock HorizontalAlignment="Stretch"
TextWrapping="Wrap" VerticalAlignment="Stretch" Style="{StaticResource PhoneTextLargeStyle}" x:Name="Temperature"></TextBlock>
<TextBlock x:Name="Condition" HorizontalAlignment="Stretch"
TextWrapping="Wrap" VerticalAlignment="Stretch" Style="{StaticResource PhoneTextNormalStyle}">
</TextBlock>
</StackPanel>
</Border>
</UserControl>
更新:在使用调试程序进行一些调查后,当调用此方法时,Measure
和Arrange
的调用似乎无法执行任何操作更新磁贴的类。但是,在创建切片时,这些调用将按预期运行(控件的ActualWidth和ActualHeight将更改为173)。
答案 0 :(得分:1)
不确定这里到底发生了什么,但这是我最终要解决的问题。
我从尝试渲染控件转换为在代码中定义StackPanel
,向其中添加元素,然后将其渲染为图像。但奇怪的是,Arrange
和Measure
方法除非已将其应用于,并且UpdateLayout
已调用,否则不执行任何操作。
完整的结果代码(减去TextBlock
的内容并写入图像)如下所示。
StandardTileData tileData = new
// None of this actually does anything, but for some reason the StackPanel
// won't render properly without it.
Border image = new Border();
image.Measure(new Size(173, 173));
image.Arrange(new Rect(0, 0, 173, 173));
image.UpdateLayout();
// End of function-less code.
StackPanel stpContent = new StackPanel();
TextBlock txbTemperature = new TextBlock();
txbTemperature.Text = temperature;
txbTemperature.Style = (Style)Application.Current.Resources["PhoneTextLargeStyle"];
stpContent.Children.Add(txbTemperature);
TextBlock txbCondition = new TextBlock();
txbCondition.Text = condition;
txbCondition.Style = (Style)Application.Current.Resources["PhoneTextNormalStyle"];
stpContent.Children.Add(txbCondition);
stpContent.Measure(new Size(173, 173));
stpContent.Arrange(new Rect(0, 0, 173, 173));
答案 1 :(得分:0)
获取图像背景以使用手机强调色的方法是使其透明。这将要求您保存PNG而不是JPG。
输出图像看起来就像所有东西都包含它需要的东西。您可能需要调整控件中包含的元素的宽度。没有XAML,很难更具体。
答案 2 :(得分:0)
我也得到了这种奇怪的行为 - 压扁了瓷砖(使用Ree7 Tile工具包),
尝试将调用更新磁贴调用到Dispatcher:
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
CustomTile tile = GetTile(card);
StandardTileData tileData = tile.GetShellTileData();
shellTile.Update(tileData);
});
为我工作