Skip to main content

Language Specification

  • 6 minutes to read

DevExpress binding mechanism uses its own language. This language combines C# and XAML rules. This topic describes these rules in detail.

Literals

The following literals are used in the same way as those in C#.

<TextBlock Text="{DXBinding 4}"/>
<TextBlock Text="{DXBinding '4'}"/>
<TextBlock Text="{DXBinding Expr='4'}"/>

<TextBlock Text="{DXBinding 4UL}"/>
<TextBlock Text="{DXBinding .4}"/>
<TextBlock Text="{DXBinding 0.4}"/>
<TextBlock Text="{DXBinding 4d}"/>
<TextBlock Text="{DXBinding 4e1}"/>
<TextBlock Text="{DXBinding 4e+1}"/>
<TextBlock Text="{DXBinding 4e-1}"/>

To define a string literal, use the ` (grave accent) symbol.

<TextBlock Text="{DXBinding `a string`}"/>
<TextBlock Text="{DXBinding Expr='`a string`'}"/>

The ‘true‘, ‘false‘, ‘null‘ words are reserved. Words ‘True‘, ‘False‘, ‘Null‘ are not literals.

<TextBlock Text="{DXBinding true}"/>
<TextBlock Text="{DXBinding false}"/>
<TextBlock Text="{DXBinding null}"/>
<TextBlock Text="{DXBinding True}"/> <!-- wrong (True is considered as a property) -->
<TextBlock Text="{DXBinding False}"/> <!-- wrong (False is considered as a property) -->
<TextBlock Text="{DXBinding Null}"/> <!-- wrong (Null is considered as a property) -->

Char constants are defined as follows:

<TextBlock Text="{DXBinding Expr='`a`[0]'}"/>

Properties

The following properties are used in the same way as those in C#.

<!--DevExpress DXBinding--> 
<TextBlock Text="{DXBinding 'Customer.FirstName + ` ` + Customer.LastName'}"/>
<!--Standard approach-->
<TextBlock>
    <TextBlock.Text>
        <MultiBinding Converter="{local:Converter}">
            <Binding Path="Customer.FirstName"/>
            <Binding Path="Customer.LastName"/>
        </MultiBinding>
    </TextBlock.Text>
</TextBlock>

Functions

You can invoke functions inside the DXBinding‘s expression and pass parameters to them.

<TextBlock Text="{DXBinding 'Calculate()'}"/>
<TextBlock Text="{DXBinding 'Calculate(PropA, PropB.Prop1 + 2).PropC'}"/>
<Button Command="{DXCommand 'Calculate(PropA, PropB.Prop1 + 2)'}"/>
<UserControl Loaded="{DXEvent 'Calculate(PropA, PropB.Prop1 + 2)'}"/>

Indexer

The indexer is used in the same way as the one in C#.

<TextBlock Text="{DXBinding '[1]'}"/>
<TextBlock Text="{DXBinding 'Property[1+1]'}"/>

The DXBinding extension does not support notifications for indexer properties.

Types and Static Properties

Type definitions start with the $ symbol.

There are some primitive types: $int, $double, …, $string, $object, $bool.

The XAML engine resolves the other types.

<TextBlock Text="{DXBinding '$int.MaxValue'}"/>
<TextBlock Text="{DXBinding '$Window.CurrentWindow'}"/>
<TextBlock Text="{DXBinding '$dx:DXWindow.CurrentWindow'}"/>
<!-- Using enums -->
<TextBlock Text="Text" Visibility="{DXBinding $Visibility.Hidden}"/>

The typeof word is reserved.

<TextBlock Text="{DXBinding 'typeof($int)'}"/>
<TextBlock Text="{DXBinding 'typeof($Window)'}"/>
<TextBlock Text="{DXBinding 'typeof($dx:DXWindow)'}"/>

The ? symbol is used for declaring nullable types: $int?, $Type?, $dx:Type?.

Type Casting

Type casting statements are the same as those in C#.

<TextBlock Text="{DXBinding '(double)1'}"/>
<TextBlock Text="{DXBinding '(PropertyA as $dx:DXWindow).CurrentWindow'}"/>

Attached Properties

Attached Properties are used in the same way as those in standard bindings. Note that the “$“ (dollar) sign should be used to specify a defining type.

<TextBlock Text="{DXBinding '($Window.AttachedProperty).SubProperty'}"/>
<TextBlock Text="{DXBinding 'Property.($Window.AttachedProperty).SubProperty'}"/>

Operators

The DXBinding supports the following operators:

  • Arithmetic operators

              Operator Name          

              Syntax          

       Alternative Syntax   

    Unary plus

    +a

    -

    Unary minus

    -a

    -

    Addition

    a + b

    -

    Subtraction

    a - b

    -

    Multiplication

    a * b

    -

    Division

    a / b

    -

    Modulo

    a % b

    -

  • Comparison and relational operators

              Operator Name          

              Syntax          

       Alternative Syntax   

    Equal to

    a eq b

    a == b

    Not equal to

    a ne b

    a != b

    Greater than

    a gt b

    a > b

    a &gt; b

    Less than

    a lt b

    a &lt; b

    Greater than or equal to

    a ge b

    a >= b

    a &gt;= b

    Less than or equal to

    a le b

    a &lt;= b

    Type compatibility

    a is b

    -

    Type conversion

    a as b

    (b)a

    -

  • Logical operators

              Operator Name          

              Syntax          

       Alternative Syntax   

    Not

    !a

    -

    And

    a and b

    a &amp;&amp; b

    Or

    a or b

    a || b

    Condition

    a ? b : c

    -

    Null Coalesce

    a ?? b

    -

  • Bitwise operators

              Operator Name          

              Syntax          

       Alternative Syntax   

    Not

    ~a

    -

    And

    a &amp; b

    -

    Or

    a | b

    -

    Xor

    a ^ b

    -

    Left shift

    a shl b

    a &lt;&lt; b

    Right shift

    a shr b

    a >> b

    a &gt;&gt; b

  • new operator. Creates a new instance of a specified class.

    Margin="{DXBinding 'new $Thickness(LeftIndent, 0, 0, 0)'}"
    
  • Assignment operator =. Only the DXEvent and DXCommand extensions support this operator.

    <Button Click="{DXEvent '@e(checkBox).IsChecked=true'}"/>
    <Button Command="{DXCommand '@e(checkBox).IsChecked=true'}"/>
    

The operator priority is the same as in C#.

Special Words

The DXBinding language supports some reserved words. These words specify locations relative to the target’s position.

  • @s, @Self

    <!--DevExpress DXBinding-->
    <TextBlock Text="{DXBinding '@s.PropA'}"/>
    <TextBlock Text="{DXBinding '@Self.PropA'}"/>
    <!--Standard approach-->
    <TextBlock Text="{Binding 'PropA', RelativeSource={RelativeSource Self}}"/>
    
  • @p, @TemplatedParent

    <!--DevExpress DXBinding-->
    <TextBlock Text="{DXBinding '@p.PropA'}"/>
    <TextBlock Text="{DXBinding '@TemplatedParent.PropA'}"/>
    <!--Standard approach-->
    <TextBlock Text="{Binding 'PropA', RelativeSource={RelativeSource TemplatedParent}}"/>
    
  • @e, @ElementName

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

    <FrameworkElement.Resources>
        <sys:Double x:Key="resource">1</sys:Double>
    </FrameworkElement.Resources>
    <!--DevExpress DXBinding-->
    <TextBlock Text="{DXBinding '@r(resource)'}"/>
    <TextBlock Text="{DXBinding '@StaticResource(resource)'}"/>
    <!--Standard approach-->
    <TextBlock Text="{Binding Source={StaticResource resource}}"/>
    
  • @a, @FindAncestor

    <!--DevExpress DXBinding-->
    <TextBlock Text="{DXBinding '@a($Window).Title'}"/>
    <TextBlock Text="{DXBinding '@FindAncestor($Window).Title'}"/>
    <TextBlock Text="{DXBinding '@a($Window, 1).Title'}"/>
    <TextBlock Text="{DXBinding '@FindAncestor($Window, 1).Title'}"/>
    <!--Standard approach-->
    <TextBlock Text="{Binding 'Title', RelativeSource={RelativeSource AncestorType={x:Type Window}, AncestorLevel=1}}"/>
    
  • @c, @DataContext

    <!--DevExpress DXBinding-->
    <TextBlock Text="{DXBinding 'PropA'}"/>
    <TextBlock Text="{DXBinding '@c.PropA'}"/>
    <TextBlock Text="{DXBinding '@DataContext.PropA'}"/>
    <TextBlock Text="{DXBinding '@c'}"/>
    <TextBlock Text="{DXBinding '@DataContext'}"/>
    <!--Standard approach-->
    <TextBlock Text="{Binding 'PropA'}"/>
    <TextBlock Text="{Binding '.PropA'}"/>
    <TextBlock Text="{Binding '.'}"/>
    
  • @Reference

    <Button x:Name="bt"/>
    <!--DevExpress DXBinding-->
    <TextBlock Text="{DXBinding '@Reference(bt).Content'}"/>
    <!--Standard approach-->
    <TextBlock Text="{Binding 'Content', Source={x:Reference bt}}"/>
    

When specifying the DXBinding.BackExpr property, you can use the @v or @value reserved word to access the input value.

<Control IsEnabled="{DXBinding Expr='!IsDisabled', BackExpr='!@v'}"/>
<Control Visibility="{DXBinding Expr='IsVisible ? `Visible` : `Collapsed`', BackExpr='@v == $Visibility.Visible'}"/>

When the DXCommand markup extension is used, you can use all the DXBinding’s special words plus the @parameter word to access the CommandParameter.

<TextBlock x:Name="tb" Text="text"/>
<Button Content="OK" Command="{DXCommand Execute='Save(@parameter)', CanExecute='CanSave(@parameter)'}" CommandParameter="{DXBinding @e(tb).Text}"/>

The DXEvent markup extension supports all the DXBinding’s special words plus the @sender and @args words to access the event sender and event arguments.

<TextBlock x:Name="tb" Text="text"/>
<Button Content="OK" Loaded="{DXEvent Handler='Initialize(@sender.Content, @args, @e(tb).Text)'}"/>

Typization

DXBinding, DXCommand, DXEvent use interpretation. This allows using dynamic typization, so you do no need to cast values.

Value1 and Value2 can be of different types in the code sample below:

{DXBinding 'BooleanValue ? IntegerValue : StringValue'}

Such expressions are invalid in C#.

Limitations

  • Generic types are not supported.
  • Nested types are not supported.
  • Non-latin symbols are not supported in property names.
  • The @Reference special word is not supported in DataTemplates.