Search code examples
c#wpfxamldata-bindingdatatemplate

Set default value in XAML if binding is null


EDIT

This is no duplicate of a fallback for string null values. I'm asking for a fallback for a complex type.

Original question

This is a followup question to a question I've asked yesterday:

Bind WPF Command to ViewModel property in C# XAML

The core part of the accepted answer to me was this:

<Window.Resources>
    <DataTemplate DataType="{x:Type local:SettingsPathSelectorViewModel}">
        <StackPanel Orientation="Horizontal">
            <TextBox Text="{Binding SettingsPath}" />
            <Button 
                Content="..." 
                Command="{Binding OpenFile}" 
                HorizontalAlignment="Left" 
                MinWidth="40" 
                Margin="4,0,0,0" 
                />
        </StackPanel>
    </DataTemplate>
</Window.Resources>
<Grid>
    <StackPanel Orientation="Vertical">
        <Label>First Path</Label>
        <ContentControl Content="{Binding FirstPath}" />
    </StackPanel>
</Grid>

A DataTemplateis created for a custom type and then a ContentControl is bound to a property of that type.

The problem is now, that the property (FirstPath in the example) could be null and no UI elements are rendered. How could I accomplish to render the controls from the DataTemplate even if the property is null

As Evk suggested I've implemented a Converter:

public class PathSelectorConverter : IValueConverter
{
    public object Convert(object o, Type type, object parameter, CultureInfo culture)
    {
        return o ?? new PathSelector();
    }
    public object ConvertBack(object o, Type type, object parameter, CultureInfo culture)
    {
        return o ?? new PathSelector();
    }
}

I've added an instance of the converter a resource in my window:

<view:PathSelectorConverter x:Key="pathSelectorConverter"/>

And added it in the binding to the property:

But the converter is only called if the value is not null


Solution

  • I found the answer to this problem in another question of mine (The code is from Clemens):

    <Window.Resources>
        <model:PathSelector x:Key="FallbackPathSelector" />
    </Window.Resources>
    ...
    
    <ContentControl Content="{Binding MyPathSelector,
                              FallbackValue={StaticResource FallbackPathSelector}}"/>