2014-09-25 3 views
1

Я должен отображать ~ 150 изображений при высоком разрешении (~ 5 МБ каждый) в одно и то же время. Проблема в том, что для загрузки всех этих изображений требуется много времени. Поэтому я собираюсь показать вначале изображения с низким разрешением и в то же время загружать истинные изображения с высоким разрешением в фоновом режиме. Затем, когда они готовы, переключите их.Замените изображение с низким разрешением с высоким разрешением.

ответ

-1

Через некоторое время я закончил с этим решением. Сначала я загружать изображения с низким разрешением и добавить их к сетке:

foreach (var extElem in ElemList) 
{ 
    IdImage img = new IdImage(); 
    img.Id = extElem.ImageID; 
    img.CollectionId = extElem.CollectionID; 
    BitmapImage bi = new BitmapImage(); 
    bi.BeginInit(); 
    bi.UriSource = new Uri(extElem.Url, UriKind.Absolute); 
    bi.DecodePixelWidth = 200; //If you want to further reduce the image size (and load time) 
    bi.EndInit(); 
    img.Source = bi; 
    grid.Children.Add(img); 

    _imgList.Add(img); 
} 

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

BackgroundWorker bgw = new BackgroundWorker(); 
bgw.DoWork += (s, args) => 
{ 
    int i = 0; 
    foreach (var extElem in _imgList) 
    { 
     String url = extElem.HighResImageUri; 
     Image img = _imgList.ElementAt(i); 

     BitmapImage bi = new BitmapImage(); 
     bi.BeginInit(); 
     bi.UriSource = new Uri(url, UriKind.Absolute); 
     bi.EndInit(); 
     bi.Freeze(); 

     Dispatcher.BeginInvoke((Action)(() => 
     { 
      img.Source = bi; 
     })); 
    } 
    i++; 
} 
bgw.RunWorkerAsync(); 
+0

-1. Хорошим решением было бы использовать ItemsControl с соответствующей DataTemplate и моделью представлений вместо создания и управления элементами пользовательского интерфейса в коде. Найдите в Интернете «MVVM». – Clemens

+0

Да, я так и сделал. Я использовал ItemControl, DataTemplate и т. Д. Но у меня есть более сложное приложение FAR, чем то, что я здесь описал, и эти изображения находятся в оверлее на изображениях «base.Internalchildren», которые даже больше 150 (они ок. 2000) и отображаются с меньшим разрешением, чтобы анимация воспроизводилась плавно. – Marco

+0

Тогда ваш ответ здесь, чтобы показать нам, как сделать что-то в BackgroundWorker? – Clemens

0

Я бы не стал беспокоиться обо всем этом коде C#. Вместо этого я бы просто использовал элемент управления коллекцией и коллекцию путей к файлам. Попробуйте этот пример:

<ListBox ItemsSource="{Binding FilePaths}"> 
    <ListBox.ItemsPanel> 
     <ItemsPanelTemplate> 
      <WrapPanel /> 
     </ItemsPanelTemplate> 
    </ListBox.ItemsPanel> 
    <ListBox.ItemTemplate> 
     <DataTemplate> 
      <Image Source="{Binding}" Width="250" Stretch="Uniform" /> 
     </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 

...

private ObservableCollection<string> filePaths = new ObservableCollection<string>(); 
public ObservableCollection<string> FilePaths 
{ 
    get { return filePaths; } 
    set { filePaths = value; NotifyPropertyChanged("FilePaths"); } 
} 

...

FilePaths = new ObservableCollection<string>(Directory.GetFiles(
    Environment.GetFolderPath(Environment.SpecialFolder.MyPictures), "*.png")); 
+0

И таким образом вы можете загружать изображения с низким разрешением для быстрого запуска, а затем загружать версию с высоким разрешением в фоновом режиме? – Marco

+0

Если у вас есть доступ к изображениям с низким разрешением, как указано здесь, вы можете использовать PriorityBinding в сочетании с свойством IsAsync, как указано в разделе примера [Binding.IsAsync] (http://msdn.microsoft.com/en-us/library /system.windows.data.binding.isasync(v=vs.110).aspx) – 0xBADF00D