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>

示例代码

相关推荐
界面开发小八哥8 小时前
界面组件DevExpress WPF中文教程:Grid - 如何显示和隐藏列?
wpf·界面控件·devexpress·ui开发·.net9
虚假程序设计9 小时前
python用 PythonNet 从 Python 调用 WPF 类库 UI 用XAML
python·ui·wpf
落落落sss11 小时前
MongoDB
数据库·windows·redis·mongodb·微服务·wpf
蒋劲豪12 小时前
WPF项目暴露WebApi接口;WinForm项目暴露WebApi接口;C#项目暴露WebApi接口;
开发语言·c#·wpf
狮歌~资深攻城狮1 天前
未来已来:HBase的新功能与发展趋势展望
大数据·wpf·hbase
界面开发小八哥2 天前
界面控件DevExpress WPF v24.2新版亮点:支持.NET 9
.net·wpf·界面控件·devexpress·ui开发·用户界面
九鼎科技-Leo3 天前
WPF快速创建DeepSeek本地自己的客户端-基础思路版本
wpf
MasterNeverDown4 天前
WPF 中为 Grid 设置背景图片全解析
大数据·hadoop·wpf
苏克贝塔4 天前
WPF8-常用控件
wpf
积跬步---行千里4 天前
记录一次WPF程序进程挂起问题
mongodb·wpf