2009-11-02 9 views
3

Je rencontre un problème dans WPF lorsqu'une fenêtre ne libère pas son verrou de fichier sur le fichier image d'arrière-plan après la fermeture, avant qu'une autre partie de l'application tente d'écrire sur l'image.Suppression de l'image d'arrière-plan d'une fenêtre WPF

À titre d'exemple; disons que j'ai une application WPF composée de 3 fenêtres, 1 fenêtre de sélection "menu" et 2 autres. Les deux fenêtres créent un ImageBrush en utilisant un BitmapImage comme le ImageSource (le même image).

fenêtre A a un bouton qui lorsqu'il est pressé, fait défiler les images de fond disponibles en les copiant sur chaque fichier utilisé comme ImageSource et la création d'une nouvelle ImageBrush et le réglage de la Window.Background à la nouvelle brosse originale. La fenêtre B utilise simplement ImageBrush pour dessiner le Window.Background.

Si la fenêtre A est lancée, que les arrière-plans sont activés, fermés et que la fenêtre B est lancée, tout va bien.

Si la fenêtre B est lancée, fermée, la fenêtre A est lancée et les arrière-plans l'activent. "Le processus ne peut pas accéder au fichier 'C: \ Backgrounds \ Background.png' car il est utilisé par un autre processus." Le processus ne peut pas accéder au fichier 'C: \ Backgrounds \ Background.png'.

Donc, la fenêtre B doit encore se tenir en quelque sorte !? J'ai essayé de faire un GC.Collect(); GC.WaitForPendingFinalizers(); pour voir si cela résout le problème mais ce n'est pas le cas.

Répondre

4

La réponse Thomas a donné est correct, et fonctionne bien si vous avez un chemin de fichier, ne pas voulez mettre en cache l'image bitmap et ne pas utiliser XAML.

Cependant, il convient également de mentionner que BitmapImage a une façon intégrée pour charger le bitmap immédiatement en mettant BitmapCacheOption:

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

ou

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

Cela va charger immédiatement et explicitement le bitmap fermez le flux, tout comme l'utiliserait un FileStream, mais avec plusieurs différences:

  • Il fonctionnera avec n'importe quel Uri, comme un pack: // Uri.
  • Il peut être utilisé directement à partir de XAML
  • Le bitmap est mis en cache dans le cache de bitmap, de sorte que l'utilisation future du même Uri ne se rendra pas sur le disque. Dans votre application particulière, cela peut être une mauvaise chose, mais pour d'autres utilisations, cela peut être une caractéristique souhaitable.
+0

C'est génial, merci les deux! – Siyfion

2

Je suppose que vous chargez l'image directement à partir du fichier, comme ça?

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

Essayez de le charger à partir d'un flux à la place; De cette façon vous pouvez fermer le flux vous-même après l'image est chargée, de sorte que le fichier est verrouillé

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

En fait, c'était pire que cela: backgroundBrush.ImageSource = new BitmapImage (new Uri (Constantes.ShellLocation + @ "Background \ TempBkgrnd.png", UriKind.Absolute)); – Siyfion