问题 在WPF中显示图像而不保持文件打开


我正在使用WPF中的图像管理应用程序,它显示了许多图像,并允许用户在文件系统中移动它们。我遇到的问题是显示带有文件的文件 <Image> element似乎保持文件打开,因此尝试移动或删除文件失败。有没有办法手动要求WPF卸载或释放文件,以便可以移动?或者是否有一种显示不保持文件打开的图像的方法?查看器Xaml如下:

<ListBox x:Name="uxImages" ScrollViewer.HorizontalScrollBarVisibility="Disabled">
            <ListBox.ItemsPanel>
                <ItemsPanelTemplate>
                    <WrapPanel Orientation="Horizontal" />
                </ItemsPanelTemplate>
            </ListBox.ItemsPanel>

            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Border Margin="4">
                        <Image Source="{Binding}" Width="150" Height="150"/>
                    </Border>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

7335
2017-11-19 14:18


起源



答案:


是什么 ItemsSource 你的 ListBox ?包含图像路径的字符串列表?

而不是隐式使用从字符串到ImageSource的内置转换器,使用自定义转换器在加载图像后关闭流:

public class PathToImageConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        string path = value as string;
        if (path != null)
        {
            BitmapImage image = new BitmapImage();
            using (FileStream stream = File.OpenRead(path))
            {
                image.BeginInit();
                image.StreamSource = stream;
                image.CacheOption = BitmapCacheOption.OnLoad;
                image.EndInit(); // load the image from the stream
            } // close the stream
            return image;
        }
    }
}

16
2017-11-19 14:31



添加了这个并且它有效。谢谢! image.CacheOption = BitmapCacheOption.OnLoad; - James Cadd
看起来像image.CacheOption = BitmapCacheOption.OnLoad;应该在image.BeginInit()之后调用; 。当我在初始化调用之后和BeginInit()之前分配它时,图像没有显示。 - SKG
警告:这个解决方案是 非常 慢。目前正在试图弄清楚如何加快速度,但它不适合加载大量图像。 - rookie1024


答案:


是什么 ItemsSource 你的 ListBox ?包含图像路径的字符串列表?

而不是隐式使用从字符串到ImageSource的内置转换器,使用自定义转换器在加载图像后关闭流:

public class PathToImageConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        string path = value as string;
        if (path != null)
        {
            BitmapImage image = new BitmapImage();
            using (FileStream stream = File.OpenRead(path))
            {
                image.BeginInit();
                image.StreamSource = stream;
                image.CacheOption = BitmapCacheOption.OnLoad;
                image.EndInit(); // load the image from the stream
            } // close the stream
            return image;
        }
    }
}

16
2017-11-19 14:31



添加了这个并且它有效。谢谢! image.CacheOption = BitmapCacheOption.OnLoad; - James Cadd
看起来像image.CacheOption = BitmapCacheOption.OnLoad;应该在image.BeginInit()之后调用; 。当我在初始化调用之后和BeginInit()之前分配它时,图像没有显示。 - SKG
警告:这个解决方案是 非常 慢。目前正在试图弄清楚如何加快速度,但它不适合加载大量图像。 - rookie1024