图片是一种比较占内存的资源,尤其是高分辨率的图片。当我们的图片控件隐藏了,不需要显示的时候,这个时候图片还逗留在内存中,就太浪费资源了。
如果我们用默认的图片控件Image
,隐藏的时候可以给图片的Source
置空,显示的时候再给Source
重新赋值。
如果不改变Source
,我们用自定义的图片组件来实现的话呢!
基本思路:在图片隐藏的时候,执行空
绘制,以释放对图片源(BitmapImage
)的引用。
//……省略
//重写事件
VisibilityProperty.OverrideMetadata(typeof(ImageControl), new FrameworkPropertyMetadata((s, e) =>
{
//do something
}, (sender, value) =>
{
var visibility=(Visibility)value;
switch (visibility)
{
//如果图片隐藏了,释放图片资源
case Visibility.Hidden:
case Visibility.Collapsed:
imageControl.IsDisposing = true;
//使绘制区域无效
imageControl.Measure(new Size(0, 0));
imageControl.Arrange(new Rect(0, 0, 0, 0));
break;
case Visibility.Visible:
imageControl.IsDisposing = false;
//重绘
imageControl.InvalidateVisual();
break;
}
return visibility;
}));
//……省略
//渲染的时候,不执行操作
protected override void OnRender(DrawingContext drawingContext)
{
if (IsDisposing) return;
//省略
}
上述逻辑,也可以在Loaded Unloaded
事件中执行。
通过上述方法,就可以实现图片资源的引用释放,垃圾回收器可正常回收该图片资源,这样就可以不用一直占用着内存了。
注意:使用BitmapImage
的时候,如果是通过Stream
的方式指定,需要把BitmapImage.CacheOption
设置为BitmapCacheOption.OnLoad
,并释放流,否则就会出现内存泄漏。
欢迎转载分享,请关注微信公众号,将同步更新博客,方便查看!
本文会经常更新,请阅读原文: https://huchengv5.gitee.io//post/WPF-%E5%A6%82%E4%BD%95%E9%87%8A%E6%94%BE%E5%9B%BE%E7%89%87%E8%B5%84%E6%BA%90.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名胡承(包含链接: https://huchengv5.gitee.io/ ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系 。