views:

205

answers:

1

In my M-V-VM application I have to show the user's avatar. The image is provided in a property of type ImageSource the ViewModel object. So that's what I have currently:

<Image Source="{Binding Path=UserAvatar}"/>

However, some users may not have an avatar configured, so UserAvatar is null. In that case I want to show a default avatar. Noone but the view must know about the default image, because it's just a concern of presentation.

So how can I either show the image with the given ImageSource, or a specific resource if ImageSource is null. Do I have to use some kind of DataTemplate with DataTriggers? Since now I only used them for ItemsControls, so I don't know.

+4  A: 

As you guessed correctly Templates and triggers are indeed your friend here..

Here is an implementation using the ContentControl:

<ContentControl Content="{Binding Path=UserAvatar}">
    <ContentControl.ContentTemplate>
        <DataTemplate>
            <Image x:Name="image" Source="{Binding}"/>
            <DataTemplate.Triggers>
                <DataTrigger Binding="{Binding}" Value="{x:Null}">
                    <Setter TargetName="image" Property="Source" Value="--your awesome default image here--" />
                </DataTrigger>
            </DataTemplate.Triggers>
        </DataTemplate>
    </ContentControl.ContentTemplate>
</ContentControl>

And in the situation when your default thingy is no ImageSource, and you wish to play around a bit with other controls, you can always resort to the Visibilty property:

<ContentControl Content="{Binding Path=UserAvatar}">
    <ContentControl.ContentTemplate>
        <DataTemplate>
            <Grid>
                <Image x:Name="image" Source="{Binding}" />
                <Canvas x:Name="defaultImage" Visibility="Collapsed" />
            </Grid>
            <DataTemplate.Triggers>
                <DataTrigger Binding="{Binding}" Value="{x:Null}">
                    <Setter TargetName="image" Property="Visibility" Value="Collapsed" />
                    <Setter TargetName="defaultImage" Property="Visibility" Value="Visible" />
                </DataTrigger>
            </DataTemplate.Triggers>
        </DataTemplate>
    </ContentControl.ContentTemplate>
</ContentControl>

Hope this helps..

Arcturus
+1 beat me to it :)
Cameron MacFarland
But how about the default image if there's no UserAvatar? Another ContentControl?Seems that I need a not-null DataTrigger. I just discovered http://stackoverflow.com/questions/356194/wpf-datatrigger-where-value-is-not-null, which proposes a custom ValueConverter.
Thomas Freudenberg
D'uh. Should learn to read. You're solution is exactly what I was looking for, Arcturus. There's only one point left before I accept your answer: the default avatar isn't an ImageSource but a canvas, so the Image element must be replaced somehow (or hidden)
Thomas Freudenberg
Ahh a Canvas you say.. let me edit my answer a bit ;)
Arcturus
It works, except that a DataTemplate can only have one child. Wrapping the Image and the Canvas in a Grid helps :)
Thomas Freudenberg
Ah my bad.. didnt compile it.. ;) Glad I could help!
Arcturus