Image control doesn't get rendered - c#

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.

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;
}
}

Related

XPS export from WPF - only one image is exported

I want to export the content from WPF app (C#,MVVM) to XPS.
I have a bunch of objects and every object contains an image (type=BitmapFrame), which is displayed using source property:
<Image Source="{Binding BusinessUnit.Picture}" />
All those objects are placed on a control called GraphCanvas. Every picture is loaded and it is properly displayed on a screen.
When using the export code:
using (var package = Package.Open(saveFileDialog.FileName, FileMode.Create))
{
var xpsDocument = new XpsDocument(package);
var writer = XpsDocument.CreateXpsDocumentWriter(xpsDocument);
writer.Write(GraphCanvas.ExportCanvas);
xpsDocument.Close();
}
everything is exported properly except of images. Only one image is exported (and it's available in resources folder when browsing through XPS structure) and this one image is used as a substitution for every other image that should be exported.
What might be a reason that all the other images are not exported?
I've faced similar issue when printing multiple pages, and eventually I had to iterate on each Item in page and do this:
fwElement.Arrange(new Rect(new Size(fwElement.ActualWidth, fwElement.ActualHeight)));
Since you have only single element, this might work for you:
GraphCanvas.ExportCanvas.Measure(GraphCanvas.ExportCanvas.RenderSize);
GraphCanvas.ExportCanvas.Arrange(new Rect(new Size(GraphCanvas.ExportCanvas.ActualWidth, GraphCanvas.ExportCanvas.ActualHeight)));
writer.Write(GraphCanvas.ExportCanvas);
I know this question is old, but I had the same issue in my WPF MVVM (I'm using DevExpress MVVM) app, and my resolution may help others in the future.
I had a page of several images, and when printing the 1st image on the page replaced all the other images! I'm not sure why it did this.
Each of my image UI controls was bound to a byte array, and the images displayed perfectly in the app. I resolved the print issue by converting my byte arrays to a BitmapImage to which each image UI control was bound. All images print correctly now.
My View XAML:
<Image Grid.Row="0" Grid.Column="0" Source="{Binding Bitmap[0]}" />
<Image Grid.Row="0" Grid.Column="1" Source="{Binding Bitmap[1]}" />
<Image Grid.Row="0" Grid.Column="2" Source="{Binding Bitmap[2]}" />
<Image Grid.Row="0" Grid.Column="3" Source="{Binding Bitmap[3]}" />
My ViewModel bound properties:
private List<BitmapImage> bitmap;
public virtual List<BitmapImage> Bitmap
{
get { return bitmap; }
set { bitmap= value; }
}
My code for printing each child view in a TabControl (some tabs contained other UI objects other than images):
public void PrintDocument(TabControl control)
{
PrintDocumentImageableArea area = null;
XpsDocumentWriter dw = PrintQueue.CreateXpsDocumentWriter(ref area);
SerializerWriterCollator c = dw.CreateVisualsCollator();
foreach (var tabitem in ((TabControl)control).Items)
{
UIElement childVisual1 = (UIElement)((TabItem)tabitem).Content;
var outputSize = new Size(area.MediaSizeHeight, area.MediaSizeWidth);
((UIElement)childVisual1).Measure(outputSize);
((UIElement)childVisual1).Arrange(new Rect(outputSize));
((UIElement)childVisual1).UpdateLayout();
if (c != null) c.Write(childVisual1);
}
if (c != null) c.EndBatchWrite();
}
This article helped with WPF printing with XPS

WPF Using Image Control to dynamically view Online images

Situation
I'm trying to use an image control in my program that accesses an online image by binding it to a property.
XAML:
<Image Source="{Binding TheImage}" x:Name="imgPic" HorizontalAlignment="Left" Height="113" Margin="14,89,0,0" VerticalAlignment="Top" Width="120"/>
Specifically, I'm binding to the return value of the searchMembers method (which returns an object) mempic contains a URL, and this mempic will change depending on which member is currently logged in.
View Model:
public Uri TheImage
{
get
{
return new Uri(hillracing.searchMembers(Username).mempic);
}
}
Problem
Neither this code, or a static link to the image actually works.
Here is the test image I'm actually using
wondered if anyone could tell em what I was doing wrong.
thanks.
The WPF Image control is more sophisticated than you imagine... just use the string URI value as the Image.Source directly like this:
<Image Source="http://i.imgur.com/aIf7B0P.jpg" />
Or, if you want to data bind, do this:
<Image Source="{Binding TheImage}" ... />
...
public string TheImage
{
get { return "http://i.imgur.com/aIf7B0P.jpg"; }
}

How can I change the StaticResource used in a VisualBrush from code behind in response to the correct user input?

I have a rectangle with the fill set to an icon from the icon set that comes with MahApps.Metro
Here's the code
<Rectangle x:Name="urlIcon" HorizontalAlignment="Left" Height="26" Margin="448,48,0,0" VerticalAlignment="Top" Width="28">
<Rectangle.Fill>
<VisualBrush Visual="{StaticResource appbar_warning}" />
</Rectangle.Fill>
</Rectangle>
In the XAML design I have a URL box that gets user input web address. In the code behind, I check if the web address is reachable, if it is, then I'd like to change the Static Resource to another icon "appbar_check"
Here's the event method for the URL box. urlExists is another method that does the checking of the url.
private void urlBox_LostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
String url = ((TextBox)sender).Text;
if (urlExists(url))
{
//change icon
}
}
You can access the resource to fill the rectangle as below
urlIcon.Fill = new VisualBrush() { Visual = (Visual)Resources["appbar_check"] };
also since your resources are UIElements then inorder to use them multiple places you need to set <Canvas x:Shared="false" > on the canvas resource in order to return a new resource everytime you ask. Otherwise it will give an error that the visual is already child of some other control.
As I am on learning curve of WPF I am not sure of the syntax.
But you can try something like this.
urlIcon.Fill(new VisualBrush(...))
May this help you or give you an idea
For that kind of use, you might better use DynamicResource.

Silverlight ComboBox bound to IEnumerable<BitmapImage> where images are downloaded from server

I am having an issue with binding a ComboBox to an IEnumerable<BitmapImage>, where the images are stored on the server and downloaded on demand. At the time the binding actually takes place, most of the images have not downloaded yet and causes the ComboBox to display empty selections in their place. Is there an easy way of forcing the bound images to update as their download completes. I would like to do this asynchronously; i.e., I don't want to wait until they are all downloaded before binding the list to the ComboBox.
All suggestions are welcome, including proposing alternative approaches.
I'm experiencing a similar problem. My hacked solution is to set each BitmapImage to a dummy Image control's source. As long as the Image control is visible, it works. Then I just collapse the Image after every BitmapImage was "loaded".
I´m working on a similar solution. The way i display images in a combobox and load them on demand is, that i define an Image-Control as DataTemplate and bind the the Source of the Image-Control to the URL of corresponding image file.
This way it´s up to the Image control to load the Image on Demand (when it gets displayed)
XAML:
<ComboBox Items="{Binding Images}">
<ComboBox.ItemTemplate>
<DataTemplate>
<Image Source="{Binding ImageUrl}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
C#:
public class ImageViewModel{
public string ImageUrl {get; set;}
}

Problem assigning source property to Image Control WPF

I have a WPF C# project that I am working on and I have multiple (25) Image controls arranged in table (5 columns, 5 rows). Each Image control is called "Image[row][column]" (eg:Image15).
Assigning a different source to the control works fine with ony one problem. No matter which control I use (Image11, Image12, Image 55) it affects Image11. No matter which one I try to change I'll end up changing the first one (Image11). This is the source change code:
BitmapImage src3 = new BitmapImage();
src3.BeginInit();
src3.UriSource = new Uri(#"D:\Electricity\CONSUMER_ON.jpg");
src3.EndInit();
Image15.Source = src3;
This does change the image but acts as if I had written "Image11.Source = src3;". Here's the XAML code just in case it might have anything to do with it.
<Image Height="150" HorizontalAlignment="Left" Margin="11,10,0,0" Name="Image11" Stretch="Fill" VerticalAlignment="Top" Width="150" />
... 23 more lines removed ...
<Image Height="150" HorizontalAlignment="Left" Margin="635,634,0,0" Name="Image55" Stretch="Fill" VerticalAlignment="Top" Width="150" />
if you need any other info, please ask. The images are 200x200 and in JPEG format and are displayed correctly (in the wrong place). The Images for the controls are determined and loaded at run-time.
Are you remembering to create a new BitmapImage for each image control, or are you recycling the same object but changing its contents when you move between images? If you set the source of two Image controls to the same ImageSource and then alter that image, both controls will reflect the changes.

Categories