【问题标题】:Binding an Image in WPF MVVM在 WPF MVVM 中绑定图像
【发布时间】:2014-02-14 20:22:02
【问题描述】:

我在将 Image 绑定到我的视图模型时遇到了一些问题。我终于摆脱了 XamlParseException,但图像没有出现。我什至在 ViewModel 中对图像进行了硬编码。有人可以看到我做错了什么吗?

查看:

<Image HorizontalAlignment="Left" Margin="0,0,0,0" Name="image1" Stretch="Fill" VerticalAlignment="Bottom" Grid.Row="8" Width="200"  Grid.ColumnSpan="2" >
<Image.Source>
    <BitmapImage DecodePixelWidth="200" UriSource="{Binding Path=DisplayedImage, Mode=TwoWay}" />
</Image.Source>

视图模型:

 string _DisplayedImagePath = @"C:\Users\Public\Pictures\Sample Pictures\Chrysanthemum.jpg";//string.Empty;
    int _DisplayedImageIndex;
    BitmapImage _DisplayedImage = null;
    public BitmapImage DisplayedImage
    {
        get
        {
            _DisplayedImage = new BitmapImage();
            if (!string.IsNullOrEmpty(_DisplayedImagePath))
            {
                _Rail1DisplayedImage.BeginInit();
                _Rail1DisplayedImage.CacheOption = BitmapCacheOption.OnLoad;
                _Rail1DisplayedImage.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
                _Rail1DisplayedImage.UriSource = new Uri(_DisplayedImagePath);
                _Rail1DisplayedImage.DecodePixelWidth = 200;
                _Rail1DisplayedImage.EndInit();
            }
            return _Rail1DisplayedImage;
        }
        set
        {
            _Rail1DisplayedImage = value;
            OnPropertyChanged("DisplayedImage");
        }
    }

【问题讨论】:

    标签: c# wpf mvvm


    【解决方案1】:

    在 WPF 中显示Image 比这容易得多。试试这个:

    <Image Source="{Binding DisplayedImagePath}" HorizontalAlignment="Left" 
        Margin="0,0,0,0" Name="image1" Stretch="Fill" VerticalAlignment="Bottom" 
        Grid.Row="8" Width="200"  Grid.ColumnSpan="2" />
    

    并且该属性可以只是一个string:

    public string DisplayedImage 
    {
        get { return @"C:\Users\Public\Pictures\Sample Pictures\Chrysanthemum.jpg"; }
    }
    

    虽然您确实应该将图像添加到项目根目录中名为 Images 的文件夹中,并在 Properties 中将它们的 Build Action 设置为 Resource Visual Studio 中的窗口...然后您可以使用以下格式访问它们:

    public string DisplayedImage 
    {
        get { return "/AssemblyName;component/Images/ImageName.jpg"; }
    }
    

    更新>>>

    作为最后的提示...如果您遇到控件无法按预期工作的问题,只需在搜索引擎中输入“WPF”、该控件的名称,然后输入“类”一词。在这种情况下,您将输入“WPF Image Class”。最上面的结果始终是 MSDN,如果您单击链接,您会发现有关该控件的所有信息,并且大多数页面也有代码示例。


    更新 2 >>>

    如果您按照 MSDN 链接中的示例操作但它不起作用,那么您的问题不是Image 控件。使用我建议的string 属性,试试这个:

    <StackPanel>
        <Image Source="{Binding DisplayedImagePath}" />
        <TextBlock Text="{Binding DisplayedImagePath}" />
    </StackPanel>
    

    如果您在TextBlock 中看不到文件路径,那么您可能没有将您的DataContext 设置为您的视图模型的实例。如果您可以看到文本,那么问题出在您的文件路径上。


    更新 3 >>>

    在 .NET 4 中,上面的 Image.Source 值可以工作。但是,Microsoft 在 .NET 4.5 中做出了一些可怕的更改,破坏了许多不同的东西,因此在 .NET 4.5 中,您需要像这样使用完整的 pack 路径:

    <Image Source="pack://application:,,,/AssemblyName;component/Images/image_to_use.png">
    

    有关包 URI 的详细信息,请参阅 Microsoft Docs 上的 Pack URIs in WPF 页面。

    【讨论】:

    • 感谢您的回复。我尝试了该代码,在 DisplayedImage 中放置了一个断点,它肯定被访问但没有图像。
    • 对不起,这意味着表单上没有出现图像。如果我将路径直接放在 XAML 中,图像会显示。
    • 是的,对不起,我没有正确看到您的财产...比这更容易。查看我的编辑。
    • 好吧,这让我无处可去。有人用绑定的 wpf 图像测试过代码吗?
    • 我很抱歉没有早点得到这个。谢谢谢里登。我在选项卡控件上有两个选项卡,每个选项卡都使用相同的 UserControl,但区别在于绑定。您的最后一次更新让我意识到我正在查看错误的选项卡,因为未设置绑定。感谢您的帮助。你太棒了。
    【解决方案2】:

    @Sheridan thx .. 如果我尝试在两侧使用“DisplayedImagePath”的示例,它可以使用绝对路径,如您所示。

    至于 relative 路径,这就是我总是连接相对路径的方式,我首先在我的项目中包含子目录 (!) 和图像文件.. 然后我使用 ~ 字符来表示bin-path..

        public string DisplayedImagePath
        {
            get { return @"~\..\images\osc.png"; }
        }
    

    这是经过测试的,见下面我在 VS2015 中的解决方案资源管理器..

    )

    注意:如果您想要点击事件,请使用Button tag around the image,

    <Button Click="image_Click" Width="128" Height="128"  Grid.Row="2" VerticalAlignment="Top" HorizontalAlignment="Left">
      <Image x:Name="image" Source="{Binding DisplayedImagePath}" Margin="0,0,0,0" />
    </Button>

    【讨论】:

      【解决方案3】:

      如果您有一个已经生成并返回 Image 类型的进程,您可以更改绑定,而不必修改任何额外的图像创建代码。

      参考绑定声明中图片的“.Source”。

      XAML

      <Image Name="imgOpenClose" Source="{Binding ImageOpenClose.Source}"/>
      

      查看模型字段

      private Image _imageOpenClose;
      public Image ImageOpenClose
      {
          get
          {
              return _imageOpenClose;
          }
          set
          {
              _imageOpenClose = value;
              OnPropertyChanged();
          }
      }
      

      【讨论】:

      • 你好内存泄漏..更新示例以正确处理图像...
      • @WalterVerhoeven 你在说什么样本?这里的代码是一个属性,而不是创建图像的过程。
      • 不,但是您将图像替换为“值”而不释放您拥有的图像,只需更新示例,它将是完美的
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-01
      • 2017-05-01
      • 2011-10-07
      • 1970-01-01
      • 1970-01-01
      • 2015-05-24
      相关资源
      最近更新 更多