Dave M
Dave M

Reputation: 3033

WPF Bind to a different property path when binding value is null

I need to do something similar to a PriorityBinding, except the lower priority binding is used when the binding is null (not when the binding is invalid like in a PriorityBinding). I can't seem to figure out a 'good' way to do this short of creating two duplicate controls one with each binding I want to use and triggering their visibility based on whether or not the binding is null. There must be a better way as I do not want to update two controls every time I need to change something (duplicate code == bad).

Example:

when SelectedItem.SelectedItem is not null:

<ContentControl Content="{Binding SelectedItem.SelectedItem}"/>

and when SelectedItem.SelectedItem is null:

<ContentControl Content="{Binding SelectedItem}"/>

using a Style like this did not work:

<ContentControl Content="{Binding SelectedItem.SelectedItem}">
    <ContentControl.Style>
        <Style TargetType="ContentControl">
            <Style.Triggers>
                <DataTrigger Binding="{Binding SelectedItem.SelectedItem}" Value="{x:Null}">
                    <Setter Property="Content" Value="{Binding SelectedItem}"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </ContentControl.Style>
</ContentControl>

I'm guessing this did not work because the bindings in the style are trying to use the ContentControl's Content property as their source so the DataTrigger is acually testing SelectedItem.SelectedItem.SelectedItem.SelectedItem. Any ideas?

Upvotes: 0

Views: 2264

Answers (1)

Florian Gl
Florian Gl

Reputation: 6014

You could use MultiBinding to achive what you want:

<ContentControl Content="{Binding SelectedItem.SelectedItem}">
    <ContentControl.Content>
        <MultiBinding Converter="{StaticResource ResourceKey=myConverter}">
            <Binding Path="SelectedItem"/>
            <Binding Path="SelectedItem.SelectedItem"/>
        </MultiBinding>
    </ContentControl.Content>
</ContentControl>

Your Converter could look like

public class MyMultiConverter:IMultiValueConverter
{
   public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
   {
      if (values[1] == null)
          return values[0];

      return values[1];
   }

   public object[] ConvertBack(object values, Type[] targetType, object parameter, CultureInfo culture)
   {
      return null;
   }
}

Upvotes: 4

Related Questions