WPF图像控制块中的文件 [英] Wpf Image Control blocks the file
问题描述
我有一个简单的窗口
使用按钮和第二窗口
当我点击<$ C $打开C>按钮。第二个窗口
有一个图片
控件,它显示的.png文件。所以,如果我用文件对象
属性绑定
一切正常,我可以删除文件档案资源管理器
。但是,如果使用文件名
属性绑定
我无法从删除文件文件浏览器
,我得到的操作系统异常。如果我关闭第二个窗口,我不能这样做就算了,即使我调用 GC
明确。
什么是文件名
属性的问题?有任何想法吗?
的Win 7,净4.0
窗口1
&LT;网格和GT;
&LT;按钮内容=确定
WIDTH =100
VerticalAlignment =中心
的HorizontalAlignment =中心
点击=点击
填充=0,2,0,2
ISDEFAULT =真
NAME =_ btnOk/&GT;
&LT; /网格和GT;公共部分类窗口:窗口
{ 公共窗口()
{
的InitializeComponent();
的DataContext =这一点;
} 私人无效点击(对象发件人,RoutedEventArgs E)
{
变种窗口=新Window3();
window.ShowDialog();
}
}
窗口2
&LT;网格和GT;
&lt;图像来源={结合的FileObject}&GT;&LT; /图像&GT;
&LT; /网格和GT;公共部分类窗口2:窗口
{
公共窗口2()
{
的InitializeComponent();
的DataContext =这一点;
文件名=D:/pdf/myfile.png 关闭+ = Window2_Closing;
} 公共字符串文件名{搞定;组; } 公共对象文件对象
{
得到
{
如果(String.IsNullOrEmpty(文件名))
返回null; 如果(!File.Exists(文件名))
返回null; VAR毫秒=新的MemoryStream();
VAR双向=新的BitmapImage(); 使用(VAR FS =新的FileStream(文件名,FileMode.Open,FileAccess.Read))
{
fs.CopyTo(毫秒);
bi.BeginInit();
bi.StreamSource =毫秒;
bi.EndInit();
}
返回双向;
}
} 无效Window2_Closing(对象发件人,System.ComponentModel.CancelEventArgs E)
{
所以GC.Collect();
GC.WaitForPendingFinalizers();
}
}
在你的 Image.Source
属性绑定到的URI(或字符串,从中乌里在内部创建),使用WPF,创建一个内置式转换器 BitmapFrame
从URI。
如果URI包含本地文件的路径,则BitmapFrame保持文件打开,只要它存在。这可能比它在你的应用中实际使用,因为它可能会通过用WPF缓存。
当你需要能够删除的图像从加载的文件,你应该总是使用你的文件对象
方法,但它应该是这样的:
公共图像的ImageSource
{
得到
{
...
VAR双向=新的BitmapImage();
使用(VAR FS =新的FileStream(文件名,FileMode.Open,FileAccess.Read))
{
bi.BeginInit();
bi.CacheOption = BitmapCacheOption.OnLoad;
bi.StreamSource = FS;
bi.EndInit();
}
返回双向;
}
}
或者是这样的:
公共图像的ImageSource
{
得到
{
使用(VAR FS =新的FileStream(文件名,FileMode.Open,FileAccess.Read))
{
返回BitmapFrame.Create(
FS,BitmapCreateOptions.None,BitmapCacheOption.OnLoad);
}
}
}
或者绑定到文件名
属性与创建的BitmapImage或BitmapFrame如上所示的绑定转换器。
I have a simple Window
with button and second Window
is opened when I click on the Button
. Second Window
has a Image
control, which displays a .png-file. So if I use FileObject
property for Binding
all is OK, I can delete file from File Explorer
. But if I use FileName
property for Binding
I cannot delete file from File Explorer
, I get OS exception. I cannot do this even if I close second window, even if I invoke GC
explicitly.
What is the problem with FileName
property? Any ideas?
Win 7, Net 4.0
Window1
<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();
}
}
Window2
<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();
}
}
When you bind the Image.Source
property to an Uri (or a string, from which an Uri is created internally), WPF uses a built-in type converter that creates a BitmapFrame
from the Uri.
If the Uri contains a path to a local file, the BitmapFrame keeps the file open, as long as it is existing. This may be longer than it is actually used in your application, because it may by cached by WPF.
When you need to be able to delete the file that an image was loaded from, you should always use your FileObject
approach, but it should look like this:
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;
}
}
Or like this:
public ImageSource Image
{
get
{
using (var fs = new FileStream(FileName, FileMode.Open, FileAccess.Read))
{
return BitmapFrame.Create(
fs, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
}
}
}
Or you bind to the FileName
property with a binding converter that creates a BitmapImage or BitmapFrame as shown above.
这篇关于WPF图像控制块中的文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!