Delete an image associated with a control

I am writing a WPF Image Manager 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 the JPG.

Some application features require you to modify the JPG file (move, rename, or delete). When I try to do this (currently trying to move the file), I get an IOException: "The process cannot access the file because it is being used by another process." The file locking process is my WPF application.

, , , , . :

  • ListBox.Source null
  • 10 .
  • GC.Collect().
  • .

? Image ItemsTemplate , , .

, , , , , , , .

.

+3
3

My Intuipic . . :

//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();
+6

Kent , bendewey, .

, , .

, , , bendewey, ( ) Kent BitmapImage:

    [ValueConversion(typeof(string), typeof(BitmapImage))]
public class PathToBitmapImage : IValueConverter
{
    public static BitmapImage ConvertToImage(string path)
    {
        if (!File.Exists(path))
            return null;

        BitmapImage bitmapImage = null;
        try
        {
            bitmapImage = new BitmapImage();
            bitmapImage.BeginInit();
            bitmapImage.StreamSource = new FileStream(path, FileMode.Open, FileAccess.Read);
            bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
            bitmapImage.EndInit();
            bitmapImage.StreamSource.Dispose();
        }
        catch (IOException ioex)
        {
        }
        return bitmapImage;
    }

    #region IValueConverter Members

    public virtual object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value == null || !(value is string))
            return null;

        var path = value as string;

        return ConvertToImage(path);
    }

    public virtual object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }

    #endregion
}

, , . ​​ , .

, , , , . , .

, , , , :

1) ImageList, . 2) , ImageList SelectedItem. 3) DeleteImage, .

, №2. SelectedItem, , ( ). SelectedItem . , .

, , SelectedItem .

+3

Send a message here.

http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/dee7cb68-aca3-402b-b159-2de933f933f1/

Example

Basically you have to preload the image using the stream. I would create a PreLoadImageConverter, something like this, I have not tested it.

<Grid>
  <Grid.Resources>
    <local:PreLoadImageConverter x:Key="imageLoadingConverter" />
  </Grid.Resources>
  <Image Width="Auto" Height="Auto" x:Name="picture" Source="{Binding Path=FullName, Converter={StaticResource imageLoadingConverter}}" />
</Grid>

PreLoadImageConverter.cs

public class PreLoadImageConverter : IValueConverter
{
  public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
  {
    if (value == null) return null;
    string imagePath = value.ToString();

    ImageSource imageSource;
    using (var stream = new MemoryStream())
    {
      Bitmap bitmap = new Bitmap(imagePath);
      bitmap.Save(stream, System.Drawing.Imaging.ImageFormat.Png);   
      PngBitmapDecoder bitmapDecoder = new PngBitmapDecoder(stream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad);
      imageSource = bitmapDecoder.Frames[0];
      imageSource.Freeze();
    }
    return imageSource;
  }

  public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
  {
    throw new Exception("The method or operation is not implemented.");
  }
}
+2
source

Source: https://habr.com/ru/post/1705471/


All Articles