智慧聪明的智人 2024-08-10 11:35 采纳率: 0%
浏览 13

关于#wpf#的问题:这是一个C# WPF应用程序项目中的一个方法,用于获取嵌入的资源中的压缩文件中的图片

        public BitmapImage LoadImageFromZip(string resourceName, string imageName)
        {
            BitmapImage bitmapImage = null;

            using (Stream zipStream = GetEmbeddedResourceStream(resourceName))
            {
                if (zipStream != null)
                {
                    using (ZipArchive archive = new ZipArchive(zipStream, ZipArchiveMode.Read))
                    {
                        ZipArchiveEntry entry = archive.GetEntry(imageName);
                        if (entry != null)
                        {
                            using (Stream imageStream = entry.Open())
                            {
                                bitmapImage = new BitmapImage();
                                bitmapImage.BeginInit();
                                bitmapImage.StreamSource = imageStream;
                                bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
                                bitmapImage.EndInit();
                                return bitmapImage;
                            }
                        }
                    }
                }
            }
            return null;
        }

这是一个C# WPF应用程序项目中的一个方法,用于获取嵌入的资源中的压缩文件中的图片,但是始终无法加载。我在bitmapImage.EndInit()后加MessageBox方法用于Debug的时候代码就起作用了,怎样才能不依靠MessageBox的副作用就让图片正常加载?

  • 写回答

2条回答 默认 最新

  • 清水白石008 2024-08-11 07:06
    关注
    🕒上午好,题主!目前:🟢[在线]
    📢参考GPT-4o mini 模型、由清水白石008整理提供!
    📣今日金句:人必須相信自己,這是成功的秘訣。
    

    在 WPF 中,BitmapImage 的加载过程是异步的,特别是在使用流作为源时。你遇到的问题是因为在调用 EndInit() 后,BitmapImage 可能还没有完成加载,而你在使用它时可能会遇到问题。使用 MessageBox 可能会导致线程阻塞,从而给 BitmapImage 足够的时间来完成加载。

    要解决这个问题,可以使用 BitmapImageDownloadCompleted 事件,或者在加载完成后使用 Dispatcher 来确保 UI 线程在使用图像之前已经完成加载。以下是两种解决方案:

    解决方案 1:使用 DownloadCompleted 事件

    public BitmapImage LoadImageFromZip(string resourceName, string imageName)
    {
        BitmapImage bitmapImage = new BitmapImage();
        bitmapImage.BeginInit();
        bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
    
        using (Stream zipStream = GetEmbeddedResourceStream(resourceName))
        {
            if (zipStream != null)
            {
                using (ZipArchive archive = new ZipArchive(zipStream, ZipArchiveMode.Read))
                {
                    ZipArchiveEntry entry = archive.GetEntry(imageName);
                    if (entry != null)
                    {
                        using (Stream imageStream = entry.Open())
                        {
                            bitmapImage.StreamSource = imageStream;
                            bitmapImage.DownloadCompleted += (s, e) =>
                            {
                                // 在这里处理加载完成后的逻辑
                                // 例如,将图像显示在 UI 上
                            };
                        }
                    }
                }
            }
        }
    
        bitmapImage.EndInit();
        bitmapImage.Freeze(); // 如果需要在其他线程中使用,可以调用 Freeze()
        return bitmapImage;
    }
    

    解决方案 2:使用 Dispatcher 确保加载完成

    如果你希望在加载完成后立即使用图像,可以在 EndInit() 后使用 Dispatcher 来确保 UI 线程在使用图像之前已经完成加载。

    public BitmapImage LoadImageFromZip(string resourceName, string imageName)
    {
        BitmapImage bitmapImage = new BitmapImage();
        bitmapImage.BeginInit();
        bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
    
        using (Stream zipStream = GetEmbeddedResourceStream(resourceName))
        {
            if (zipStream != null)
            {
                using (ZipArchive archive = new ZipArchive(zipStream, ZipArchiveMode.Read))
                {
                    ZipArchiveEntry entry = archive.GetEntry(imageName);
                    if (entry != null)
                    {
                        using (Stream imageStream = entry.Open())
                        {
                            bitmapImage.StreamSource = imageStream;
                        }
                    }
                }
            }
        }
    
        bitmapImage.EndInit();
        bitmapImage.Freeze(); // 如果需要在其他线程中使用,可以调用 Freeze()
    
        // 使用 Dispatcher 确保在 UI 线程中使用
        Application.Current.Dispatcher.Invoke(() =>
        {
            // 在这里使用 bitmapImage,例如将其设置为 Image 控件的 Source
        });
    
        return bitmapImage;
    }
    

    总结

    通过使用 DownloadCompleted 事件或 Dispatcher,你可以确保在使用 BitmapImage 之前,它已经完成加载,而不依赖于 MessageBox 的副作用。选择适合你需求的解决方案来实现图像的正常加载。希望这些建议能帮助你解决问题!

    评论

报告相同问题?

问题事件

  • 创建了问题 8月10日

悬赏问题

  • ¥66 换电脑后应用程序报错
  • ¥50 array数据同步问题
  • ¥15 pic16F877a单片机的外部触发中断程序仿真失效
  • ¥15 Matlab插值拟合差分微分规划图论
  • ¥15 keil5 target not created
  • ¥15 C/C++数据与算法请教
  • ¥15 怎么找志同道合的伙伴
  • ¥20 如何让程序ab.eXe自已删除干净硬盘里的本文件自己的ab.eXe文件
  • ¥50 爬虫预算充足,跪巨佬
  • ¥15 滑块验证码拖动问题悬赏