【问题标题】:Image control doesn't get rendered图像控件未呈现
【发布时间】:2018-10-16 16:39:53
【问题描述】:

我正在尝试使用多个小型编辑器创建 WPF 应用程序。其中一个编辑器需要加载两个图像,在 TextBox 中输入名称并点击保存按钮。

在代码中,这确实完美无缺。文件保存在模型中,并且可以加载图像。在点击保存按钮之前,两个图像实际上都显示在编辑器中。然而,在重新打开(编辑)后,只渲染了一张图像。

我测试了一下,发现总是第一个图像没有被渲染而第二个被渲染。

例如在 XAML 中它看起来像这样:

<Image Name="BackgroundImage" Grid.Row="1" Grid.Column="0" Source="{Binding Path=Background}" Width="120" Height="90"/>
<Image Name="ForegroundImage" Grid.Row="2" Grid.Column="0" Source="{Binding Path=Foreground}" Width="120" Height="90"/>

这里 BackgroundImage 没有被渲染,即使模型的属性 Background 已经成功加载了图像。如果我要交换这些 XAML 标记,即把 ForegroundImage 控件放在 BackgroundImage 上方,那么 ForegroundImage 不会在 时呈现BackgroundImage 可以。即使我不更改任何其他内容,例如 Grid.Row 或 Column。

然后我尝试在窗口的Loaded事件处理程序后面的代码中加载图片:

private void LocationEditor_OnLoaded(object sender, RoutedEventArgs e)
{
    BackgroundImage.Source = ((Location)DataContext).Background;
    ForegroundImage.Source = ((Location)DataContext).Foreground;
}

这同样适用于这种情况。无论哪一行先执行,都不会在 Window 中呈现。

如果有帮助,这里是 Background 属性的代码(Foreground 构建相同):

[JsonIgnore]
public BitmapImage Background
{
    get
    {
        if (!string.IsNullOrWhiteSpace(BackgroundFile))
        {
            SetFree();
            SetImage();
        }
        else
            _background = null;
        return _background;
    }
}

如果不再需要图像,SetFree() 方法会释放内存资源。当窗口关闭或需要 BitmapImage 时,就会发生这种情况。 (如果图像文件发生变化,它会每次重新加载图像。)

SetImage() 方法只做了一件简单的事情:加载 BackgroundFile 图像文件的图像并将其保存在 _background 字段中.


我不太清楚问题可能是什么。我已经尝试了一些东西,但我在编码时不经常使用图像。

【问题讨论】:

  • 你能提供更多的xaml代码吗?图像在哪些控件中?一个可能对您有所帮助的工具是像 Snoop 这样的可视化树检查器,您可以使用它来实时查看 UI 元素及其值。
  • @user2619824 控件只是在没有额外参数的网格中。该网格是窗口的直接子级。所以那里没什么好看的。我去看看史努比。感谢您的提示。
  • 您的视图模型属性实现看起来很奇怪。请向我们展示 SetFree 和 SetImage 方法。这些方法如何知道是 Background 还是 Foreground 属性?
  • 除此之外,您是否尝试直接绑定到 BackgroundFile 路径,例如 &lt;Image Source="{Binding BackgroundFile}"/&gt;?这也应该有效,因为有内置的类型转换。
  • @Clemens 2 我不知道它可以自动转换为图像。我尝试将它直接绑定到文件路径并且....它有效。我想我不知何故在使用 SetFree 方法时犯了一个错误,尽管我仍然不知道为什么它在“技术上”适用于第二张图像。也许提交它作为答案?毕竟这对我有帮助。

标签: c# wpf


【解决方案1】:

您的SetFree()SetImage() 方法一定有问题。

幸运的是,您的视图模型中根本不需要 BackgroundForeground 属性,因为 WPF 提供了从 stringUribyte[]ImageSource 的内置自动类型转换.因此,您可以直接将 Image 的 Source 属性绑定到视图模型中的相应路径属性:

<Image ... Source="{Binding BackgroundFile}"/>
<Image ... Source="{Binding ForegroundFile}"/>

为了完整起见,如果您仍想拥有这些属性,我建议您使用如下所示的简单实现。内置图像缓存将确保文件的解码频率不会超出必要:

public ImageSource Background
{
    get
    {
        if (BackgroundFile != null)
        {
            try
            {
                return new BitmapImage(new Uri(BackgroundFile));
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }
        }

        return null;
    }
}

【讨论】:

    【解决方案2】:

    绑定问题可能很难解决。有时,评估绑定的时间并不明显或似乎没有意义。我知道这是一个通用的答案,但我使用的一个技巧是为我遇到问题的绑定添加一个“调试转换器”,可以在评估期间进行调试。它救了我几次。

    <UserControl
     xmlns:converters="clr-namespace:WhateverYourNamespaceIs.Converters">
    <UserControl.Resources>
    <converters:DebugConverter x:Key="DebugConverter"/>
    </UserControl.Resources>
    
    <Image Name="BackgroundImage" Grid.Row="1" Grid.Column="0" Source="{Binding Path=Background, Converter={StaticResource DebugConverter}" Width="120" Height="90"/>
    
    
    
    
    Here is an example of the converter.
    
    public sealed class DebugConverter : IValueConverter
        { 
    
    
            public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
            {
                //Debug.WriteLine("Debug Converter Value:" + value.ToString());
                // Since you are working with graphics, maybe just dump the size
    Debug.WriteLine("Debug Converter Value:" + value.Length().ToString());
                return (value);
            }
    
    
            public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
            {
                throw new NotImplementedException();
            }
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-12-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-23
      相关资源
      最近更新 更多