Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Binding a Text to Multiple Sources

0.00/5 (No votes)
27 Apr 2016 1  
This article presents a way to display a message in a single control with several sources in a priority order

Introduction

I had a situation where I had to display messages from several sources, and came up with this concept where I used converter and binding to each of the sources. This significantly simplified the design of the underlying view models, reducing coupling.

Description

The converter required to enable this functionality is derived from IMultiValueConverter. The convert method in this class basically just returns the first non-empty value from the array of values:

public sealed class FirstNotNullConverter : MarkupExtension, IMultiValueConverter
{
  public FirstNotNullConverter() { }

  public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
  {
    return values.FirstOrDefault(value => value != DependencyProperty.UnsetValue && value != null
       && value.ToString() != string.Empty);
  }

  public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
  {
    throw new NotImplementedException();
  }

  public override object ProvideValue(IServiceProvider serviceProvider)
  {
    return this;
  }
}

There is one change made to the above code from the original version: added the "value != DependencyProperty.UnsetValue" which allows the converter to work when there is no property for the Binding to bind to.

The XAML to use this convert would be as follows:

<TextBlock FontWeight="Black">
 <TextBlock.Text>
  <MultiBinding Converter="{local:FirstNotNullConverter}">
   <Binding Path="Message" />
   <Binding Path="Child.Message" />
   <Binding Path="Child.Child.Message" />
  </MultiBinding>
 </TextBlock.Text>
</TextBlock>

As can be seen in this example, in XAML, Binding can be done to child properties of the DataContext.

Compared to Priority Binding

The difference between this an a PriorityBinding is that PriorityBinding will accept any binding, null or not, whereas this will look for a non-empty value.

The XAML for the PriorityBinding in this sample is actually the following:

<TextBlock FontWeight="Black">
 <TextBlock.Text>
  <PriorityBinding >
   <Binding Path="DummnyDoesNotExist"/>
   <Binding Path="Message" />
   <Binding Path="Child.Message" />
   <Binding Path="Child.Child.Message" />
  </PriorityBinding>
 </TextBlock.Text>
</TextBlock>

Here it is obvious that the converter is providing the right result, which is the "Message Level 2" text is being displayed since the "Message Level 1" is empty (null). However the PriorityBinding is not showing the right result, and that is because the Binding with "Message Level 1" is succeeding and the result is null.

The actual XAML for the converter Binding is:

<TextBlock FontWeight="Black">
 <TextBlock.Text>
  <MultiBinding Converter="{local:FirstNotNullConverter}">
   <Binding Path="Message" />
   <Binding Path="DummnyDoesNotExist"/>
   <Binding Path="Child.Message" />
   <Binding Path="Child.Child.Message" />
  </MultiBinding>

In the middle of all the Binding Paths above there is the DummnyDoesNotExist. The above sample works even though they DummnyDoesNotExist will not be resolved. This is because the IValueConverter checks if a value is DependencyProperty.UnsetValue, and treats it like the value is resolved, and is null or string.Empty.

History

  • 04/27/2016: Initial version
  • 05/02/2016: Added PriorityBinding comparison and images

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here