Wpf Image Control会阻止该文件

mon*_*str 5 c# wpf image

我有一个简单Window的按钮,第二个Window是我点击时打开的Button.第二个Window有一个Image控件,显示一个.png文件.因此,如果我使用FileObject属性Binding就可以了,我可以从中删除文件File Explorer.但是,如果我使用FileName属性,Binding我无法删除文件File Explorer,我得到操作系统异常.即使我GC明确调用,即使关闭第二个窗口,我也无法做到这一点.FileName财产有什么问题?有任何想法吗?

赢7,净4.0

窗口1

<Grid>
    <Button Content="Ok"
            Width="100" 
            VerticalAlignment="Center" 
            HorizontalAlignment="Center" 
            Click="Click" 
            Padding="0,2,0,2" 
            IsDefault="True" 
            Name="_btnOk"/>
</Grid> 



public partial class Window : Window
{

    public Window()
    {
        InitializeComponent();
        DataContext = this;
    }

    private void Click(Object sender, RoutedEventArgs e)
    {
        var window = new Window3();
        window.ShowDialog();
    }
}
Run Code Online (Sandbox Code Playgroud)

窗口2

<Grid>
    <Image Source="{Binding FileObject}"></Image>
</Grid>

public partial class Window2 : Window
{
    public Window2()
    {
        InitializeComponent();
        DataContext = this;
        FileName = "D:/pdf/myfile.png";

        Closing += Window2_Closing;
    }

    public String FileName { get; set; }

    public Object FileObject
    {
        get
        {
            if (String.IsNullOrEmpty(FileName))
                return null;

            if (!File.Exists(FileName))
                return null;

            var ms = new MemoryStream();
            var bi = new BitmapImage();

            using (var fs = new FileStream(FileName, FileMode.Open, FileAccess.Read))
            {
                fs.CopyTo(ms);
                bi.BeginInit();
                bi.StreamSource = ms;
                bi.EndInit();
            }
            return bi;
        }
    }

    void Window2_Closing(Object sender, System.ComponentModel.CancelEventArgs e)
    {
        GC.Collect();
        GC.WaitForPendingFinalizers();
    }
}
Run Code Online (Sandbox Code Playgroud)

Cle*_*ens 8

Image.Source属性绑定到Uri(或从内部创建Uri的字符串)时,WPF使用内置类型转换器BitmapFrame从Uri 创建.

如果Uri包含本地文件的路径,则BitmapFrame会保持文件处于打开状态,只要它存在即可.这可能比您在应用程序中实际使用的时间更长,因为它可能由WPF缓存.

当您需要能够删除加载图像的文件时,应始终使用您的FileObject方法,但它应如下所示:

public ImageSource Image
{
    get
    {
        ...
        var bi = new BitmapImage();
        using (var fs = new FileStream(FileName, FileMode.Open, FileAccess.Read))
        {
            bi.BeginInit();
            bi.CacheOption = BitmapCacheOption.OnLoad;
            bi.StreamSource = fs;
            bi.EndInit();
        }
        return bi;
    }
}
Run Code Online (Sandbox Code Playgroud)

或者像这样:

public ImageSource Image
{
    get
    {
        using (var fs = new FileStream(FileName, FileMode.Open, FileAccess.Read))
        {
            return BitmapFrame.Create(
                fs, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

或者FileName使用绑定转换器绑定到属性,该绑定转换器创建BitmapImage或BitmapFrame,如上所示.