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>

示例代码

相关推荐
Scout-leaf9 天前
WPF新手村教程(三)—— 路由事件
c#·wpf
柒.梧.12 天前
基于SpringBoot+JWT 实现Token登录认证与登录人信息查询
wpf
特立独行的猫a14 天前
基于HarmonyOS ArkTS的MVVM架构最佳实践
华为·架构·harmonyos·mvvm·最佳实战
十月南城15 天前
Flink实时计算心智模型——流、窗口、水位线、状态与Checkpoint的协作
大数据·flink·wpf
听麟17 天前
HarmonyOS 6.0+ 跨端会议助手APP开发实战:多设备接续与智能纪要全流程落地
分布式·深度学习·华为·区块链·wpf·harmonyos
@hdd17 天前
Kubernetes 可观测性:Prometheus 监控、日志采集与告警
云原生·kubernetes·wpf·prometheus
zls36536518 天前
C# WPF canvas中绘制缺陷分布map
开发语言·c#·wpf
专注VB编程开发20年18 天前
c#Redis扣款锁的设计,多用户,多台电脑操作
wpf
闲人编程19 天前
定时任务与周期性调度
分布式·python·wpf·调度·cron·定时人物·周期性
zls36536519 天前
C# WPF canvas中绘制缺陷分布map并实现缩放
开发语言·c#·wpf