How do I bind an Image dynamically in XAML? - c#

The following displays an image correctly in a silverlight usercontrol:
Image image = pagingManager.BaseApp.DatasourceManager.GetImage("helloWorld1");
ContentArea.Content = image;
...
<ContentControl x:Name="ContentArea"/>
However, I want to dynamically bind the image to XAML, e.g. like this:
#region ViewModelProperty: MainImage
private Image _mainImage;
public Image MainImage
{
get
{
return _mainImage;
}
set
{
_mainImage = value;
OnPropertyChanged("MainImage");
}
}
#endregion
...
MainImage = pagingManager.BaseApp.DatasourceManager.GetImage("helloWorld1");
And my XAML is this but the result is that it shows nothing:
<Image Source="{Binding MainImage}"/>
What do I need to put in my XAML to make it display the image object I have in my ViewModelProperty?

The Image.Source property is of type ImageSource, so your ViewModel should expose an ImageSource. Image is a control, it has nothing to do in the ViewModel.
If you do expose an Image control in your ViewModel (which is definitely a bad idea), then you should display it in a ContentControl, not an Image control :
<ContentControl Content="{Binding MainImage}" />

Related

how to display an image on xamarin forms using binding tag from image

Using xamarin forms trying to display an image using binding...followed a few online Q's already including the answer on this one https://stackoverflow.com/questions/30850510/how-to-correctly-use-the-image-source-property-with-xamarin-forms just cant seem to get the image to display...yes I knoW I can load the image by using <Image Source="Bud.jpeg"></Image> which works fine....but I would like to display it using binding....
eg..
xaml
<Image Source="{Binding imageTest}"></Image>
code
var imageTest = new Image { Aspect = Aspect.AspectFit };
imageTest.Source = ImageSource.FromFile("Guinness.jpg");
anyone any idea why? thanks
You can only bind to public properties
<Image Source="{Binding imageTest}" />
then declare a public property in your code-behind
public string imageTest { get; set; }
and then set the property value and BindingContext
imageTest = "Guinness.jpg";
this.BindingContext = this;

How do I bind to an image from an api endpoint?

Currently, I have an app where I want to display a list of image thumbnails on my layout.
I'm able to get the json response from the api endpoint and deserialize it. Now, I have an image object and in that object, I have an image preview url (the thumbnail image). My question is how do I display a list of thumbnail images in my layout?
Here's the method that gets called to display images and some property setup:
private List<string> images;
public List<string> Images
{
get { return images; }
set { SetProperty(ref images, value); }
}
private async Task DisplayImages()
{
var imageObj = await _mediaService.GetCatImages();
//imageObj.Hits[i].PreviewUrl; <-- how to a reference to the previewurl but what property should it bind to?
}
Here's my layout at the moment:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:flv="clr-namespace:DLToolkit.Forms.Controls;assembly=DLToolkit.Forms.Controls.FlowListView"
x:Class="MediaViewer.Views.ContentFolderMedia">
<flv:FlowListView FlowColumnCount="3" SeparatorVisibility="None" HasUnevenRows="false"
FlowItemTappedCommand="{Binding ItemTappedCommand}" FlowLastTappedItem="{Binding LastTappedItem}"
FlowItemsSource="{Binding Images}" >
<flv:FlowListView.FlowColumnTemplate>
<DataTemplate>
<Label HorizontalOptions="Fill" VerticalOptions="Fill"
XAlign="Center" YAlign="Center"/>
</DataTemplate>
</flv:FlowListView.FlowColumnTemplate>
</flv:FlowListView>
</ContentPage>
Where the layout should look like an image gallery (hence why I'm using this third party library: https://github.com/daniel-luberda/DLToolkit.Forms.Controls)
So, this line: FlowItemsSource="{Binding Images} should be where the binding occurs but I'm not sure to properly set the property so that it binds to the preview url and displays the image. It also makes me think... usually an image source is a name of a local image but if I'm hitting a url to see an image, do I need to do any conversion in my app to display the image from a url?
What is the structure of the list returned by your service? Let's say it is List<ImageObj>.
First you need to change your Images type:
private List<ImageObj> images;
public List<ImageObj> Images
{
get { return images; }
private set { SetProperty(ref images, value); }
}
private async Task DisplayImages()
{
Images = await _mediaService.GetCatImages()
.Select(x => x.Hit)
.ToList();
}
Then you've correctly bound your list to your Listview.
Now within the DataTemplate you need to add an Image bound to the url:
<DataTemplate>
<Image Source="{Binding PreviewUrl}" />
</DatatTemplate>
You can use FFImageLoading with a FlowListView
This will give you the ability to load the image from a url, caching, and fast loading.
Just add it to your DataTemplate and bind via the CachedImage Source property
Source="{Binding url}"

ImageFailed with GridView

I have a problem with GridView and multiple items. Each of the item has image in it, source is online image, bound to property, like this:
<GridView x:Name="gridView" Width="710" ItemTemplate="{StaticResource FirstTemplate}" AllowDrop="True" CanDragItems="True" CanReorderItems="True">
<DataTemplate x:Key="FirstTemplate">
<Grid HorizontalAlignment="Left" Width="306" Height="210">
<Border Background="White" Opacity="0.1"/>
<Image Stretch="Uniform" Width="190" Height="100" Margin="0,50,0,0" ImageFailed="ImageFailed" Source="{Binding ImagePath}"/>
</Grid>
</DataTemplate>
Image paths are like this:
www.example.com/images/1.png
www.example.com/images/2.png
www.example.com/images/3.png
and so on...
If some image not exist, for example www.example.com/images/29.png, I use the event ImageFailed, which change the source of the image to image that is located in my project (default image). Code in this event:
private void ImageFailed(object sender, ExceptionRoutedEventArgs e)
{
var image = sender as Image;
image.Source = new BitmapImage(new Uri("ms-appx:///Images/default.png"));
}
And this is working just fine, the default image is shown in the items that don't have images. But, when I scroll down the gridview, and then return to the beginning, images are messed up. Some items that had their images, now have the default image. Again when I scroll the gridview, and then return, again random changes with images.
Is this some cache problem? What could be the problem here? Or is there any better way of setting the default image source?
The source of your problem could be virtualization, i.e. reuse of item containers. When you replace a failed image by a fallback image in your ImageFailed handler, you are effectively replacing the Binding by a fixed value, so that the item container will later always show only the fallback image.
You may instead implement the ImageFailed handler in the view model, so that replacing the image with a fallback image won't break the Binding.
Add another property, e.g. Image to your item class
public class ImageItem
{
public string ImagePath { get; set; }
private BitmapImage image;
public BitmapImage Image
{
get
{
if (image == null)
{
image = new BitmapImage();
image.ImageFailed += (s, e) =>
image.UriSource = new Uri("ms-appx:///Images/default.png");
image.UriSource = new Uri(ImagePath);
}
return image;
}
}
}
and change the Binding to this:
<Image ... Source="{Binding Image}"/> // no ImageFailed handler here

Binding image to property in wpf with image from resources

i have some pictures included to my project.
this line of code works fine:
<Image Stretch="UniformToFill" Source="/Images/OffsetSituations/offsetsituation1.jpg"
but i have to change the picture from the VM so i made a property to bind to:
private ImageSource _image;
public ImageSource Image
{
get { return _image; }
set
{
if (_image == value)
return;
_image = value;
RaisePropertyChanged("Image");
}
}
from another post here on stackoverflow i got this code and changed it a bit:
string picture = "offsetsituation1";
if (!string.IsNullOrEmpty(picture))
{
var image = new BitmapImage(new Uri(String.Format("/Images/OffsetSituations/{0}.jpg", picture), UriKind.Relative));
image.Freeze(); // -> to prevent error: "Must create DependencySource on same Thread as the DependencyObject"
Image = image;
}
else
{
Image = null;
}
now in the xaml:
<Image Stretch="UniformToFill" Source="{Binding Image}" Margin="5"/>
but there never is a picture.
i added MessageBox.Show(Image.ToString()); after Image = image; to debug. it shows /Images/OffsetSituations/offsetsituation1.jpg, so the path seems to be right.
what am i doing wrong here?
WPF provide implicit converters for most of the framework types including ImageSource
all you have to do is provide the correct image path as string and let the implicit converter do the rest
so change the type of Image property to string
eg
public string Image
{
get { return _image; }
set
{
if (_image == value)
return;
_image = value;
RaisePropertyChanged("Image");
}
}
and assign the path as a string
Image = String.Format("/Images/OffsetSituations/{0}.jpg", picture);
that's all you need to show the image, rest will be handled by the framework
implicit converter are so handy in many places including this one.

WPF image source gif animation

How do I get the GIF animated to work with the code below? The problem is the image will change accordinly to few different image.
WPF:
<Image Source="{Binding ElementName=L, Path=Image}" Height="400" Width="600" Stretch="None" />
Code behind:
public readonly DependencyProperty ImageProperty;
public ImageSource ImageStatus
{
get { return (ImageSource)GetValue(ImageProperty); }
set { SetValue(ImageProperty, value); }
}
Image = new BitmapImage(new Uri("/L;component/Images/test.gif", UriKind.Relative));
EDITED:
http://eladm.wordpress.com/2009/04/02/animated-gif-support-behavior/
I have used this to make my gifs work: http://www.vcskicks.com/csharp_animated_gif.php
[edit]
I have found something for WPF: http://wpfanimatedgif.codeplex.com/
But I didn't test it!

Categories