Самый простой способ - просто установить свойство Binding.IsAsync
следующим образом:
<Image ImageSource="{Binding propertyThatComputesImageSource, IsAsync=true}" />
Каждый доступ к propertyThatComputesImageSource
будет осуществляться из потока ThreadPool. Если поток создает изображение с помощью ImageCacheOptions.OnLoad, он будет блокироваться до тех пор, пока изображение не будет загружено. Таким образом, пользовательский интерфейс сразу запустится, и изображения будут загружены в фоновом режиме и появятся, когда они станут доступны.
Binding.IsAsync
- это хорошее решение для десяти или двадцати изображений, но, вероятно, это не очень хорошее решение, если у вас есть сотни изображений и задержка загрузки велика, так как вы можете получить сотни потоков. В этом случае загрузите изображения вне привязки данных полностью, используя ThreadPool напрямую:
ThreadPool.QueueUserWorkItem((state) =>
{
foreach(var model in _models.ToArray())
model.ImageSource = LoadOneImage(model.ImageUrl);
});
Это может потребоваться расширить с помощью Dispatcher.Invoke или двух, если свойствами модели являются DependencyProperty, поскольку к ним нельзя получить доступ из отдельного потока.
Эту технику можно расширить, чтобы порождать фиксированное количество рабочих для загрузки изображений и разбивать работу между ними, чтобы происходило несколько загрузок изображений, но количество одновременных загрузок ограничено, поэтому вы не получите сотни резьб.