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>

示例代码

相关推荐
△曉風殘月〆2 小时前
WPF MVVM入门系列教程(二、依赖属性)
c#·wpf·mvvm
.net开发9 小时前
WPF怎么通过RestSharp向后端发请求
前端·c#·.net·wpf
九鼎科技-Leo9 小时前
WPF 中 NavigationWindow 与 Page 的继承关系解析
wpf
SongYuLong的博客10 小时前
C# WPF 打印机
wpf
就是有点傻10 小时前
WPF中的转换器
wpf
.net开发17 小时前
WPF使用prism框架发布订阅实现消息提示
c#·.net·wpf
那少年已不再......21 小时前
C#WPF使用CommunityToolkit.Mvvm库
开发语言·c#·wpf
SEO-狼术1 天前
Syncfusion Essential Studio WPF 2024 Crack
wpf
Olivia_vivi2 天前
WPF XAML
ui·wpf
就是有点傻2 天前
WPF中如何简单的使用CommunityToolkit.Mvvm创建一个项目并进行 增删改查
wpf