DXBinding

  • 4 minutes to read

DXBinding is a MarkupExtension descendant that extends the standard WPF binding mechanism. With DXBinding, you can write conversion functions right in the DXBinding expression. This topic describes how the DXBinding operates and how to use it.

How DXBinding Operates

The DXBinding provides two properties: Expr and BackExpr. The first property specifies the straight conversion function. The second property specifies the back conversion function. Each property is specified with using a special language that is described in the following topic: Language Specification.

The DXBinding uses the standard binding mechanism. If there is only one property in the DXBinding's expression, the DXBinding creates a one standard binding. If there are several properties, it creates the standard MultiBinding.

<!--DevExpress DXBinding-->
<TextBlock Text="{DXBinding}"/>
<TextBlock Text="{DXBinding 'PropA'}"/>
<TextBlock Text="{DXBinding '!PropA'}"/>
<TextBlock Text="{DXBinding 'PropA+PropB'}"/>
<!--Standard approach-->
<TextBlock Text="{Binding}"/>
<TextBlock Text="{Binding 'PropA'}"/>
<TextBlock Text="{Binding 'PropA', Converter={CustomConverter}}"/>
<TextBlock>
    <TextBlock.Text>
        <MultiBinding Converter="{CustomConverter}">
            <Binding Path="PropA"/>
            <Binding Path="PropB"/>
        </MultiBinding>
    </TextBlock.Text>
</TextBlock>

If there are no parameters in the DXBinding expression; the DXBinding calculates the result of the defined expression and sets this calculated value to the Binding.Source property.

<!--DevExpress DXBinding-->
<TextBlock Text="{DXBinding '2+2'}"/>
<!--Standard approach-->
<TextBlock Text="{Binding Source='4'}"/>

When there are function invocations in the DXBinding's expression, the standard binding is created only for the part of the defined expression that ends on the first method.

<!--DevExpress DXBinding-->
<TextBlock Text="{DXBinding 'PropA.PropB.Calculate().PropC'}"/>
<!--Standard approach-->
<TextBlock Text="{Binding 'PropA.PropB', Converter={CustomConverter}}"/> 
<!--The Calculate function is invoked from the CustomConverter.-->

The function arguments used in the DXBinding's expression are also used in standard binding.

<!--DevExpress DXBinding-->
<TextBlock Text="{DXBinding 'Calculate(PropB)'}"/>
<!--Standard approach-->
<TextBlock>
    <TextBlock.Text>
        <MultiBinding Converter="{CustomConverter}">
            <Binding/>
            <Binding Path="PropB"/>
        </MultiBinding>
    </TextBlock.Text>
</TextBlock>

Relative Source in DXBinding

There are some reserved words supported by the DXBinding's language. These words specify locations relative to the position of the binding target.

  • @s, @Self
  • @p, @TemplatedParent
  • @e, @ElementName
  • @r, @StaticResource
  • @a, @FindAncestor
  • @c, @DataContext
  • @Reference

All items from the above list are described in the Language Specification topic in the Special Words section.

Two-Way Binding Mode

The DXBinding supports the Mode property in the same way as standard binding does.

The DXBinding.Expr property value can be simple or complex. If the DXBinding creates only one standard binding without any converter – this is simple DXBinding.

<Button x:Name="myButton"/>
<!--DevExpress DXBinding-->
<TextBlock Text="{DXBinding 'PropA'}"/>
<TextBlock Text="{DXBinding '@e(myButton).Content'}"/>
<!--Standard approach-->
<TextBlock Text="{Binding 'PropA'}"/>
<TextBlock Text="{Binding 'Content', ElementName=myButton}"/>

The simple DXBinding allows you to use the TwoWay or OneWayToSource binding mode without any additional customizations.

<TextBlock Text="{DXBinding 'PropA', Mode=TwoWay}"/>
<TextBlock Text="{DXBinding '@e(myButton).Content', Mode=OneWayToSource}"/>

If the DXBinding creates several bindings or it is necessary to generate a converter, then the binding is complex. In this case, it is necessary to specify the DXBinding.BackExpr property that controls the back-conversion mechanism.

<TextBlock Text="{DXBinding '!PropA', BackExpr='!$bool.Parse(@value)', Mode=TwoWay}"/>
<!--
public class DXBindingConverter : IValueConverter {
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
        return !(bool)value;
    }
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {
        return bool.Parse((string)value);
    }
}
-->

<TextBlock Tag="{DXBinding 'PropA+2', BackExpr='$int.Parse(@v)-2', Mode=TwoWay}"/>
<!--
public class DXBindingConverter : IValueConverter {
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
        return (int)value + 2;
    }
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {
        return int.Parse((string)value) - 2;
    }
}
-->

The @v or @value words are reserved and used only in the BackExpr expression. See the Special Words section in the Language Specification topic for more details.

NOTE

The BackExpr property supports the @v or @value reserved words only.

The BackExpr property does not support binding to individual collection items accessed via index notation.

The BackExpr property does not support calling methods from DataContext. This limitation occurs because DataContext is not accessible in the ConvertBack method.

If there are several binding operands in the DXBinding.Expr expression, you can specify a set of assignments in the DXBinding.BackExpr expression.

<TextBox Text="{DXBinding '!PropA', BackExpr='PropA=!@v'}"/>
<TextBox Text="{DXBinding 'FirstName + ` ` + LastName', 
    BackExpr='FirstName=@v.Split(` `[0])[0]; LastName=@v.Split(` `[0])[1]'}"/>
<!--
public class DXBindingConverter : IMultiValueConverter{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) {
        return values[0].ToString() + " " + values[1].ToString();
    }
    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) {
        object value1 = value.ToString().Split(' ')[0];
        object value2 = value.ToString().Split(' ')[1];
        return new[] { value1, value2 };
    }
}
-->

Custom Converter

The DXBinding supports the Converter (of the IValueConverter type), ConverterParameter, and ConverterCulture properties.

In straight conversion, the DXBinding resolves the input expression and passes the calculated value to the custom converter, i.e., the converter is called at the end of the conversion.

In back conversion, the converter is called before resolving the BackExpr expression.