2009-11-02 94 views
3

我在WPF中有一个问题,在应用程序的另一部分尝试写入图像之前,窗口没有在关闭之后释放它的背景图像文件上的文件锁定。删除一个窗口的背景图像WPF

所以作为一个例子;说我有一个WPF应用程序由3个窗口,1个“菜单”选择窗口和其他2个组成。这两个窗口创建一个ImageBrush使用BitmapImage作为ImageSource相同图像)。

窗口A中有一个按钮,当按下时,通过将它们复制每遍用作原始ImageSource该文件并创建一个新的ImageBrush和设置Window.Background到新刷的可用背景图像周期。

窗口B只是使用ImageBrush来绘制Window.Background

如果窗口A启动,背景切换,关闭,然后启动窗口B,一切都很好。

如果窗口B启动,关闭,然后窗口A启动并且背景切换它崩溃。试图切换背景会抛出IOException,因为:

“该进程无法访问文件'C:\ Backgrounds \ Background.png',因为它正在被另一个进程使用。”

因此,窗户B仍然必须以某种方式持有它!?我试图做一个GC.Collect(); GC.WaitForPendingFinalizers();看看是否能治愈这个问题,但事实并非如此。

回答

4

托马斯给出的答案是正确的,效果很好,如果你有一个文件路径,不想要缓存位图,而不想使用XAML。

但是还应该提到的BitmapImage有一个内置的方式,通过设置BitmapCacheOption立即加载位图:

BitmapImage img = new BitmapImage { CacheOption = BitmapCacheOption.OnLoad }; 
img.BeginInit(); 
img.UriSource = imageUrl; 
img.EndInit(); 

<BitmapImage CacheOption="OnLoad" UriSource="..." /> 

这将立即并明确加载位图关闭流,就像使用FileStream一样,但有几点区别:

  • 它可以和任何Uri一起使用,例如pack:// Uri。
  • 它可以直接从XAML使用
  • 位图被缓存在位图缓存中,所以未来使用相同的Uri将不会进入磁盘。在您的特定应用中,这可能是一件坏事,但对于其他用途,它可能是一个理想的功能。
+0

这是灿烂的,谢谢你们俩! – Siyfion 2009-11-02 18:39:09

2

我想你是直接从文件加载图像,像这样?

BitmapImage img = new BitmapImage(); 
img.BeginInit(); 
img.UriSource = imageUrl; 
img.EndInit(); 

试着从流中加载它;这样你可以像照顾自己关闭流被加载,从而使文件未锁定:

BitmapImage img = new BitmapImage(); 
using (FileStream fs = File.OpenRead(imageFilePath) 
{ 
    img.BeginInit(); 
    img.StreamSource = fs; 
    img.EndInit(); 
} 
+0

其实它比这还糟糕:backgroundBrush.ImageSource = new BitmapImage(new Uri(Constants。ShellLocation + @“Background \ TempBkgrnd.png”,UriKind.Absolute)); – Siyfion 2009-11-02 14:23:16