c# - 在 WPF 中将 Image.Source 绑定(bind)到字符串?

标签 c# wpf image data-binding binding

我有以下 XAML 代码:

<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    DataContext="{Binding RelativeSource={RelativeSource Self}}"
    WindowStartupLocation="CenterScreen"
    Title="Window1" Height="300" Width="300">

    <Grid>
        <Image x:Name="TestImage" Source="{Binding Path=ImageSource}" />
    </Grid>

</Window>

此外,还有一种方法可以从 Base64 字符串生成图像:

Image Base64StringToImage(string base64ImageString)
{
    try
    {
        byte[] b;
        b = Convert.FromBase64String(base64ImageString);
        MemoryStream ms = new System.IO.MemoryStream(b);
        System.Drawing.Image img = System.Drawing.Image.FromStream(ms);

        //////////////////////////////////////////////
        //convert System.Drawing.Image to WPF image
        System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(img);
        IntPtr hBitmap = bmp.GetHbitmap();
        System.Windows.Media.ImageSource imageSource = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(hBitmap, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());

        Image wpfImage = new Image();
        wpfImage.Source = imageSource;
        wpfImage.Width = wpfImage.Height = 16;
        //////////////////////////////////////////////

        return wpfImage;
    }
    catch
    {
        Image img1 = new Image();
        img1.Source = new BitmapImage(new Uri(@"/passwordManager;component/images/TreeView/empty-bookmark.png", UriKind.Relative));
        img1.Width = img1.Height = 16;
        return img1;
    }
} 

现在,我要将 TestImage 绑定(bind)到 Base64StringToImage 方法的输出。
我使用了以下方式:

public string ImageSource { get; set; }
ImageSource = Base64StringToImage("iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAABjUExURXK45////6fT8PX6/bTZ8onE643F7Pf7/pDH7PP5/dns+b7e9MPh9Xq86NHo947G7Hm76NTp+PL4/bHY8ojD67rc85bK7b3e9MTh9dLo97vd8/D3/Hy96Xe76Nfr+H+/6f///1bvXooAAAAhdFJOU///////////////////////////////////////////AJ/B0CEAAACHSURBVHjaXI/ZFoMgEEMzLCqg1q37Yv//KxvAlh7zMuQeyAS8d8I2z8PT/AMDShWQfCYJHL0FmlcXSQTGi7NNLSMwR2BQaXE1IfAguPFx5UQmeqwEHSfviz7w0BIMyU86khBDZ8DLfWHOGPJahe66MKe/fIupXKst1VXxW/VgT/3utz99BBgA4P0So6hyl+QAAAAASUVORK5CYIII").Source.ToString(); 

但什么也没发生。
我该如何解决?

顺便说一句,我非常确定 base64 字符串是正确的

最佳答案

让我们分解一下您正在做的事情。

<Image Source="{Binding ImageSource}" />

为此,绑定(bind)源需要是 ImageSource 或表示图像文件 URI 的字符串。那么让我们来看看 ImageSource 属性到底是什么。

public string ImageSource { get; set; }

这里的一个问题是 ImageSource 没有引发 PropertyChanged 事件。因此,当您更新属性时,WPF 不会更新绑定(bind)目标。

而且,ImageSource 不是 ImageSource,它是一个字符串。没关系,但是 WPF 会将那个字符串解释为 URI。那个 URI 是什么?

ImageSource = Base64StringToImage(BIG_HONKING_STRING).Source.ToString(); 

这就是你的问题所在。 ImageSource 字符串实际上不是 URI,因为您的图像不是可寻址资源。 Base64StringToImage 从 base64 字符串创建一个内存中的 ImageSource,然后返回一个以此为源的图像。然后获取图像的源(这是一个 ImageSource 对象),并将其字符串化。如果 ImageSource 来自文件或 URL,那可能会起作用,但事实并非如此:它来自 HBITMAP。所以 ToString() 的结果将毫无意义。所以 ImageSource 被设置为无意义的东西,而您的 Image 试图将这个无意义的东西解释为位图文件的 URL。

所以要解决这个问题,您需要做三件事:

  1. 引发 ImageSource 属性的 PropertyChanged 事件(或使其成为依赖属性)。
  2. 将 ImageSource 属性更改为 ImageSource 类型而不是字符串类型(以便它可以包含无 URL 的图像源)。
  3. 更改您的 setter 调用以将 ImageSource 设置为 Base64StringToImage(...).Source —— 即删除 ToString() 调用。更好的是,更改 Base64StringToImage 以返回 ImageSource 而不是 Image:创建 Image 元素只会产生开销,因为您真正感兴趣的是 BitmapSource。

关于c# - 在 WPF 中将 Image.Source 绑定(bind)到字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2573912/

相关文章:

html - 将图片放在我的 HTML 上时会失真

php - 如何保护用户上传到我网站的私有(private)照片?

c# - 在不构建解决方案的情况下运行 StyleCopAnalyzers

c# - 需要高效稳定的 PriorityQueue 实现

wpf - 在 MVVM 中,在 ViewModel 中 Hook 模型项的事件会导致内存泄漏吗?

c# - 从 WebBrowser 控件中加载的文档中获取标题

C# 正则表达式替换() : getting the values

c# - 如何避免 Iterator 方法被重启?

c# - 为什么 WinForms/WPF 控件不在内部使用 Invoke?

python - 如何使用 matplotlib 读取 32 位整数图像?