7

I'm trying to delete a Image file in WPF, but WPF locks the file.

    <Image Source="C:\person.gif" x:Name="PersonImage">
        <Image.ContextMenu>
            <ContextMenu>
                <MenuItem Header="Delete..." x:Name="DeletePersonImageMenuItem" Click="DeletePersonImageMenuItem_Click"/>
            </ContextMenu>
        </Image.ContextMenu>
    </Image>

And the Click handler just looks like this:

    private void DeletePersonImageMenuItem_Click(object sender, RoutedEventArgs e)
    {
        System.IO.File.Delete(@"C:\person.gif");
    }

But, when I try to delete the file it is locked and cannot be removed.

Any tips on how to delete the file?

Frode Lillerud
  • 7,324
  • 17
  • 58
  • 69
  • Possible duplicate of [Cannot delete file used by some other process](https://stackoverflow.com/questions/12799931/cannot-delete-file-used-by-some-other-process) – Coden Jul 10 '18 at 11:34

5 Answers5

10

My application Intuipic deals with this by using a custom converter that frees the image resource. See the code here.

Kent Boogaart
  • 175,602
  • 35
  • 392
  • 393
3

Using code behind, you can use the cache option BitmapCacheOption.OnLoad:

                BitmapImage bi = new BitmapImage();
                bi.BeginInit();
                bi.CacheOption = BitmapCacheOption.OnLoad;
                bi.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
                bi.UriSource = new Uri(PathToImage);
                bi.EndInit();
                PersonImage.Source = bi;

Because I struggled to find it, I will add that if you want to replace the deleted image dynamically, you need to add the argument BitmapCreateOptions.IgnoreImageCache.

Magellan
  • 93
  • 7
1

First Remove it from the PersonImage control then delete the image. Hope that will help. As you have assigned to the control in source, and remove it without unassigning the control source.

PersonImage.Source = null; 
System.IO.File.Delete(@"C:\person.gif"); 

hope that will help.

Asim Sajjad
  • 2,526
  • 10
  • 36
  • 73
1

The most easiest way to do this will be, creating a temporary copy of your image file and using it as a source.. and then at end of your app, deleting all temp files..

static List<string> tmpFiles = new List<string>();

static string GetTempCopy(string src)
{
   string copy = Path.GetTempFileName();
   File.Copy(src, copy);
   tmpFiles.Add(copy);
   return copy;
}

static void DeleteAllTempFiles()
{
   foreach(string file in tmpFiles)
   {
      File.Delete(file);
   }
}

Image caching in WPF also can be configured to do this, but for some reason my various attempts failed and we get unexpected behaviour like not being able to delete or refresh the image etc, so we did this way.

Akash Kava
  • 39,066
  • 20
  • 121
  • 167
  • Thanks, I used this to delete images from a `listbox` I made. You have to create a list of temps and a parallel list of the filenames of the actual files. The actual files and the temp files must be at the same index so that when you go to delete you can use their indexes to do so. – Stylzs05 May 23 '12 at 15:14
0

Do not attach the physical file to the object.

BitmapImage bmp;
static int filename = 0;
static string imgpath = "";


private void saveButton_Click(object sender, RoutedEventArgs e)
{
  try
  {
    filename = filename + 1;
    string locimagestored = Directory.GetParent(Assembly.GetExecutingAssembly().Location).ToString();
    locimagestored = locimagestored + "\\StoredImage\\";
    imgpath = locimagestored + filename + ".png";
    webCameraControl.GetCurrentImage().Save(imgpath);

    Bitmap bitmap = new Bitmap(@imgpath);
    IntPtr hBitmap = bitmap.GetHbitmap();
    ImageSource wpfBitmap = Imaging.CreateBitmapSourceFromHBitmap(hBitmap, IntPtr.Zero, Int32Rect.Empty,    BitmapSizeOptions.FromEmptyOptions()); ;

    if (filename == 1)
    {
      imgSavedOnline0.Source = wpfBitmap;
      bitmap.Dispose();
    }
    else if (filename == 2)
    {
      imgSavedOnline1.Source = wpfBitmap;
      bitmap.Dispose();
    }
    else if (filename == 3)
    {
      imgSavedOnline2.Source = wpfBitmap;
      bitmap.Dispose();
    }
    else if (filename == 4)
    {
      imgSavedOnline3.Source = wpfBitmap;
      bitmap.Dispose();
    }

    System.IO.DirectoryInfo di2 = new DirectoryInfo(locimagestored);

    foreach (FileInfo file in di2.GetFiles())
    {
      file.Delete();
    }    
  }
  catch (Exception ex)
  {
    textBox1.Text = ex.Message;
  }
}
RUL
  • 268
  • 2
  • 12
Saira
  • 1