Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将Image.Source绑定到WPF中的字符串?_C#_Wpf_Image_Data Binding_Binding - Fatal编程技术网

C# 将Image.Source绑定到WPF中的字符串?

C# 将Image.Source绑定到WPF中的字符串?,c#,wpf,image,data-binding,binding,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}}"

我有以下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>
现在,我要将
TestImage
绑定到
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}" />
这里的一个问题是ImageSource没有引发PropertyChanged事件。因此,当您更新属性时,WPF不会更新绑定目标

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

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

因此,要解决此问题,您需要做三件事:

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

  • 作为对@itowlson优秀答案的补充,您的代码应该是这样的:

    // MainWindow.xaml
    <Window x:Class="MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525">
        <DockPanel>
            <Image Source="{Binding ImageSource}" />
        </DockPanel>
    </Window>
    
    // MainWindow.xaml.cs
    using System.ComponentModel;
    using System.IO;
    using System.Windows;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
    
            var model = new MainModel();
            DataContext = model;
    
            model.SetImageData(File.ReadAllBytes(@"C:\Users\Public\Pictures\Sample Pictures\Desert.jpg"));
        }
    }
    
    class MainModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
    
        public void SetImageData(byte[] data) {
            var source = new BitmapImage();
            source.BeginInit();
            source.StreamSource = new MemoryStream(data);
            source.EndInit();
    
            // use public setter
            ImageSource = source;
        }
    
        ImageSource imageSource;
        public ImageSource ImageSource
        {
            get { return imageSource; }
            set
            {
                imageSource = value;
                OnPropertyChanged("ImageSource");
            }
        }
    
        protected void OnPropertyChanged(string name)
        {
            var handler = PropertyChanged;
            if (null != handler)
            {
                handler(this, new PropertyChangedEventArgs(name));
            }
        }
    }
    
    //MainWindow.xaml
    //MainWindow.xaml.cs
    使用系统组件模型;
    使用System.IO;
    使用System.Windows;
    使用System.Windows.Media;
    使用System.Windows.Media.Imaging;
    公共部分类主窗口:窗口
    {
    公共主窗口()
    {
    初始化组件();
    var模型=新的主模型();
    DataContext=模型;
    model.SetImageData(File.ReadAllBytes(@“C:\Users\Public\Pictures\Sample Pictures\Desert.jpg”);
    }
    }
    类MainModel:INotifyPropertyChanged
    {
    公共事件属性更改事件处理程序属性更改;
    public void SetImageData(字节[]数据){
    var source=新的位图图像();
    source.BeginInit();
    source.StreamSource=新内存流(数据);
    source.EndInit();
    //使用公共设置器
    图像源=源;
    }
    图像源图像源;
    公共图像源图像源
    {
    获取{return imageSource;}
    设置
    {
    imageSource=值;
    OnPropertyChanged(“ImageSource”);
    }
    }
    受保护的void OnPropertyChanged(字符串名称)
    {
    var handler=PropertyChanged;
    if(null!=处理程序)
    {
    处理程序(此,新PropertyChangedEventArgs(名称));
    }
    }
    }
    
    与您的问题无关,但您是否尝试过使用
    var img=new BitmapImage{StreamSource=ms}
    加载图像?@Simon:没有。但是,为什么我要这样做呢?好吧,你可以直接用WPF加载图像,而不是通过GDI+(System.Drawing)。因为它是从XAML使用的,所以实际上必须执行
    var source=new-BitmapImage();source.BeginInit();source.StreamSource=ms;source.EndInit()
    。我注意到ImageSource=“resources\refresh.png”不起作用,但ImageSource=“\resources\refresh.png”起作用,其中ImageSource是一个dependencyproperty。而直接在图像控件中使用Source=“resources\refresh.png”确实有效。谢谢,我已经完成了,但没有显示任何内容。只显示一个字符串,而不是image=>
    WpfApplication1.MainModel
    。你可以从附近下载我的项目,它是
    DataContext=model,而不是
    内容=模型。另外,您可以在
    SetImageData()
    中直接使用
    Convert.FromBase64String(…)
    BitmapImage
    可以加载与
    System.Drawing.Image
    相同的图像。非常感谢兄弟,我真的需要它。谢谢:-)
    图像。源代码也可以绑定到
    字节[]
    ImageSource = Base64StringToImage(BIG_HONKING_STRING).Source.ToString(); 
    
    // MainWindow.xaml
    <Window x:Class="MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525">
        <DockPanel>
            <Image Source="{Binding ImageSource}" />
        </DockPanel>
    </Window>
    
    // MainWindow.xaml.cs
    using System.ComponentModel;
    using System.IO;
    using System.Windows;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
    
            var model = new MainModel();
            DataContext = model;
    
            model.SetImageData(File.ReadAllBytes(@"C:\Users\Public\Pictures\Sample Pictures\Desert.jpg"));
        }
    }
    
    class MainModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
    
        public void SetImageData(byte[] data) {
            var source = new BitmapImage();
            source.BeginInit();
            source.StreamSource = new MemoryStream(data);
            source.EndInit();
    
            // use public setter
            ImageSource = source;
        }
    
        ImageSource imageSource;
        public ImageSource ImageSource
        {
            get { return imageSource; }
            set
            {
                imageSource = value;
                OnPropertyChanged("ImageSource");
            }
        }
    
        protected void OnPropertyChanged(string name)
        {
            var handler = PropertyChanged;
            if (null != handler)
            {
                handler(this, new PropertyChangedEventArgs(name));
            }
        }
    }