2009-11-02 3 views
3

У меня возникла проблема с WPF, когда окно не освобождает файловую блокировку в файле фонового изображения после закрытия, прежде чем другая часть приложения попытается записать на изображение.Удаление фонового изображения окна WPF

Так, например, У меня есть приложение WPF, состоящее из 3 окон, 1 "меню" и 2 других. Оба окна создают ImageBrush, используя BitmapImage как ImageSource (то же изображение).

Окно А имеет кнопку, которая при нажатии, циклически доступных фоновых изображений путем копирования их каждый поверх файла, используемого в качестве исходного 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

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 (новый Uri (константы.ShellLocation + @ "Background \ TempBkgrnd.png", UriKind.Absolute)); – Siyfion

Смежные вопросы