Search code examples
wpfxamlmvvmdatatriggerframeworkelement

Conditional FrameworkElements depending on DataContext


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.


Solution

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