Как динамически изменить источник изображения в проекте Silverlight для Windows Phone 7? - PullRequest
1 голос
/ 26 сентября 2010

Я работаю над проектом Windows Phone 7 с Silverlight, и я пытаюсь показать 4 изображения в последовательности, чтобы дать пользователю ощущение короткого фильма.У меня есть 4 URL-адреса, указывающие на 4 различных изображения JPEG, и я использую элемент управления изображения, чтобы показать эти JPEG в последовательности.Я пытаюсь достичь этого путем:

private void RetrieveImages()
    {            
        image1.ImageOpened += new EventHandler<RoutedEventArgs>(image1_ImageOpened);
        frameNumber = 0;         
        gotoNextImage();
    }

    void image1_ImageOpened(object sender, RoutedEventArgs e)
    {
        System.Threading.Thread.Sleep(400);
        gotoNextImage();
    }

    private void gotoNextImage()
    {
        if (frameNumber < 4)
        {
            webBrowser1.Dispatcher.BeginInvoke(()=> {
            image1.Source = new System.Windows.Media.Imaging.BitmapImage(new Uri(cam.framesUrl[frameNumber]));
            frameNumber++;
            });
        }
        else
        {
             image1.ImageOpened -= image1_ImageOpened;
        }
    }

Но это не работает так, как ожидалось.Я уверен, что мне не хватает того, как взаимодействовать с пользовательским интерфейсом.Может кто-то указать мне верное направление?Какой лучший способ добиться этого?

Отредактировано:

Я лучше объясню, что случилось с моим кодом ... возможно, неясно, что происходит.Я не получаю никакой ошибки с моим кодом, но я также не вижу "эффект фильма".Он просто показывает 1 одиночное изображение, без перебора между коллекциями изображений.Я думаю, что это проблема с многопоточностью ... вроде как я не правильно делаю в нужном потоке, чтобы увидеть обновление пользовательского интерфейса, как и ожидалось ...

Ответы [ 3 ]

2 голосов
/ 09 августа 2011

Это швы для лучшей работы.

xaml

<UserControl
    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"
    x:Class="YourNamspace.YourClass"
    d:DesignWidth="24" 
    d:DesignHeight="24">

    <Grid x:Name="LayoutRoot">
        <Image Name="YourImageName" Stretch="Fill" Source="YourPath" ImageOpened="onImageOpened"/>
    </Grid>
</UserControl>

C #

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Threading;

namespace YourNameSpace
{
    public partial class YourClass : UserControl
    {
        public int FirstImageIndex = 1;
        public int LastImageIndex = 1000;
        public int CurrentImageIndex = 1;

        public YourClass() 
        {
            InitializeComponent();
        }

        private void onImageOpened(object sender, System.Windows.RoutedEventArgs e) 
        {
            Thread.Sleep(1000);
            CurrentImageIndex = ( CurrentImageIndex == LastImageIndex ) ? FirstImageIndex : CurrentImageIndex++;
            YourImageName.Source = new BitmapImage(new Uri("Your/path/to/image"+CurrentImageIndex+".jpg"), UriKind.RelativeOrAbsolute);
        }
    }
}

Надеюсь, это поможет.Я довольно новичок в Silverlight.

0 голосов
/ 26 сентября 2010

Хорошо, я понял это, и я думаю, что я также нашел хорошее решение :) ИМХО

Я в основном привязал Image.source к свойствам моего класса (теперь это расширение INotifyPropertyChanged). Но это дало мне некоторую проблему с транскрипцией между изображениями: поскольку они были загружены из Интернета, между изображениями появлялись чёрные изображения ... и только в первый раз (я зацикливаюсь на наборе из 4 изображений) похоже, что видео повторяется), потому что после этого изображения кэшируются.

Итак, что я сделал, так это кешировал изображения в первый раз, не отображая правильный элемент управления изображением, а вместо этого отображая другой элемент управления изображением (или что-то еще), который говорит пользователю «Я загружаю». Для обработки этого сценария я создал пользовательское событие:

public delegate void FramesPrefetchedEventHanlder();
public event FramesPrefetchedEventHanlder FramesPrefetched;

Теперь давайте посмотрим на метод RetrieveImages:

private void RetrieveImages()
{
    frameNumber = 0;
    currentCycle = 0;
    // set e very short interval, used for prefetching frames images
    timer.Interval = new TimeSpan(0, 0, 0, 0, 10);
    timer.Tick += (sender, e) => gotoNextImage();
    // defines what is going to happen when the prefetching is done
    this.FramesPrefetched += () => 
    {
        // hide the "wait" image and show the "movie" one
        imageLoading.Opacity = 0;
        image1.Opacity = 1;
        // set the timer with a proper interval to render like a short movie
        timer.Interval = new TimeSpan(0, 0, 0, 0, 400);
    };

    // when a frame is loaded in the main Image control, the timer restart
    image1.ImageOpened += (s, e) =>
    {
        if (currentCycle <= cycles) timer.Start();
    };
    // start the loading (and showing) frames images process
    gotoNextImage();            

}

Хорошо, теперь нам нужно выполнить пошаговую загрузку изображения и сообщить, когда мы закончили фазу предварительной выборки:

private void gotoNextImage()
{
    timer.Stop();
    if (frameNumber < 4)
    {
        CurrentFrame = new System.Windows.Media.Imaging.BitmapImage(new Uri(cam.framesUrl[frameNumber]));
        frameNumber++;
    }
    else
    {
        // repeat the frame's sequence for maxCycles times
        if (currentCycle < maxCycles)
        {
            frameNumber = 0;
            currentCycle++;
            // after the first cycle through the frames, raise the FramesPrefetched event
            if (currentCycle == 1)
            {
                FramesPrefetchedEventHanlder handler = FramesPrefetched;
                if (handler != null) handler();
            }
            // step over to next frame
            gotoNextImage();
        }
    }
}

Это прекрасно работает для меня ... но, поскольку я новичок в разработке Silverlight и Windows Phone 7, любые предложения по улучшению приветствуются.

0 голосов
/ 26 сентября 2010

Пока что лучший способ - определить изображение как ресурс.Через конвертер установите источник изображения.

Но ваш код также должен работать нормально.Попробуйте установить UriKind.RelativeOrAbsolute, возможно, это должно помочь.Потому что это самая распространенная область, в то время как установка источника изображения вызывает проблему

HTH

...