Динамический LiveTile — добавление фонового изображения?

#c# #windows-phone-7 #live-tile

#c# #windows-phone-7 #живая плитка

Вопрос:

Работаю с живыми плитками в моем приложении для Windows Phone 7, и оно работает вполне нормально.

Сейчас я пытаюсь создать динамическую живую плитку, и я не могу заставить фоновое изображение отображаться. При использовании приведенного ниже кода я получаю только черную плитку. Текст, который я добавляю, отображается, но не фоновое изображение. Для параметра «Действие сборки» изображения установлено значение «Содержимое».

Есть идеи?

 StackPanel sp = new StackPanel();
sp.Height = 173;
sp.Width = 173;

string fileName = "tile.jpg";
BitmapImage image = new BitmapImage(new Uri(fileName, UriKind.Relative));
ImageBrush brush = new ImageBrush();
brush.ImageSource = image;
sp.Background = brush;

sp.Measure(new Size(173, 173));
sp.Arrange(new Rect(0, 0, 173, 173));
sp.UpdateLayout();
WriteableBitmap wbm = new WriteableBitmap(173, 173);
wbm.Render(sp, null);
wbm.Invalidate();
  

Ответ №1:

У меня также были проблемы с использованием BitmapImage и я до сих пор не знаю, как это решить. Но я нашел обходной путь, используя WriteableBitmap :

         // grid is container for image and text
        Grid grid = new Grid();

        // load your image
        StreamResourceInfo info = Application.GetResourceStream(new Uri(filename, UriKind.Relative));
        // create source bitmap for Image control (image is assumed to be alread 173x173)
        WriteableBitmap wbmp2 = new WriteableBitmap(1,1);
        wbmp2.SetSource(info.Stream);
        Image img = new Image();
        img.Source = wbmp2;
        // add Image to Grid
        grid.Children.Add(img);

        TextBlock text = new TextBlock() { FontSize = (double)Resources["PhoneFontSizeExtraLarge"], Foreground = new SolidColorBrush(Colors.White) };
        // your text goes here:
        text.Text = "HellonWorld";
        grid.Children.Add(text);

        // this is our final image containing custom text and image
        WriteableBitmap wbmp = new WriteableBitmap(173, 173);

        // now render everything - this image can be used as background for tile
        wbmp.Render(grid, null);
        wbmp.Invalidate();
  

Комментарии:

1. Спасибо, Генрих! Работает просто отлично! Случалось ли когда-нибудь с вашим кодом, что изображение загружалось не полностью и, следовательно, не отображалось? Я читал об этом, но это может быть не проблемой здесь, верно?

2. Это произошло, и я подозреваю, что здесь это тоже проблема. Иногда настройка CreateOptions ( msdn.microsoft.com/en-us/library / … ) to None помогло загрузить изображение немедленно, но, похоже, здесь это не работает. Итак, я действительно хотел бы попробовать что-то вроде BitmapImage.ForceLoadingNow() , но я не смог найти подходящий метод.

3. Ага, ладно, это плохо. Часто ли это случается? Это сбой wbmp2 или это весь макет (wbmp) для живой плитки, который не отображается? Кто-нибудь еще может нам здесь помочь?

4. Это просто происходит с BitmapImage , так что не беспокойтесь о приведенном выше коде. Он намеренно его не использует. «здесь также» означало «здесь в вашем исходном коде с использованием BitmapImage», а не «здесь выше» 😉

5. То есть вы хотите сказать, что в моем исходном коде вы заметили проблемы, но не в вашем коде?

Ответ №2:

Попробуйте это — у меня сработало:

 Uri uri = new Uri("tile.jpg", UriKind.Relative);
StreamResourceInfo sri = Application.GetResourceStream(uri);

WriteableBitmap wbm = new WriteableBitmap(173, 173);
wbm.SetSource(sri.Stream);

using (var stream = IsolatedStorageFile.GetUserStoreForApplication().CreateFile("/Shared/ShellContent/tile.png"))
{
    wbm.SaveJpeg(stream, 173, 173, 0, 100);
}

var data = new StandardTileData();
data.BackgroundImage = new Uri("isostore:/Shared/ShellContent/tile.png", UriKind.Absolute);
data.Title = "updated image";

var tile = ShellTile.ActiveTiles.First();
tile.Update(data);
  

Комментарии:

1. Спасибо, Крис, за твою помощь! В итоге я протестировал другое решение, приведенное ниже, поскольку оно немного больше походило на мой код, и я чувствовал себя более знакомым с ним (я счастливый новичок 🙂 и изо всех сил пытаюсь разобраться во всем).

Ответ №3:

Я думаю, проблема в том, что изображение загружается асинхронно и, следовательно, недоступно. Я преуспел с этим кодом:

 BitmapImage bmi = new BitmapImage();
bmi.CreateOptions = BitmapCreateOptions.None;
StreamResourceInfo streamInfo = 
     Framework.App.GetResourceStream(new Uri(@"imagesimg.png", 
          UriKind.Relative));
bmi.SetSource(streamInfo.Stream);
imgctl.Source = bmi;
  

Тем не менее, я все еще пытаюсь заставить его работать при загрузке из Xaml таким образом:

 <Image  HorizontalAlignment="Center" Width="173" Height="89" x:Name="imgctl" 
    Source="/images/lowsunrise.png"/>
  

В этом случае изображение никогда не загружается, и ни одно из событий не запускается, вероятно, потому, что оно не подключено к визуальному дереву и, следовательно, не будет отображаться.