Binding images to Image in Silverlight 2 - silverlight

I'm building a Silverlight 2 application and I need to bind some images to Image object declarated in XAML. I'm doing some other binding in the application and it works just fine, I'm having problem with only images!
This is it's XAML:
<Image Source="{Binding Path=ThumbNail}" Style="{StaticResource ThumbNailPreview}" />
And this is the C# code-behind:
ThumbNail = (string)story.Element("thumbnail").Attribute("src")
I'm just parsing the URL's from a XAML file. When I try to do a foreach loop over all of the ThumbNail properties, it returns the URL as expected. As I said, all other binding works great, so it has to be a problem between the Image control and the ThumbNail property. I also tried chanding the datatype from string to Uri, but nothing happened. Could anyone help me?

I think this has already been asked and answered in StackOverflow here
The key is that the ImageSource property is not a string but a System.Windows.Media.Imaging.BitmapImage type and so needs to be converted.
HTH

Related

How does WPF handle binding to the property of a null object?

I have a listBox using an itemTemplate that contains the following line:
<Image Source="{Binding MyProperty.PossiblyNullObject.UrlProperty}"/>
Bound to this listBox is a model view collection that loads components of the items in the collection on a separate thread. The 'PossiblyNullObject' may not be set to a value when the xaml code is first rendered by the composition engine.
How does WPF handle this? Does it use a default value(no image source so no image) and continue on? Does it wait? Does it automatically detect when the value is initialized and rerenders with the new source? How does it not throw object null exceptions in the same way it would if I called 'MyProperty.PossiblyNullObject.UrlProperty' programmatically? How can I reproduce this functionality in my own code when I try to call it?
Thanks for any suggestions. I am embarrassingly new to WPF and I'm trying to tackle a problem out of my depth. The image load is a perf problem so I found a solution to load, decode, then freeze the image source on a background thread so it wouldn't lock up the UI. Unfortunately, I ran across this null exception problem when I tried replacing the image source binding with my solution that calls the same property. WPF somehow handles the possible null objects and I'd like to do it the same way to keep things clean.
In BindingBase have two properties: TargetNullValue and FallbackValue.
TargetNullValue returns your value when the value of the source is null.
FallbackValue returns your value when the binding is unable to return a value.
Example of using:
<!-- xmlns:sys="clr-namespace:System;assembly=mscorlib" -->
<Window.Resources>
<!-- Test data -->
<local:TestDataForImage x:Key="MyTestData" />
<!-- Image for FallbackValue -->
<sys:String x:Key="ErrorImage">pack://application:,,,/NotFound.png</sys:String>
<!-- Image for NULL value -->
<sys:String x:Key="NullImage">pack://application:,,,/NullImage.png</sys:String>
</Window.Resources>
<Grid DataContext="{StaticResource MyTestData}">
<Image Name="ImageNull"
Width="100"
Height="100"
Source="{Binding Path=NullString, TargetNullValue={StaticResource NullImage}}" />
<Image Name="ImageNotFound"
Width="100"
Height="100"
Source="{Binding Path=NotFoundString, FallbackValue={StaticResource ErrorImage}}" />
</Grid>
See this links, for more information:
BindingBase.TargetNullValue Property
BindingBase.FallbackValue Property
Note: The upvoted and accepted answer does not answer the question; it explains how you can get {Binding A} to work if A is null, which is trivial to handle anyway, but it does not explain what happens and how to handle the much more interesting case of {Binding A.B} when A is null, and that is specifically what the question is asking. What follows is the answer to the question as stated.
WPF generally handles the case where A is null when you use A.B in a binding; I have not tried specifically with <Image Source>, but I have tried with <DataGrid ItemsSource> and with <Button Command>.
When WPF handles these cases, what I have observed happening is that there is no error or warning in the output window, and the application malfunctions a bit, but it does not crash:
In the case of <DataGrid ItemsSource>, the DataGrid appears empty.
In the case of a <Button Command>, the button is clickable, but when you click it nothing happens.
In the case of <Image Source> I would expect that no image will appear.
(Note that all these are cases of silent failure, so whoever decided that WPF should behave this way should be shot by firing squad at the central square with great celebrations and live music and big giveaways.)
The way we generally handle these cases depends on the nature of the element at hand.
For images, if an empty image is acceptable, then you do not need to do anything. If some image must be shown despite the property being null, then the accepted answer probably provides a solution.
For grids, not showing anything when the property is null is probably the desired behavior.
For buttons, the solution is to use an additional binding to the IsEnabled property of the button.
So, for example:
<Button Command="{Binding A.B}" IsEnabled="{Binding HasA}"/>
Where HasA is defined in the viewmodel as follows:
bool HasA => A != null;

Cannot see binded imges in VS 2012 at design time in WPF

I am using MVVM to bind images to my WPF page, but I have a lot of buttons and wihout pics, hard to determine button purpose. The problem is that VS designer does not show me binded images if I use such URI:
xAxis = new BitmapImage(new Uri("/SettingsManager;component/Icons/CameraIcons/X.png",
UriKind.Relative));
But when I use:
xAxis = new BitmapImage(new Uri("../../Icons/CameraIcons/X.png", UriKind.Relative));
Designer correctly displays image.
I make binding via source:
<ToggleButton.Content> <Image Source="{Binding Source={StaticResource
CameraIcons}, Path=XAxis, Mode=OneWay,
UpdateSourceTrigger=PropertyChanged}"></Image> </ToggleButton.Content>
Does someone know why this happening?
In your first example (that doesn't work), it looks like you provide an absolute URI, but declare it as UriKind.Relative.
In your second example (that does work), it looks like you provide a relative URI, and declare it as UriKind.Relative.
I assume that is why the first example work, but the second one doesn't. You could try using UriKind.Absolute instead in the first example.

get image from resource XAML

I have a WPF application, I should set button image depending on current culture. It works fine for strings:
<Label Content="{x:Static res:Resources.Buy}"></Label>
show string depending on culture, but with image:
<Image Source="{x:Static res:Resources.GetItFree}"></Image>
I get an error. Why and how to do correctly?
I have done this before, but using a library: Infralution.Localization.Wpf. It is very simple the way of doing the images resources references:
<Window Language="{UICulture}" x:Class="WpfApp.MainWindow"
...
Icon="{Resx ResxName=WpfApp.MainWindow, Key=Window.Icon}">...</Window>
This is the final image you get (it changes with culture):
Hope this reference could helps, it works for me...

Images bound to images added to resx files using XAML

My WPF application includes a resource file MyResources.resx, containing several strings and images. Because the application will need to be localized, all my references to globalized resources must be made via named properties of the auto-generated MyResources class. The following code works well for string resources:
<Button Content="{x:Static local:Properties.MyResources.ButtonText}" />
However the same does not work for images. Assuming I have an image eflag.bmp added to the resources as a resource named Flag, I would like to be able to do something like this:
<Image Source="{x:Static local:Properties.MyResources.Flag}" />
Please note that the following alternative approach:
<Image Source="/MyNamespace;component/Resources/eflag.bmp" />
cannot be used in this case because it will not be able to handle localization. The problem can be solved using code behind but I am looking for a XAML based solution.
Turn your x:Static into a Binding.Source and add a Converter which does Bitmap to ImageSource.
Source="{Binding Source={x:Static local:Properties.MyResources.Flag},
Converter={StaticResource BitmapToImageSourceConverter}}"
Alternatively you can make the converter a custom markup extension which takes a Bitmap and returns the ImageSource in ProvideValue.
Source="{me:BitmapToImageSource {x:Static local:Properties.MyResources.Flag}}"

binding an image source in XAML

I am trying to bind an image source to my XAML through c#
this works
<Image Source="images/man.jpg"></Image>
this does not work
<Image Source="images/{Binding imagesource}"></Image>
where imagesource is a string variable in the c# file of this xaml and is being set equal to "man.jpg"
here is a way how to do it in XAML:
add this to the namespace:
xmlns:System="clr-namespace:System;assembly=mscorlib"
then add your images paths
<System:String x:Key="ImageRefresh">/Theme;component/Images/icon_refresh.png</System:String>
<System:String x:Key="ImageSearch">/Theme;component/Images/icon_search.png</System:String>
This is how you use it
<Image Height="16" Source="{StaticResource ImageSearch}" Stretch="Uniform" Width="16"/>
This works ok, but if you load your xaml style in Blend it will go bogus..
An object of type "System.String" cannot be applied to a property that expects the type "System.Windows.Media.ImageSource".
I haven't figured out yet, how to replace System:String with that Media.ImageSource... but hey.. it works for me in Visual Studio.
You can't stick a binding mid-way through the value like that. It's either a binding, or it's not. Assuming imagesource is publicly accessible via your DataContext, you could do this:
<Image Source="{Binding imagesource}"/>
However, if it's been set to "man.jpg" then it won't find the image. Either set imagesource to the full path ("images/man.jpg") or use a converter:
<Image Source="{Binding imagesource, Converter={StaticResource RelativePathConverter}}"/>
The converter would prepend "images/" onto its value. However, it may be necessary for the converter to return an ImageSource rather than a string.
Images have bitten me in the past. There is a certain lookup order involved.
When you use "image/man.jpg" it could refer to a file inside your silverlight xap, or relative to the location of XAP file. For example, it could be in YourProject.Web/ClientBin/image/man.jpg.
You should troubleshoot by using full URLs first and find out if this works.
imagesource needs to be an actual Image object, not a string.
Here is a method that will create a new Image object given a path:
public BitmapImage Load(string path)
{
var uri = new Uri(path);
return new BitmapImage(uri);
}

Resources