0

I am trying to create a WPF application with multiple small editors. One of these editors requires to load two images, enter a name in a TextBox and hit a save button.

In the code this does work flawless. The files are saved in a model and the image can be loaded. Before hitting the save button both of the images are actually shown in the editor. However after reopening (for editing) only one image is rendered.

I tested a bit around and found out that always the first image doesn't get rendered while the second does.

For example in the XAML it looks like this:

<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"/> 

Here BackgroundImage doesn't get rendered, even though the property Background of the model has loaded the image successfully. If I were to swap these XAML Tags, meaning putting the ForegroundImage control above the BackgroundImage, then ForegroundImage doesn't get rendered while BackgroundImage does. Even if I don't change anything else like the Grid.Row or Column.

Then I tried to load the images in the code behind in the Loaded event handler of the window:

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

The same applies to this situation. Whichever line is executed first, won't be rendered in the Window.

In case it'll help, here's the code of the Background property (Foreground is built the same):

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

The SetFree() method frees up memory resources if the image isn't needed anymore. This occurs when the window closes or whenever the BitmapImage is needed. (It'll reload the image each time in case the file of the image has changed.)

The SetImage() method does just one simple thing: Loading the image of the BackgroundFile image file and saves it in the _background field.


I don't quite know what the problem could be. I've tried out a few things but I don't work often with images while coding.

6
  • Can you provide more xaml code? What controls are the images in? One tool that might help you is a visual tree inspector like Snoop which you can use to view UI elements and their values in real time. Commented Oct 15, 2018 at 20:53
  • @user2619824 The controls are just in a Grid which has no extra parameters. And that grid is a direct child of the window. So nothing fancy there. I'll check out Snoop. Thanks for the hint. Commented Oct 15, 2018 at 20:58
  • Your view model property implementations are looking odd. Please show us the SetFree and SetImage methods. How do these methods know whether it's the Background or the Foreground property? Commented Oct 16, 2018 at 5:18
  • Besides that, did you try to bind directly to the BackgroundFile path, like <Image Source="{Binding BackgroundFile}"/>? This should also work, because there is built-in type conversion. Commented Oct 16, 2018 at 5:22
  • @Clemens 2 I didn't know it can convert automatically to an image. I tried binding it directly to the file path and....it works. I suppose I somehow made a mistake with the SetFree method, though I still don't know why it "technically" works for the second image. Maybe submit it as answer? It was what helped me after all. Commented Oct 16, 2018 at 7:47

1 Answer 1

1

There must be something wrong with your SetFree() or SetImage() methods.

Fortunately you don't need the Background and Foreground properties in your view model at all, because WPF provides built-in automatic type conversion from string, Uri and byte[] to ImageSource. You can hence directly bind the Image's Source properties to the appropriate path properties in the view model:

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

For completeness, if you still wanted to have these properties, i'd suggest a simple implementation like shown below. Built-in image caching will take care that the file is not decoded more often than necessary:

public ImageSource Background { get { if (BackgroundFile != null) { try { return new BitmapImage(new Uri(BackgroundFile)); } catch (Exception ex) { Debug.WriteLine(ex.Message); } } return null; } } 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.