Я должен отображать ~ 150 изображений при высоком разрешении (~ 5 МБ каждый) в одно и то же время. Проблема в том, что для загрузки всех этих изображений требуется много времени. Поэтому я собираюсь показать вначале изображения с низким разрешением и в то же время загружать истинные изображения с высоким разрешением в фоновом режиме. Затем, когда они готовы, переключите их.Замените изображение с низким разрешением с высоким разрешением.
ответ
Через некоторое время я закончил с этим решением. Сначала я загружать изображения с низким разрешением и добавить их к сетке:
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();
Я бы не стал беспокоиться обо всем этом коде 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"));
И таким образом вы можете загружать изображения с низким разрешением для быстрого запуска, а затем загружать версию с высоким разрешением в фоновом режиме? – Marco
Если у вас есть доступ к изображениям с низким разрешением, как указано здесь, вы можете использовать PriorityBinding в сочетании с свойством IsAsync, как указано в разделе примера [Binding.IsAsync] (http://msdn.microsoft.com/en-us/library /system.windows.data.binding.isasync(v=vs.110).aspx) – 0xBADF00D
-1. Хорошим решением было бы использовать ItemsControl с соответствующей DataTemplate и моделью представлений вместо создания и управления элементами пользовательского интерфейса в коде. Найдите в Интернете «MVVM». – Clemens
Да, я так и сделал. Я использовал ItemControl, DataTemplate и т. Д. Но у меня есть более сложное приложение FAR, чем то, что я здесь описал, и эти изображения находятся в оверлее на изображениях «base.Internalchildren», которые даже больше 150 (они ок. 2000) и отображаются с меньшим разрешением, чтобы анимация воспроизводилась плавно. – Marco
Тогда ваш ответ здесь, чтобы показать нам, как сделать что-то в BackgroundWorker? – Clemens