wpfxamldata-bindingcoalescetargetnullvalue

Equiv. to Coalesce() in XAML Binding?


In SQL I can do this:

Select Coalesce(Property1, Property2, Property3, 'All Null') as Value
From MyTable 

If Property1, 2 and 3 are all null, then I get 'All Null'

How do I do this in XAML? I tried the following, but no luck:

<Window.Resources>
    <local:Item x:Key="MyData" 
                Property1="{x:Null}"
                Property2="{x:Null}"
                Property3="Hello World" />
</Window.Resources>

<TextBlock DataContext="{StaticResource MyData}">
    <TextBlock.Text>
        <PriorityBinding TargetNullValue="All Null">
            <Binding Path="Property1" />
            <Binding Path="Property2" />
            <Binding Path="Property3" />
        </PriorityBinding>
    </TextBlock.Text>
</TextBlock>

The result should be 'Hello World' but instead it is 'All Null'

I hope my question is clear.


Solution

  • You'd have to build a custom IMultiValueConverter to do that and use a MultiBinding. PriorityBinding uses the first binding in the collection that produces a value successfully. In your case, the Property1 binding resolves immediately, so it's used. Since Property1 is null, the TargetNullValue is used.

    A converter like this:

    public class CoalesceConverter : System.Windows.Data.IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, 
                object parameter, System.Globalization.CultureInfo culture)
        {
            if (values == null)
                return null;
            foreach (var item in values)
                if (item != null)
                    return item;
            return null;
        }
    
        public object[] ConvertBack(object value, Type[] targetTypes, 
                object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    

    And MultiBinding like this:

    <Window.Resources>
        <local:Item x:Key="MyData" 
                    Property1="{x:Null}"
                    Property2="{x:Null}"
                    Property3="Hello World" />
        <local:CoalesceConverter x:Key="MyConverter" />
    </Window.Resources>
    
    <TextBlock DataContext="{StaticResource MyData}">
        <TextBlock.Text>
            <MultiBinding Converter="{StaticResource MyConverter}">
                <Binding Path="Property1" />
                <Binding Path="Property2" />
                <Binding Path="Property3" />
            </MultiBinding>
        </TextBlock.Text>
    </TextBlock>