WPF MVVM模式图片占用问题

在很久以前就遇到这个问题,当时解决了,这过了几年,又遇到这个问题,这里做个总结,防止下次再踩坑了,也顺便帮助一下同样遇到这个问题的朋友 。

出现这个问题的原因是:将文件路径绑定到Image的Source上

ImageSource 属性实际上需要的是一个ImageSource类型,但是可以直接将string(文件路径)绑定到Source上。我查了一下WPF的源码,并没有找到是如何在绑定时将string转换成ImageSource。不过原理应该还是下面这样,所以会导致图片文件占用。

复制代码
Image image = new Image();
image.BeginInit();
image.UriSource = new Uri(xxx);
image.EndInit();

下面看一下文件占用的情况:

如下:

MainWindow.xaml

复制代码
1  <Grid>
2         <Image Source="{Binding ImagePath}"/>
3  </Grid>

MainWindow.xaml.cs

复制代码
 1  public partial class MainWindow : Window
 2     {
 3         public MainWindow()
 4         {
 5             InitializeComponent();
 6 
 7             var viewModel = new MainWindowViewModel();
 8             this.DataContext = viewModel;
 9 
10             //假设D盘下有个d.jpeg文件
11             viewModel.ImagePath = @"D:\\d.jpeg";
12         }
13     }

MainWindowViewModel.cs

复制代码
 1 public class MainWindowViewModel : INotifyPropertyChanged
 2     {
 3         private string imagePath;
 4 
 5         public string ImagePath
 6         {
 7             get => imagePath;
 8             set
 9             {
10                 imagePath = value;
11                 RaiseChanged("ImagePath");
12             }
13         }
14 
15         public event PropertyChangedEventHandler PropertyChanged;
16 
17         public void RaiseChanged(string propertyName)
18         {
19             PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
20         }
21     }

运行后可以看到D盘下的d.jpeg文件是不能删除的

解除文件占用的原理是在初始化时,就将图片加载到内存中,如下:

复制代码
1 image.BeginInit();
2 image.CacheOption = BitmapCacheOption.OnLoad;
3 image.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
4 image.UriSource = new Uri(path, UriKind.Absolute);
5 image.EndInit();

了解原理后,我们就可以建立一个ImageSourceConvert来解除文件占用的问题

复制代码
 1 public class ImageSourceConverter : IValueConverter
 2     {
 3         public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
 4         {
 5             if (value == null)
 6                 return DependencyProperty.UnsetValue;
 7 
 8             var path = value.ToString();
 9             BitmapImage image = new BitmapImage();
10             image.BeginInit();
11             image.CacheOption = BitmapCacheOption.OnLoad;
12             image.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
13             image.UriSource = new Uri(path, UriKind.Absolute);
14             image.EndInit();
15             return image;
16         }
17 
18         public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
19         {
20             throw new NotImplementedException();
21         }
22     }

MainWindow.xaml

复制代码
1  <Window.Resources>
2         <local:ImageSourceConverter x:Key="ImageSourceConverter"/>
3     </Window.Resources>
4     <Grid>
5         <!--<Image Source="{Binding ImagePath}"/>-->
6         <Image Source="{Binding ImagePath,Converter={StaticResource ImageSourceConverter}}"/>
7     </Grid>

示例代码

相关推荐
精明的身影1 天前
深入WPF -- Dispatcher(补)
wpf
云中飞鸿2 天前
该如何进行WPF界面设计
wpf
云中飞鸿3 天前
WPF分哪几块
wpf
newbe365243 天前
我们如何使用 impeccable 优化前端界面设计与实现稳定性
前端·人工智能·分布式·github·aigc·wpf
Chris _data21 天前
WPF 学习第三天 — Modbus RTU 串口通信
hadoop·学习·wpf
Peter(阿斯拉)21 天前
[Android]_[中级]_[如何创建MVVM架构原型]
android·java·架构·mvvm·viewmodel
布吉岛的石头22 天前
Java 程序员第 43 阶段05:微服务整合大模型,跨服务调用架构设计实战,Seata分布式事务实战
wpf
步步为营DotNet22 天前
基于.NET Aspire 实现云原生应用的高效监控与可观测性
云原生·.net·wpf
芒鸽22 天前
HarmonyOS 分布式开发实战:设备协同、数据共享与跨设备迁移
分布式·wpf·harmonyos
Volunteer Technology22 天前
Flink状态管理与容错(二)
大数据·flink·wpf