删除窗口的背景图像WPF

时间:2009-11-02 14:09:52

标签: wpf image background ioexception

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

以此为例;说我有一个WPF应用程序,包括3个窗口,1个“菜单”选择窗口和另外2个。这两个窗口使用ImageBrush作为BitmapImage相同的图片)创建ImageSource

窗口A有一个按钮,当按下该按钮时,通过将可用背景图像复制到用作原始ImageSource的文件并创建新ImageBrush并设置Window.Background来循环显示这些图像。到新画笔。

Window B只使用ImageBrush绘制Window.Background

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

如果Window B启动,关闭,则启动Window A并且背景切换它崩溃。尝试切换背景会引发IOException因为:

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

所以Window B仍然必须以某种方式抓住它!?我试过做一个GC.Collect(); GC.WaitForPendingFinalizers();看看是否可以解决这个问题,但事实并非如此。

2 个答案:

答案 0 :(得分:4)

Thomas给出的答案是正确的,如果您有文件路径,不想缓存位图,并且不想使用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将不会进入磁盘。在您的特定应用中,这可能是一件坏事,但对于其他用途,它可能是一个理想的功能。

答案 1 :(得分: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();
}