21

I'm using binding for source of an Image control.

<Image Source="{Binding ImageUri}"/>

But this ImageUri can be null, therefor I want to use a default image, a place holder, for that, which can be in /Assets/PlaceHolder.png for example.

How can I set a default image? thanks. (It's a WP8 app, but should not be different of WPF)

user2715606
  • 267
  • 1
  • 3
  • 9

7 Answers7

34

You can achieve it by setting TargetNullValue

<Image>
    <Image.Source>
        <Binding Path="ImageUri" >
            <Binding.TargetNullValue>
                <ImageSource>/Assets/PlaceHolder.png</ImageSource>
            </Binding.TargetNullValue>
        </Binding>
    </Image.Source>
</Image>
Nitesh
  • 7,261
  • 3
  • 30
  • 25
  • 1
    I have an application where it loads hundreds of images. How to show a default image until the actual image is loaded? – Arjun K R May 19 '14 at 07:13
  • @ArjunKR you might want to visit http://stackoverflow.com/questions/19113141/is-it-possible-to-show-default-image-before-original-load-from-server – Fandi Susanto Jul 28 '15 at 06:58
  • Brilliant! WPF never ceases to amaze me with its veering from simple elegance to frustrating verbosity. – Holf Apr 21 '18 at 14:48
  • 1
    Just to add in case it is not obvious, the "ImageUri" is a binding path to the Image control's data context's property "ImageUri" and can be changed to the appropriate path -- it's not part of ImageSource. I also had to specify my ImageSource as an assembly uri for it to work: `/AssemblyName;component/Images/Placeholder.png` – Slate Feb 14 '19 at 12:45
4

You can actually go the other way around which is a better experience in my opinion by simply using two Image controls in a Grid layout, one with the local placeholder source and one with the remote Binding. The local image is already there when you your remote binding is null. However if the binding is not null, it automatically covers the local placeholder image once it gets rendered.

<Grid>
    <Image Source="Assets/Placeholder.png"/>
    <Image Source="{Binding ImageUri}"/>
</Grid>
Shikhar
  • 1,411
  • 1
  • 11
  • 17
  • This works in theory but my images have transparent backgrounds. That means that I can see the image below my other image. How can I hide the image underneath? – Sweepster Nov 07 '17 at 00:18
  • @Sweepster Try using the ImageOpened event of the bound image. Set the opacity of the placeholder image to 0 if the image opened event of the data bound event gets successfully triggered!! – Shikhar Nov 09 '17 at 18:28
3

You can set the ImageFailed event on your image,

<Image Source="{Binding ImageUri}" ImageFailed="Image_ImageFailed"/>

and use the following C# to load a specific image in its place.

private void Image_ImageFailed(object sender, ExceptionRoutedEventArgs e)
{
    ((Image)sender).Source = new BitmapImage(new Uri("/Assets/MyDefaultImage.png", UriKind.Relative));
}
ZombieSheep
  • 29,603
  • 12
  • 67
  • 114
2

You may try this:

<Image>
    <Image.Source>
        <Binding Path="ImageUri">
            <Binding.TargetNullValue>
                <BitmapImage UriSource="/ProjName;component/Assets/PlaceHolder.png" />                    
            </Binding.TargetNullValue>
        </Binding>
    </Image.Source>
</Image>
Hossein Narimani Rad
  • 31,361
  • 18
  • 86
  • 116
1

You can use ImageFailed event and ChangePropertyAction.

This Code Snippet worked for me:

xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"

<Image x:Name="GeologyMapsLegend" Stretch="Fill" Height="150">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="ImageFailed">
            <ei:ChangePropertyAction PropertyName="Source" TargetName="GeologyMapsLegend">
                <ei:ChangePropertyAction.Value>
                    <ImageSource>
                        /LanSysWebGIS;component/Pictures/Icon/NoImageAvailable.jpg
                    </ImageSource>
                </ei:ChangePropertyAction.Value>
            </ei:ChangePropertyAction>
        </i:EventTrigger>
    </i:Interaction.Triggers>
</Image>
SeyedPooya Soofbaf
  • 2,654
  • 2
  • 29
  • 31
  • I have an application where it loads hundreds of images. How to show a default image until the actual image is loaded? – Arjun K R May 19 '14 at 07:14
1

use TargetNullValue attribute. It is very helpful if I don't want to display any image.

CinCout
  • 9,486
  • 12
  • 49
  • 67
-2

You should try to play with FallBackValue here. These two links should provide more help

WPF Binding - Default value for empty string

MSDN

Community
  • 1
  • 1
AsitK
  • 651
  • 1
  • 4
  • 14