0

我在将 UserControl 保存为 JPG 时遇到了一个奇怪的问题。基本上我想做的是创建一个动态磁贴,我可以使用后台代理(以及从应用程序本身内部)更新它。

我已经按照这篇博文中的步骤进行了操作,这些步骤在我创建磁贴时非常有用;我有一个自定义的用户控件,上面有一些文本块,它作为 JPG 保存到独立存储中,正如帖子所说。

创建图块没有问题 - UserControl 被很好地呈现,因为它应该是。但是,当我尝试更新磁贴时(使用完全相同的方法 - 将新控件保存为 JPG,然后使用该 JPG 作为 BackgroundImage),事情就崩溃了。

放置在图块上(并保存在独立存储中)的结果图像如下所示:压扁图块(使用独立存储资源管理器工具从独立存储中拉出)

背景是黑色的,所有文字都沿着图像的一侧向下延伸(并相互重叠)——预期的结果是背景是手机的强调色,而文字在顶部附近水平显示。

用于生成和保存图像的代码在两个实例中完全相同——我已将其抽象为一个静态方法,该方法返回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)。

4

3 回答 3

1

不确定这里到底发生了什么,但这是我最终为解决该问题所做的工作。

我从尝试渲染控件切换到StackPanel在代码中定义一个,向其中添加元素,然后将其渲染为图像。然而,奇怪的是,ArrangeandMeasure方法不会做任何事情,除非另一个元素已将它们应用于它并被UpdateLayout调用。

完整的结果代码(减去TextBlocks 的内容并写入图像)如下。

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));
于 2012-06-27T06:03:27.393 回答
0

让图像背景使用手机的强调色的方法是使其透明。这将要求您保存 PNG 而不是 JPG。

输出图像看起来像所有东西都比它需要的更多。您可能需要调整控件中包含的元素的宽度。如果没有 XAML,很难更具体。

于 2012-06-25T11:39:08.043 回答
0

我也得到了这种奇怪的行为 - 压扁的瓷砖(使用 Ree7 Tile 工具包),

尝试在 Dispatcher 中调用 update tile:

Deployment.Current.Dispatcher.BeginInvoke(() =>
{
    CustomTile tile = GetTile(card);
    StandardTileData tileData = tile.GetShellTileData();
    shellTile.Update(tileData);
});

为我工作

于 2013-07-19T12:43:14.030 回答