2013-06-21 4 views
0

Я пытаюсь сделать массив изображений для установки на мой контроль изображения. Существует цикл, который будет проходить через изображения и отображать каждую секунду, пока не остановится на случайном изображении.Как создать массив типа ImageSource?

Мой подход: Я сохранил пути изображений в строке, которую затем помещаю в массив. Внутри моего цикла я создаю новый ImageSource и определяю его по элементу массива, который поворачивается, чтобы он отображался. Я считаю, что причина, по которой моя программа не будет работать, заключается в том, что ImageSource не может вытащить изображение из файла и достаточно быстро установить его на контроллер изображения, прежде чем спеть поток, чтобы изображение отображалось на секунду.

Вот мой код (предположим, что строки являются правильные пути, и я попытался несметное Thread.Sleep() переменные)

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

Будет ли создавать массив типа ImageSource, чтобы изображения «под рукой» отображались быстрее? Может ли WPF поддерживать скорость, необходимую для получения и установки изображений в контроллер изображения? Может ли моя спящая нить выполняться слишком быстро, прежде чем изображение будет установлено и отображено?

private void ButtonClick(object sender, RoutedEventArgs e) 
{ 
    String[] picArray = new String[] { kristen, justin, brandon, sarah, miles, nina };  
    int i = 0;  
    x = rnd.Next(0,5); 

     while (i < rnd.Next(10,50)) 
     { 
      ImageSource _currentPic = new BitmapImage(new Uri(picArray[x]));        
      cImage.Source = _currentPic; 
      if (x == 5) 
       x = 0; 
      else 
       x++; 

      Thread.Sleep(100); 
      i++; 
     } 

    } 

Петля останавливается на «случайной» точке массива, чтобы рандомизировать, чей образ заканчивается.

Спасибо заранее.

+0

'ImageSource []', это, безусловно, будет быстрее зависеть от того, как вы их храните, если вы просто держите их локальными в этом методе, то это займет больше времени – Sayse

+0

Не связано с вашим вопросом, но кажется, что вы «Выполняем некоторые длительные операции с потоком пользовательского интерфейса, особенно с вызовом« Thread.Sleep() ». Возможно, вы захотите это изменить. – Steve

+0

Я попытался использовать ImageSource [], но это не позволило мне создать и массив этого типа. Что касается thread.sleep(), я не задумывался над этим. Будет ли использование таймера более эффективным? – meisenman

ответ

0

Если это форма нормальные окна, вы могли бы использовать

this.Refresh() 

непосредственно перед Sleep() для обновления экрана (отображение текущего изображения).

Однако, поскольку это WPF, вы должны вывести этот цикл в отдельный поток (например, BackgroundWorker). Другим вариантом было бы установить Timer и просто вызывать содержимое цикла каждый раз, когда выполняется таймер.

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

+0

В классе WPF Window такого метода нет. Я имею в виду 'Control.Refresh' в WinForms. – Clemens

+0

Мне нравится идея обновления, чтобы отобразить текущее изображение. Я, в конце концов, добавляю новый поток, когда у моей программы есть функции, которые я мог бы использовать, пока она работает через цикл изображения. – meisenman

+0

Бах! Да, это старые формы Windows, а не WPF. Попадая в WPF, проблема усложняется. (Работа над пересмотром) – Richard

0

Ваш код не создает новые темы. Это не ошибка WPF, что ваш пользовательский интерфейс замерзнет.

Выполнение Thread.Sleep() в теме пользовательского интерфейса просто заставило ваше приложение замораживаться, независимо от того, является ли WPF или нет.

Кроме того, в WPF не требуется никаких изменений. В WPF есть DataBinding, что устраняет необходимость всех этих ужасных хаков манипулировать пользовательским интерфейсом в процедурном коде, к которому вы могли бы привыкнуть, если вы привыкли к случайным бесполезным фреймворкам динозавра, таким как winforms.

Вот правильный способ делать то, что вы описываете в WPF:

<Window x:Class="MiscSamples.SlideShowSample" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="SlideShowSample" Height="300" Width="300"> 
    <Image Source="{Binding ImageSource}"/> 
</Window> 

Код За:

public partial class SlideShowSample : Window 
{ 
    public SlideShowSample() 
    { 
     InitializeComponent(); 
     DataContext = new SlideShowViewModel(); 
    } 
} 

ViewModel:

public class SlideShowViewModel:PropertyChangedBase 
{ 
    public const string SourceURL = "http://lorempixel.com/400/200/sports/"; 

    private string _imageSource; 
    public string ImageSource 
    { 
     get { return _imageSource; } 
     set 
     { 
      _imageSource = value; 
      OnPropertyChanged("ImageSource"); 
     } 
    } 

    private System.Threading.Timer _slideShowTimer; 
    private System.Random _random = new Random(); 

    public SlideShowViewModel() 
    { 
     _slideShowTimer = new Timer(x => OnTimerTick(), null, 1000, 3000); 
    } 

    private void OnTimerTick() 
    { 
     ImageSource = SourceURL + _random.Next(1, 10).ToString(); 
    } 
} 

PropertyChangedBase (MVVM Вспомогательный класс) :

public class PropertyChangedBase:INotifyPropertyChanged 
    { 
     public event PropertyChangedEventHandler PropertyChanged; 

     protected virtual void OnPropertyChanged(string propertyName) 
     { 
      Application.Current.Dispatcher.BeginInvoke((Action) (() => 
                    { 
                     PropertyChangedEventHandler handler = PropertyChanged; 
                     if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName)); 
                    })); 
     } 
    } 
  • Посмотрите, как мой код не управляет каким-либо элементом пользовательского интерфейса.
  • Мой образец загружает изображения из Интернета, поэтому он должен быть намного быстрее, если вы используете локально сохраненные изображения.
  • Обратите внимание, что пользовательский интерфейс не замерзает в любое время. Есть еще небольшая задержка, потому что фактические данные изображения загружаются из Интернета. Эта загрузка выполняется в потоке пользовательского интерфейса, поэтому вы можете улучшить свой образец для загрузки async, но поскольку вы используете локально сохраненные изображения, это не имеет значения.
+0

Благодарим вас за то, что вы показали мне такой продуманный образец и выяснили множество проблем, связанных с моим подходом к динозавру. Я просто получил задание на работу, поэтому я проверю код, как только закончу. На самом деле я действительно не попал в официальные модели взглядов и, возможно, нуждался в помощи с некоторыми простыми разъяснениями о том, где находятся классы или как их модифицировать для удовлетворения моих точных потребностей. Еще раз спасибо – meisenman

+0

Я только что протестировал этот код. У меня есть проблемы с публикацией SlideShowViewModel(). Более конкретно, он сказал, что таймер не будет принимать 4 параметра. – meisenman

+1

@muffinMan 'Timer' - это' System.Threading.Timer', проверьте свои данные. –