Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delete an image bound to a control

Tags:

c#

file-io

wpf

I am writing an Image Manager WPF application. I have a ListBox with the following ItemsTemplate:

        <Grid x:Name="grid" Width="150" Height="150" Background="{x:Null}">
            <Grid.RowDefinitions>
                <RowDefinition Height="*"/>
                <RowDefinition Height="27.45"/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="150"/>
            </Grid.ColumnDefinitions>
            <Border Margin="5,5,5,5.745" Grid.RowSpan="2" Background="#FF828282" BorderBrush="{DynamicResource ListBorder}" CornerRadius="5,5,5,5" BorderThickness="1,1,2,2" x:Name="border">
                <Grid>
                    <Viewbox Margin="0,0,0,21.705">
                        <Image Width="Auto" Height="Auto" x:Name="picture" Source="{Binding Path=FullName}" />
                    </Viewbox>
                    <TextBlock Height="Auto" Text="{Binding Path=Name}" TextWrapping="Wrap" x:Name="PictureText" HorizontalAlignment="Left" Margin="70,0,0,0" VerticalAlignment="Bottom" />
                </Grid>
            </Border>
        </Grid>

Note that the "Image" control is bound to the "FullName" property, which is a string representing the absolute path to a JPG.

Several application features require that I alter the JPG file (move, rename, or delete). When I try to do so (currently trying to Move the file) I receive an IOException: "The process cannot access the file because it is being used by another process." The process locking the file is my WPF application.

I did some searching online and found several postings indicating that Images in particular have trouble letting go of their resources. I have tried the following:

  1. Setting the ListBox.Source to null
  2. Adding a 10 second wait time before attempting the move.
  3. Issuing GC.Collect().
  4. Moving the operation to a different thread.

What else can I try? I thought about finding a reference to the Image object in the ItemsTemplate and trying to dispose of the Image, but I can't figure out how to get the reference.

One possible solution I read about was to create copies of the Images rather than the actual images, but since the Binding is to the filename and not the actual Image I don't know if I could make this work.

Any help or suggestions would be most appreciated.

like image 780
Joel Cochran Avatar asked Sep 02 '25 03:09

Joel Cochran


1 Answers

My Intuipic application allows users to delete images, too. I had to write this converter to achieve it. Relevant code:

//create new stream and create bitmap frame
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.StreamSource = new FileStream(path, FileMode.Open, FileAccess.Read);
bitmapImage.DecodePixelWidth = (int) _decodePixelWidth;
bitmapImage.DecodePixelHeight = (int) _decodePixelHeight;
//load the image now so we can immediately dispose of the stream
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
bitmapImage.EndInit();

//clean up the stream to avoid file access exceptions when attempting to delete images
bitmapImage.StreamSource.Dispose();
like image 130
Kent Boogaart Avatar answered Sep 05 '25 01:09

Kent Boogaart