Wpf Image Control会阻止该文件

我有一个带按钮的简单Window ,当我点击Button时会打开第二个Window 。 第二个Window有一个Image控件,它显示一个.png文件。 因此,如果我使用FileObject属性进行Binding就可以了,我可以从File Explorer删除文件。 但是,如果我使用FileName属性进行Binding我无法从File Explorer删除文件,我得到操作系统exception。 即使我明确调用GC ,即使关闭第二个窗口,我也无法做到这一点。 FileName属性有什么问题? 有任何想法吗?

赢7,净4.0

窗口1

  

窗口2

    public partial class Window2 : Window { public Window2() { InitializeComponent(); DataContext = this; FileName = "D:/pdf/myfile.png"; Closing += Window2_Closing; } public String FileName { get; set; } public Object FileObject { get { if (String.IsNullOrEmpty(FileName)) return null; if (!File.Exists(FileName)) return null; var ms = new MemoryStream(); var bi = new BitmapImage(); using (var fs = new FileStream(FileName, FileMode.Open, FileAccess.Read)) { fs.CopyTo(ms); bi.BeginInit(); bi.StreamSource = ms; bi.EndInit(); } return bi; } } void Window2_Closing(Object sender, System.ComponentModel.CancelEventArgs e) { GC.Collect(); GC.WaitForPendingFinalizers(); } } 

当您将Image.Source属性绑定到Uri(或从内部创建Uri的字符串)时,WPF使用内置类型转换器从Uri创建BitmapFrame

如果Uri包含本地文件的路径,则BitmapFrame会保持文件处于打开状态,只要它存在即可。 这可能比您在应用程序中实际使用的时间更长,因为它可能由WPF缓存。

当您需要能够删除从中加载图像的文件时,应始终使用FileObject方法,但它应如下所示:

 public ImageSource Image { get { ... var bi = new BitmapImage(); using (var fs = new FileStream(FileName, FileMode.Open, FileAccess.Read)) { bi.BeginInit(); bi.CacheOption = BitmapCacheOption.OnLoad; bi.StreamSource = fs; bi.EndInit(); } return bi; } } 

或者像这样:

 public ImageSource Image { get { using (var fs = new FileStream(FileName, FileMode.Open, FileAccess.Read)) { return BitmapFrame.Create( fs, BitmapCreateOptions.None, BitmapCacheOption.OnLoad); } } } 

或者使用绑定转换器绑定到FileName属性,该绑定转换器创建BitmapImage或BitmapFrame,如上所示。

使用这段代码,我稍后会解释是什么问题。

 var image = new BitmapImage(); image.BeginInit(); image.CacheOption = BitmapCacheOption.OnLoad; image.CreateOptions = BitmapCreateOptions.IgnoreImageCache; image.UriSource = new Uri(FilePath); image.EndInit(); return image;