我有一个带有按钮的简单 Window
,当我单击 Button
时会打开第二个 Window
。第二个 Window
有一个 Image
控件,它显示一个 .png 文件。因此,如果我将 FileObject
属性用于 Binding
一切正常,我可以从 File Explorer
中删除文件。但是,如果我将 FileName
属性用于 Binding
,我将无法从 File Explorer
中删除文件,我会遇到操作系统异常。即使我关闭第二个窗口,即使我显式调用 GC
,我也不能这样做。
FileName
属性有什么问题?有任何想法吗?
Win 7、Net 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();
}
}
窗口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();
}
}
最佳答案
当您将 Image.Source
属性绑定(bind)到一个 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;
}
}
或者像这样:
public ImageSource Image
{
get
{
using (var fs = new FileStream(FileName, FileMode.Open, FileAccess.Read))
{
return BitmapFrame.Create(
fs, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
}
}
}
或者,您使用创建 BitmapImage 或 BitmapFrame 的绑定(bind)转换器绑定(bind)到 FileName
属性,如上所示。
关于c# - Wpf 图像控件阻止文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29625428/