图片控件无法呈现

时间:2018-10-15 20:45:17

标签: c# wpf

我正在尝试使用多个小型编辑器来创建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"/>

即使模型的属性 Background 已成功加载图像,也不会渲染 BackgroundImage 。如果我要交换这些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 字段中


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

2 个答案:

答案 0 :(得分:1)

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

幸运的是,您不需要在视图模型中使用BackgroundForeground属性,因为WPF提供了stringUri的内置自动类型转换功能和byte[]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;
    }
}

答案 1 :(得分:-1)

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

<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();
        }
    }
相关问题