【问题标题】:How to bind the Image.Source in MVVM correctly?如何正确绑定 MVVM 中的 Image.Source?
【发布时间】:2016-05-25 19:21:53
【问题描述】:

我现在花了一些时间试图解决这个问题,但我仍然坚持下去。我有一个带有 MVVM 模式的 WPF 应用程序。在我的 ViewModel 中,我有三种情况:

  • X needs YY is available
  • X needs YY is not available
  • X doesn't need Y

我正在尝试根据这些条件在我的视图上设置一个图像图标(如复选标记、感叹号……随便什么)。

在 ViewModel 中: 我创建了我的属性。在任何 GUI 更改时,我都会根据上述情况设置变量,类似于以下内容:

void MyBigFunctionToSetAllProperties()
{
   // other cases
   // ..
   if (NeedsY && YExists)
    {
        // properties
        StatusIconPath = "@\"/Resources/SessionView/X-With-Green-Check-White.png\"";
        ResultIconPath = "@\"/Resources/SessionView/Y-White.png\"";
    }
}

View.Cs 中:我实际上什么也没做。

View.xaml: 我这样绑定:

<StackPanel>
     <Image Source="{Binding StatusIconPath} />
</StackPanel>

我仍然不明白为什么它不起作用。我错过了什么?请和谢谢。

按照建议将属性直接与 Xaml 绑定是行不通的。我是这样尝试的:

VM:示例属性:

public BitmapImage VerificationStatusIcon{ get { return new BitmapImage(new Uri(@VerificationStatusIconPath, UriKind.Relative));}}

查看 Xaml

<Image Name="verificationStatusImage" Source="{Binding VerificationStatusIcon}" Margin="5,0" Width="40" Height="40"/>

【问题讨论】:

  • 您的视图模型类是否实现了INotifyPropertyChangedStatusIconPath 的 Setter 是否正确提升了PropertyChanged
  • @brad 我对 textBlock 绑定使用相同的描述例程并且它正在工作,它只是不适用于图像。你能看看OP编辑吗?谢谢
  • 当绑定发生时,您是否在 Visual Studio 的“输出”窗口中看到任何绑定错误?我还将验证图像实际上是否作为资源正确嵌入,并且您使用的资源路径是否正确。有时这些在 WPF 中看起来很奇怪。
  • 有关如何在 WPF 中通过路径引用资源的一些示例,请参见此页面。 msdn.microsoft.com/en-us/library/aa970069(v=vs.100).aspx 您最终可能会得到一条类似于 pack://application:,,,/ResourceFile.png 的路径
  • @brad 我添加了我的输出。有趣,谢谢。我正在挖掘更多

标签: c# wpf mvvm binding


【解决方案1】:

您的图标路径中有一大堆不必要的字符:

StatusIconPath = "@\"/Resources/SessionView/X-With-Green-Check-White.png\"";
ResultIconPath = "@\"/Resources/SessionView/Y-White.png\"";

把它们改成这样:

StatusIconPath = "Resources/SessionView/X-With-Green-Check-White.png";
ResultIconPath = "Resources/SessionView/Y-White.png";

【讨论】:

  • 使用完整的资源文件包 URI,例如 "pack://application:,,,/Resources/SessionView/Y-White.png",并确保图像文件的 Build Action 设置为 Resource
  • @Clemens 虽然完整包 URI 可能更安全,但我测试了本地字符串,就像 OP 在测试项目中一样,没有任何问题。只要它在同一个程序集中就应该没问题。
  • 这是正确的,凯尔。但是,我需要在我的 View.cs 中设置我的Image.Source = new BitMapImage(new Uri(@WhateverThisPathIs, UriKind.Relative));。我将编辑我的 OP 以包含它
  • 并且路径一开始需要/。像这样:"/Resources/..."
  • @FirstStep 我不确定为什么会这样。我完全按照我在这里的方式测试了这个解决方案,它在没有前导斜杠并且没有显式创建ImageSource 的情况下运行良好(这让我很惊讶,我认为绑定引擎不会执行那种特定的转换)。
【解决方案2】:

。但最初没有可查看的图像,也没有任何变化..

验证图像的路径是否正确。也许硬编码一个图像来测试它的控制。

另一种情况是资源没有被复制以进行运行时获取。确保它们在运行时实际可用。

不明白为什么它不工作

主视图的 DataContext 是否设置为实时 VM 的实例?

我错过了什么?

如果您确定视图的数据上下文包含实时 VM,请确保 VM 上的属性 StatusIconPath 报告属性更改事件

这样,绑定到它的 XAML 控件知道它发生了变化,因此需要确保持有 StatusIconPath 的 ViewModel 遵守INotifyPropertyChanged,这将促进这种一般操作:

private string _StatusIconPath;

public string StatusIconPath 
{
   get { return _StatusIconPath; }
   set
       {
       _StatusIconPath = value;
       PropertyChanged("StatusIconPath");
       }
}

我在我的博客上提供了更强大的示例,标题为:

Xaml: ViewModel Main Page Instantiation and Loading Strategy for Easier Binding

【讨论】:

  • 我不认为这是问题所在,因为它正在使用 TextBlock 绑定。你能看看OP编辑吗?谢谢
  • @FirstStep 我更新了我的答案...听起来图像位置可能无法解析。
  • 图像文件在解决方案的资源中,我在文件夹资源管理器中看到它们。还是行不通。如果你能分析一下,我添加了我的输出。我现在正在挖掘更多
  • @FirstStep 看起来资源要么没有被复制(用于运行时),要么文件的路径错误。
  • 如果您想编辑和反映它,我可以让它工作。感谢您的帮助
【解决方案3】:

事实证明,正如 Kyle 所说,我的 ImagePaths 中有多余的字符。然后,我需要在我的 View.cs 中设置我的Image.Source。至少,这对我来说是这样的:

ViewModel 像这样的:

if (Whatever)
{
    StatusIconPath = "/Resources/SessionView/X-With-Green-Check-White.png";
    ResultIconPath = "/Resources/SessionView/Y-White.png";
}

然后在 View.csSelectedItemChanged:

private void Grid_SelectedItemChanged(object sender, DevExpress.Xpf.Grid.SelectedItemChangedEventArgs e)
{
    string tempStatus = ((SessionViewModel) DataContext).StatusIconPath;
    string tempResult = ((SessionViewModel) DataContext).ResultIconPath;
    StatusImage.Source = new BitmapImage(new Uri(@tempStatus, UriKind.Relative));
    ResultImage.Source = new BitmapImage(new Uri(@tempResult, UriKind.Relative));
}

Xaml: 中只是一个备用值(我们想要的任何原始/默认图像)。例如:

<Image Name="ResultImage" Source="/EZ3D;component/Resources/SessionView/Retake-White.png"/>

【讨论】:

    猜你喜欢
    • 2011-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-29
    相关资源
    最近更新 更多