2012-06-25 27 views
0

我將一個UserControl保存爲JPG時出現了一個奇怪的問題。基本上我想要做的是創建一個活動瓷磚,我可以使用後臺代理(以及從應用程序本身進行更新)。將UserControl保存爲JPG - 結果爲「壓扁」

我已按照this blog post中的步驟工作,該工作適用於創建瓦;我有一個自定義的用戶控件,上面有一些TextBlocks,它被保存爲IsolatedStorage的JPG格式,完全如帖子所述。

創建貼圖不成問題 - UserControl按照它的樣子很好地呈現。但是,當我嘗試更新拼貼圖時(使用完全相同的方法 - 將一個新控件另存爲JPG,然後將該JPG用作BackgroundImage),就會出現問題。

是被放置在瓦(並保存在IsolatedStorage)產生的圖像看起來是這樣的:squished tile

背景爲黑色(使用獨立存儲資源管理器工具從IsolatedStorage拉),以及所有文字耗盡圖像的邊(彼此重疊) - 預期的結果是背景是電話的重音顏色,並且文字在頂部附近出現水平。

用於生成和保存圖像的代碼在兩個實例中都完全相同 - 我已將它抽象爲一個返回StandardTileData的靜態方法。唯一的區別是它從哪裏調用:在創建tile的工作情況下,它是從主應用程序中的頁面調用的;在非工作情況下(更新磁貼的地方),它只能通過從磁貼本身進行深度鏈接才能訪問的頁面調用。

有什麼想法?我猜測把控件渲染成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> 

更新:經過一番調查使用調試器時,看起來MeasureArrange的調用在從更新磁貼的類中調用該方法時似乎沒有任何作用。但是,在創建磁貼時,這些調用按預期工作(控件的ActualWidth和ActualHeight將更改爲173)。

回答

1

不確定到底發生了什麼,但這裏是我最終做的解決方法。

我嘗試渲染一個控件,在代碼中定義一個StackPanel,向其添加元素,然後將其渲染爲圖像。奇怪的是,ArrangeMeasure方法不會做任何事情,除非另一個元素已將它們應用到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)); 
0

獲取圖像背景以使用手機的重音顏色的方法是使其透明。這將需要您保存一個PNG而不是JPG。

輸出圖像看起來像一切都包裹更多thna它需要。您可能需要調整包含在控件中的元素的寬度。沒有XAML,就很難更具體。

+0

感謝響應 - 我會考慮將其另存爲PNG,但創建區塊時重音顏色會得到正確保存;只有在更新不起作用的地方。 我使用XAML編輯了我正在使用的控件的原始文章。 – Ayulin

0

我也得到這種奇怪的行爲 - 壓扁瓦(使用Ree7瓷磚工具包),

嘗試調用update瓦到調度員:

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

爲我工作