3

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.

Dave Clemmer
  • 3,757
  • 12
  • 47
  • 72
Thomas Freudenberg
  • 4,960
  • 1
  • 36
  • 42

1 Answers1

6

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..

Dave Clemmer
  • 3,757
  • 12
  • 47
  • 72
Arcturus
  • 25,273
  • 10
  • 88
  • 101
  • 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 Jul 30 '09 at 13:11
  • 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 Jul 30 '09 at 13:29
  • It works, except that a DataTemplate can only have one child. Wrapping the Image and the Canvas in a Grid helps :) – Thomas Freudenberg Jul 30 '09 at 15:04
  • Ah my bad.. didnt compile it.. ;) Glad I could help! – Arcturus Jul 30 '09 at 15:13