【问题标题】:WPF frozen BitmapImage not showingWPF冻结的BitmapImage不显示
【发布时间】:2011-10-25 15:58:59
【问题描述】:

我正在使用绑定到 UI 上的图像属性的视图模型,并且该视图模型包含一个 ImageSource 属性。我使用以下函数设置该属性

    private BitmapImage GetImageFromUri(Uri urisource)
    {
        if (urisource == null)
            return null;

        var image = new BitmapImage();
        image.BeginInit();
        image.UriSource = urisource;
        image.EndInit();
        image.Freeze(); //commenting this shows the image if the routine is called from the proper thread.

        return image;
   }

出于某种奇怪的原因,在下面的代码中,当我对我的 BitmapImage 调用 Freeze 时,它​​没有出现在主窗口中。我没有出现异常或崩溃。有人可以帮我吗? 我正在异步设置图像属性,因此我需要能够使用创建的图像,假设 GetImageFromUri 调用是从 UI 线程以外的线程进行的。

【问题讨论】:

    标签: wpf bitmapsource freezable


    【解决方案1】:

    在冻结之前尝试为 BitmapImage 设置 CacheOption。看看这是否有效 -

    var image = new BitmapImage();
    image.BeginInit();
    image.CacheOption = BitmapCacheOption.OnLoad;
    image.UriSource = urisource;
    image.EndInit();
    image.Freeze();
    

    【讨论】:

      【解决方案2】:

      在冻结它之前,您需要完全渲染它。
      您应该尝试监听 SourceUpdated 事件,然后才冻结图像。

      附带说明,如果您想在此之后修改图像,则必须克隆它。

      【讨论】:

      • 渲染是什么意思?
      • 图形渲染。设置源不使其可视化,WPF首先需要渲染图像。看起来您在 WPF 有机会执行此操作之前将其冻结。
      【解决方案3】:

      如果我使用StreamSource,对我来说就足够了:

      public static BitmapSource ToBitmap(this MemoryStream stream)
          {
              try
              {
                  using (stream)
                  {
                      stream.Position = 0;
                      var image = new BitmapImage();
                      image.BeginInit();
                      image.CacheOption = BitmapCacheOption.OnLoad;
                      image.StreamSource = stream;
                      image.EndInit();
                      image.Freeze();
                      return image;
                  }
              }
              catch (Exception)
              {
                  return null;
              }
          }
      

      但如果我使用UriSource 我需要:

      public static async Task<BitmapSource> ToBitmapAsync(this string sourceUri)
          {
              try
              {
                  using (var client = new WebClient())
                  using (var stream = await client.OpenReadTaskAsync(new Uri(sourceUri)))
                  using (var ms = new MemoryStream())
                  {
                      stream.CopyTo(ms);
                      return ms.ToBitmap();
                  }
              }
              catch (Exception)
              {
                  return null;
              }
          }
      

      BitmapSourceUriSource,但它在 xaml 渲染后工作

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-08-07
        • 1970-01-01
        • 2017-06-07
        • 1970-01-01
        • 1970-01-01
        • 2013-02-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多