MSDN.WhiteKnight - Stack Overflow answers
Ответ на "WPF невозможно обновить элемент окна"
Answer 868062
Объект ImageSource обычно может использоваться только из потока, в котором он был создан. Необходимо вызвать
image.Freeze()
после завершения загрузки изображения (т.е., вызоваimage.EndInit()
), если вы хотите использовать его в других потоках (после этого он станет неизменяемым). См. Freezable Objects Overview
Также, если ImageSource указывает на HTTP URL, его загрузка осуществляется асинхронно. Поэтому перед вызовом Freeze нужно дождаться его загрузки, при этом выполняя обработку событий WPF в потоке. Для этого понадобится вспомогательный метод:
using System.Windows.Threading; public static void DoWpfEvents() { DispatcherFrame frame = new DispatcherFrame(); Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background, new DispatcherOperationCallback((f) => { ((DispatcherFrame)f).Continue = false; return null; }), frame); Dispatcher.PushFrame(frame); }
Ожидание можно выполнить так:
BitmapImage image = new BitmapImage(); image.BeginInit(); image.UriSource = new Uri("http://example.com/image_" + slideId.ToString() + ".png"); image.CacheOption = BitmapCacheOption.OnLoad; image.EndInit(); while (image.IsDownloading) { DoWpfEvents(); Thread.Sleep(100); } image.Freeze();
Но лучше воспользоваться советом из соседнего ответа и создать изображение в основном потоке (он на самом деле работает, если все сделать правильно):
BitmapImage image=null; Application.Current.Dispatcher.Invoke(() => { image = new BitmapImage(); image.BeginInit(); image.UriSource = new Uri("http://example.com/image_" + slideId.ToString() + ".png"); image.EndInit(); });
Content is retrieved from StackExchange API.
Auto-generated by ruso-archive tools.