0

In my C# WPF app, I have a main window xaml like this:

<Window x:Class="MyProg.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:MyProg"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid Name="MainGrid">
        <ListBox x:Name="lbSongs" HorizontalContentAlignment="Stretch">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="Auto"/>
                            <ColumnDefinition Width="*"/>
                            <ColumnDefinition Width="Auto"/>
                        </Grid.ColumnDefinitions>
                        <Rectangle RadiusX="8" RadiusY="8" Height="128" Width="128" Grid.Column="0" Margin="3,1,3,5">
                            <Rectangle.Fill>
                                <ImageBrush ImageSource="{Binding ImgPath}" x:Name="SongImage"/>
                            </Rectangle.Fill>
                        </Rectangle>
                        <StackPanel Grid.Column="1" Orientation="Vertical">
                            <TextBlock Text="{Binding SongName}"/>
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="*"/>
                                    <ColumnDefinition MaxWidth="200"/>
                                </Grid.ColumnDefinitions>
                                <StackPanel Orientation="Vertical" Grid.Column="0">
                                    <TextBlock Text="{Binding Artist}" FontSize="18" HorizontalAlignment="Left"/>
                                </StackPanel>
                                <StackPanel Orientation="Vertical" Grid.Column="1">
                                    <TextBlock Text="{Binding TrackTime}" FontSize="14" HorizontalAlignment="Left"/>
                                    <TextBlock Text="{Binding BPM}" FontSize="14" HorizontalAlignment="Left"/>
                                </StackPanel>
                            </Grid>
                        </StackPanel>
                        <StackPanel Grid.Column="2" Orientation="Vertical" Width="39">
                            <Button Content="Play" Click="OnClickPlay" Tag="{Binding SongDir}"/>
                            <Button Content="Delete" Click="OnClickDelete" Tag="{Binding SongDir}"/>
                        </StackPanel>
                    </Grid>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Grid>
</Window>

This window uses a main ListBox with a DataTemplate which is filled dynamically with a list of songs. Each song/ListBox item has a "Delete" Button. I use a Tag element to tell the OnClickDelete handler which ListBox item is to be deleted:

private void OnClickDelete(object sender, RoutedEventArgs e)
{
    Button clicked = (Button)sender;
    string dir = clicked.Tag.ToString();
    MessageBoxResult result = MessageBox.Show(
        "Are you sure you want to delete this song?", "Confirmation", MessageBoxButton.OKCancel);
    if (result == MessageBoxResult.OK)
    {
        string imgPath = dir + @"\" + info._coverImageFilename;
        foreach (var item in lbSongs.Items)
        {
            var container = lbSongs.ItemContainerGenerator.ContainerFromItem(item) as FrameworkElement;
            if (container != null) {
                if (dat.ImgPath == imgPath)
                {
                    lbSongs.Items.Remove(item);
                    break;
                }
            }
        }
    }
}

The ListBox item is removed properly like this, but the bitmap of the ImageBrush element in the deleted ListBox item is not properly disposed of. I know this because I want to delete the source image file when I delete the song and the image file is locked after the ListBox item removal.

Is there a way to dispose of the right ImageBrush ImageSource bitmap?

Carmen DiMichele
  • 555
  • 4
  • 18
  • You may write a Binding Converter that loads a BitmapImage directly from a FileStream, to avoid that the images files are kept open. See e.g. here: https://stackoverflow.com/a/13265190/1136211. Calling BitmapImage.Freeze() would further reduce the memory footprint. – Clemens Jan 15 '23 at 09:18

0 Answers0