相信很多WPF 的开发,应该都很多用到 Image 这个控件来显示图片。这个图片的来源可以来自各种各样的方式获取到。
我们的组内白板、批注的扫码的功能也用到这个去生成二维码,生成后,二维码显示不出来,由于触发到了全局捕获,界面又没有崩溃,遇到了好几个坑,记录一下。
开始看代码:
private async void MainWindow_Loaded(object sender, RoutedEventArgs e){ImageSource imageSource = null;//用来模拟时间回调后,去获取图片资源Task.Run(() =>{imageSource = BitmapImageToBitmap();});await Task.Delay(2000);MyImage.Source = imageSource;}public static BitmapImage BitmapImageToBitmap(){BitmapImage bitmapImage = new BitmapImage(new Uri(@"C:\Users\a\Desktop\祁厅长壁纸.png", UriKind.RelativeOrAbsolute));return bitmapImage;}
我们在工作线程上去获取ImageSource (模拟事件回调),然后在Loaded 事件中给 Image控件的Source 赋值。
其实细看一下ImageSource 的定义,是继承了 Animatable,而Animatable继承了Freezable,Animatable继承了Freezable,Freezable继承了DependencyObject
这也就是说,ImageSource 的创建和使用必须是用一个线程下的,不然就会存在以上的异常报错
Freezable.Freeze Method (System.Windows) | Microsoft Learn
解决方法:
BitmapImage 在获取图片的时候,提供了Freenze()的方法
public static BitmapImage BitmapImageToBitmap() {BitmapImage bitmapImage = new BitmapImage(new Uri(@"C:\Users\a\Desktop\祁厅长壁纸.png", UriKind.RelativeOrAbsolute));if (bitmapImage.CanFreeze){bitmapImage.Freeze();}return bitmapImage; }
加上就可以正常显示了,效果如下: