locked
Couldn't delete image from the listBox. Error message: Image is being used RRS feed

  • Question

  • Hi Guys, I have loaded a collection of images in the listBox and I display them in the ImageBox for further modification when I click on each image.

    I have a button to delete the image, when i use the below function I'm getting a message, 'Image is being used'.

    How can i delete the image & select another image? Thank you very much for your help & support.

    Delete Function:

    private void bDeletePhoto_Click(object sender, RoutedEventArgs e)
            {
                currImgHandler.ClearImage();
                ImageFileCollectionViewModel viewModel = imageListBox.DataContext as ImageFileCollectionViewModel;
                if (viewModel != null)
                {
                    ImageFileViewModel image = imageListBox.SelectedItem as ImageFileViewModel;
                    if (image != null)
                    {
                        //remove physical file from disk:
                        File.Delete(image.FileName);
                        //remove item from ObservableCollection:
                        viewModel.AllImages.Remove(image);
                    }
                }
            }

    ListBox Select Item & display in the Image:

     CurrentImageHandler currImgHandler;
     private string saveFilname;
            private void showImage(object sender, SelectionChangedEventArgs args)
             {
                 
                 ListBox list = ((ListBox)sender);
                 if (list != null)
                 {
                     int index = list.SelectedIndex;	
                     if (index >= 0)
                     {
                         ImageFileViewModel image = imageListBox.SelectedItem as ImageFileViewModel;
                        
                         if ((image != null) )
                         {
                             Uri uriSource = new Uri(image.FileName, UriKind.RelativeOrAbsolute);
                             ViewedPhoto.Source = new BitmapImage(uriSource);
                             ViewedCaption.Content = image.ShortName.ToString();
                             saveFilname = image.FileName.ToString();
                             currImgHandler.CurrentFileHandler.Load(saveFilname);
                             PaintImage();
                            
                         }
                         
                         
                     }
                 }
                 
             }
    
    private void PaintImage()
    {
    	System.IO.MemoryStream stream = new System.IO.MemoryStream();
    	currImgHandler.CurrentBitmap.Save(stream, System.Drawing.Imaging.ImageFormat.Bmp);
    	stream.Position = 0;
    	byte[] data = new byte[stream.Length];
    	stream.Read(data, 0, Convert.ToInt32(stream.Length));
    	BitmapImage bmapImage = new BitmapImage();
    	bmapImage.BeginInit();
    	bmapImage.StreamSource = stream;
    	bmapImage.EndInit();
    	ViewedPhoto.Source = bmapImage; //ImageBox
    
    }

    Wednesday, March 5, 2014 12:32 PM

Answers

  • You should also set the Source property of the ViewedPhoto Image in the showImage event handler as follows:

            private void showImage(object sender, SelectionChangedEventArgs args)
             {
                 
                 ListBox list = ((ListBox)sender);
                 if (list != null)
                 {
                     int index = list.SelectedIndex; 
                     if (index >= 0)
                     {
                         ImageFileViewModel image = imageListBox.SelectedItem as ImageFileViewModel;
                        
                         if ((image != null) )
                         {
                            Uri uriSource = new Uri(image.FileName, UriKind.RelativeOrAbsolute);
                            BitmapImage bi = new BitmapImage();
                            bi.BeginInit();
                            bi.CacheOption = BitmapCacheOption.OnLoad;
                            bi.UriSource = uriSource;
                            bi.EndInit();
                            ViewedPhoto.Source = bi;
                            ViewedCaption.Content = image.ShortName.ToString();
                            saveFilname = image.FileName.ToString();
                            currImgHandler.CurrentFileHandler.Load(image.FileName);
                            PaintImage();
                         }
                     }
                 }
             }
    

    • Marked as answer by KrKa2022 Thursday, March 6, 2014 2:34 PM
    Thursday, March 6, 2014 2:20 PM

All replies

  • You should close the stream once you are done with it, either explicitly by calling its Close() method or implictly by the use of an using statment (http://msdn.microsoft.com/en-us//library/yh598w02.aspx):

            private void PaintImage()
            {
                System.IO.MemoryStream stream = new System.IO.MemoryStream();
                currImgHandler.CurrentBitmap.Save(stream, System.Drawing.Imaging.ImageFormat.Bmp);
                stream.Position = 0;
                byte[] data = new byte[stream.Length];
                stream.Read(data, 0, Convert.ToInt32(stream.Length));
                BitmapImage bmapImage = new BitmapImage();
                bmapImage.BeginInit();
                bmapImage.StreamSource = stream;
                bmapImage.EndInit();
                ViewedPhoto.Source = bmapImage; //ImageBox
                stream.Close();
            }
    

    Wednesday, March 5, 2014 2:04 PM
  • You should close the stream once you are done with it, either explicitly by calling its Close() method or implictly by the use of an using statment (http://msdn.microsoft.com/en-us//library/yh598w02.aspx):

            private void PaintImage()
            {
                System.IO.MemoryStream stream = new System.IO.MemoryStream();
                currImgHandler.CurrentBitmap.Save(stream, System.Drawing.Imaging.ImageFormat.Bmp);
                stream.Position = 0;
                byte[] data = new byte[stream.Length];
                stream.Read(data, 0, Convert.ToInt32(stream.Length));
                BitmapImage bmapImage = new BitmapImage();
                bmapImage.BeginInit();
                bmapImage.StreamSource = stream;
                bmapImage.EndInit();
                ViewedPhoto.Source = bmapImage; //ImageBox
                stream.Close();
            }

    Hi Magnus, thank you.

    When i use the `Stream.Close()` I don't see any image in the `ImageBox.  Is there any other way to fix this? Please help me. Thank you


    • Edited by KrKa2022 Wednesday, March 5, 2014 3:00 PM Edited
    Wednesday, March 5, 2014 2:17 PM
  • Hi Magnus, thank you.

    When i use the `Stream.Close()` I don't see any image in the `ImageBox. can you please guide me??

    You also have to set the CacheOption property of the BitmapImage to BitmapCacheOption.OnLoad to load the stream directly:

                BitmapImage bmapImage = new BitmapImage();
                bmapImage.BeginInit();
                bmapImage.CacheOption = BitmapCacheOption.OnLoad;
                bmapImage.StreamSource = stream;
                bmapImage.EndInit();

    By default, it is loaded on demand and the stream will be closed by then.

    Please remember to mark any post(s) that provide(s) a solution to your issue as answer and/or helpful.


    Wednesday, March 5, 2014 3:08 PM
  • Hi Magnus, thank you once again. St'll i'm getting the same message that 'Image is being used'.*

    I don't know what is wrong with this? Down i'm posted the entire code.

    If i don't use the below 2 lines of code, then I can delete the images from listbow using the delete function:

    currImgHandler.CurrentFileHandler.Load(saveFilname);
                     PaintImage();

    Thank you

    Code:

            CurrentImageHandler currImgHandler;
            ImageFileViewModel urNewName;
            string destination_dir = System.IO.Directory.GetCurrentDirectory() + @"./Prints/3.5x5";
            public PhotoView(ImageFileViewModel image)
           
            {
                InitializeComponent();
                currImgHandler = new CurrentImageHandler();
                urNewName = image;
                saveFilname = image.FileName.ToString();
                if ((urNewName != null))
                {
                    Uri uriSource = new Uri(urNewName.FileName, UriKind.RelativeOrAbsolute);
                    ViewedPhoto.Source = new BitmapImage(uriSource);
                    ViewedCaption.Content = image.ShortName.ToString();
    
                    currImgHandler.CurrentFileHandler.Load(saveFilname);
                    PaintImage();
                    imageinfo();
                }
    
                imageListBox.Items.Clear();
                DataContextChanged += OnDataContextChanged;
    
                ImageFileCollectionViewModel ImagesViewModel = new ImageFileCollectionViewModel();
                ImageFileControler.CompleteViewList(ImagesViewModel, destination_dir);
                imageListBox.DataContext = ImagesViewModel;
    
               
    
            }
    		void imageinfo() // To get the image details
            {
                FileInfo fileInfo = new FileInfo(currImgHandler.CurrentBitmapPath);
                lblImageName.Content = fileInfo.Name.Replace(fileInfo.Extension, "");
                lblImageExtension.Content = fileInfo.Extension;
                string loc = fileInfo.DirectoryName;
                if (loc.Length > 50)
                    loc = loc.Substring(0, 15) + "..." + loc.Substring(loc.LastIndexOf("\\"));
                lblImageLocation.Content = loc;
                lblImageDimension.Content = currImgHandler.CurrentBitmap.Width + " x " + currImgHandler.CurrentBitmap.Height;
                lblImageSize.Content = (fileInfo.Length / 1024.0).ToString("0.0") + " KB";
                lblImageCreatedOn.Content = fileInfo.CreationTime.ToString("dddd MMMM dd, yyyy");
            }
    		private ImageFileCollectionViewModel _currentDataContext;
             private void OnDataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
             {
                 if (_currentDataContext == DataContext) return;
    
                 if (_currentDataContext != null)
                     _currentDataContext.SelectedImageFileViewModels = null;
    
                 _currentDataContext = DataContext as ImageFileCollectionViewModel;
                 if (_currentDataContext != null)
                     _currentDataContext.SelectedImageFileViewModels = imageListBox.SelectedItems;
    
             }
    		 
    		private string saveFilname;
            private void showImage(object sender, SelectionChangedEventArgs args) //ListBox Selection
             {
                 
                
                 ImageFileViewModel image = imageListBox.SelectedItem as ImageFileViewModel;
    
                 if ((image != null))
                 {
                     Uri uriSource = new Uri(image.FileName, UriKind.RelativeOrAbsolute);
                     ViewedPhoto.Source = new BitmapImage(uriSource);
                     ViewedCaption.Content = image.ShortName.ToString();
                     saveFilname = image.FileName.ToString();
                     currImgHandler.CurrentFileHandler.Load(saveFilname);
                     PaintImage();
                     imageinfo();
    
                 }
             }
    		   private void PaintImage()
            {
                System.IO.MemoryStream stream = new System.IO.MemoryStream();
                currImgHandler.CurrentBitmap.Save(stream, System.Drawing.Imaging.ImageFormat.Bmp);
                stream.Position = 0;
                byte[] data = new byte[stream.Length];
                stream.Read(data, 0, Convert.ToInt32(stream.Length));
                BitmapImage bmapImage = new BitmapImage();
                bmapImage.BeginInit();
                bmapImage.CacheOption = BitmapCacheOption.OnLoad;
                bmapImage.StreamSource = stream;
                bmapImage.EndInit();
                ViewedPhoto.Source = bmapImage; //ImageBox
                ViewedPhoto.Stretch = Stretch.Uniform;
                stream.Close();
                
            }
    		 private void bDeletePhoto_Click(object sender, RoutedEventArgs e)
            {
                //currImgHandler.ClearImage();
                
                ImageFileCollectionViewModel viewModel = imageListBox.DataContext as ImageFileCollectionViewModel;
                if (viewModel != null)
                {
                    ImageFileViewModel image = imageListBox.SelectedItem as ImageFileViewModel;
                    if (image != null)
                    {
                        //remove physical file from disk:
                        File.Delete(image.FileName);
                        //remove item from ObservableCollection:
                        viewModel.AllImages.Remove(image);
                    }
                }
            }


    • Edited by KrKa2022 Wednesday, March 5, 2014 4:14 PM added
    Wednesday, March 5, 2014 3:24 PM
  • What is CurrentImageHandler and what does it do? Make sure you are not creating another stream that doesn't get closed properly in its CurrentFileHandler.Load method. For further help, please upload a project where your issue can be reproduced to SkyDrive or similar.
    Wednesday, March 5, 2014 10:20 PM
  • Hi Magnus, thank you very much once gain & sorry for the late reply.

    What am i doing: Basic Image editing functions like: Rotate, Flip(Hor, Ver), Brightness, Contrast, Gray Scale, Sepia.

    Don't know much about Image Processing or rather Image editing functions.

    I'm using this project dll for all the image editing functions: http://www.codeproject.com/Articles/237226/Image-Processing-is-done-using-WPF

    I have uploaded the project in the SkyDrive: 

    https://onedrive.live.com/redir?resid=8FE34CB77340CAA9!178&authkey=!AGQiXDiJZC2XPUs&ithint=file%2c.rar


    FileNme is : ImagePrintU.rar

    In the xaml file: PhotoView.XAML, change the dir image location:

    "string destination_dir = @"C:\Users\krangaraj\Pictures\AAA\4X6";"

    If you could give me some suggestions to have these functions without using that .dll it would be more helpful.

    Once again thank you very much & looking forward to your reply.

    karthik

    Thursday, March 6, 2014 7:31 AM
  • Just as I supspected, the ImageFileHandler.Load method in the third-party dll is the problem here. It creates a System.Drawing.Bitmap object that you must dispose before you can delete the physical file:

            private void bDeletePhoto_Click(object sender, RoutedEventArgs e)
            {
                ImageFileCollectionViewModel viewModel = imageListBox.DataContext as ImageFileCollectionViewModel;
                if (viewModel != null)
                {
                    ImageFileViewModel image = imageListBox.SelectedItem as ImageFileViewModel;
                    if (image != null)
                    {
                        //remove physical file from disk:
                        currImgHandler.CurrentBitmap.Dispose();
                        ViewedPhoto.Source = null;
                        File.Delete(image.FileName);
                        //remove item from ObservableCollection:
                        viewModel.AllImages.Remove(image);
                    }
                }
            }
    

    • Proposed as answer by Pete LakerMVP Thursday, March 6, 2014 1:03 PM
    Thursday, March 6, 2014 1:00 PM
  • Just as I supspected, the ImageFileHandler.Load method in the third-party dll is the problem here. It creates a System.Drawing.Bitmap object that you must dispose before you can delete the physical file:

            private void bDeletePhoto_Click(object sender, RoutedEventArgs e)
            {
                ImageFileCollectionViewModel viewModel = imageListBox.DataContext as ImageFileCollectionViewModel;
                if (viewModel != null)
                {
                    ImageFileViewModel image = imageListBox.SelectedItem as ImageFileViewModel;
                    if (image != null)
                    {
                        //remove physical file from disk:
                        currImgHandler.CurrentBitmap.Dispose();
                        ViewedPhoto.Source = null;
                        File.Delete(image.FileName);
                        //remove item from ObservableCollection:
                        viewModel.AllImages.Remove(image);
                    }
                }
            }

    Hi Magnus, i really appreciate your time & help.

    I used the above code & I'm still getting the same error like before. Could you please share me the project?

    Thank you.

    Karthik


    • Edited by KrKa2022 Thursday, March 6, 2014 2:18 PM edited
    Thursday, March 6, 2014 1:11 PM
  • You should also set the Source property of the ViewedPhoto Image in the showImage event handler as follows:

            private void showImage(object sender, SelectionChangedEventArgs args)
             {
                 
                 ListBox list = ((ListBox)sender);
                 if (list != null)
                 {
                     int index = list.SelectedIndex; 
                     if (index >= 0)
                     {
                         ImageFileViewModel image = imageListBox.SelectedItem as ImageFileViewModel;
                        
                         if ((image != null) )
                         {
                            Uri uriSource = new Uri(image.FileName, UriKind.RelativeOrAbsolute);
                            BitmapImage bi = new BitmapImage();
                            bi.BeginInit();
                            bi.CacheOption = BitmapCacheOption.OnLoad;
                            bi.UriSource = uriSource;
                            bi.EndInit();
                            ViewedPhoto.Source = bi;
                            ViewedCaption.Content = image.ShortName.ToString();
                            saveFilname = image.FileName.ToString();
                            currImgHandler.CurrentFileHandler.Load(image.FileName);
                            PaintImage();
                         }
                     }
                 }
             }
    

    • Marked as answer by KrKa2022 Thursday, March 6, 2014 2:34 PM
    Thursday, March 6, 2014 2:20 PM