图片是一种比较占内存的资源,尤其是高分辨率的图片。当我们的图片控件隐藏了,不需要显示的时候,这个时候图片还逗留在内存中,就太浪费资源了。

如果我们用默认的图片控件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/ ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系