Starting with version 18.1, the DXBinding (DXCommand, DXEvent) markup extensions moved to a new engine with dynamic typization.
Moving to dynamic typization allows us to provide the following improvements.
- With DXBinding, DXCommand, and DXEvent extensions, you have no need to cast values. In the example below, Value1 and Value2 can be of different types.
XAML{DXBinding 'something ? Value1 : Value2'}
- The DXBinding, DXCommand, and DXEvent extensions support the new operator.
XAML{DXBinding 'new $Thickness(Left, Top, 1+1, 0)'}
- The DXCommand and DXEvent extensions support the "=" operator
XAML<Button Click="{DXEvent '@e(checkBox).IsChecked=true'}"/>
<Button Command="{DXCommand '@e(checkBox).IsChecked=true'}"/>
How it works in versions prior 18.1.
Based on expression passed to DXBinding (DXEvent, DXCommand), these markup extensions build a standard Binding/MultiBinding and compile a converter.
E.g., the following code
XAML<TextBlock Text="{DXBinding '!PropA'}"/>
is converted to
XAML<TextBlock Text="{Binding 'PropA', Converter={local:DXBindingConverter}}"/>
C#public class DXBindingConverter : IValueConverter {
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
return !(bool)value;
}
...
}
DXBinding faced with some static typization limitations because it compiled the Binding converter.
Due to the static typization, you need to cast values.
E.g. In the following code sample, Value1 and Value2 must be of the same type:
XAML{DXBinding 'something ? Value1 : Value2'}
otherwise you have to cast them to a certain type.
XAML{DXBinding 'something ? ($dx:Foo)Value1 : ($dx:Foo)Value2'}
How it works starting with version 18.1
Starting with v18.1, the DXBinding (DXCommand, DXEvent) mechanism uses interpretation, not compilation. This allows using dynamic typization, so you have no need to cast used values.
In the following example, Value1 and Value2 can be of different types:
XAML{DXBinding 'something ? Value1 : Value2'}
In 18.1, if the DXBinding mechanism cannot generate a converter, it reports about all the errors in error output.
Performance
On startup
217ms - standard Binding
411ms - DXBinding 17.2
243ms - DXBinding 18.1
On triggering
191ms - standard Binding
235ms - DXBinding 17.2
278ms - DXBinding 18.1
What can stop working.
The following scenario can stop working.
E.g.
XAML{DXBinding 'Foo().MyNullableBooleanProperty.Value'}
Prior 18.1.
In the example above, due to static typization, the Foo() method returns an object of the bool? type. Nullable objects provide the Value property.
Starting with 18.1.
Due to dynamic typization, the Foo().MyNullableBooleanProperty expression may return the "true" or "false" boolean values that do not provide the Value property.
Backward Compatibility
DXBinding uses dynamic typization by default. To make it use static typisation (like in versions 17.2 and older), set CompatibilitySettings.DXBindingResolvingMode to DXBindingResolvingMode.LegacyStaticTyping like it is shown in the code sample below.
C#DevExpress.Xpf.Core.CompatibilitySettings.DXBindingResolvingMode = DXBindingResolvingMode.LegacyStaticTyping;
To enable compatibility mode for a particular binding expression, set DXBinding.ResolvingMode to DXBindingResolvingMode.LegacyStaticTyping:
XAML<TextBox Text="{DXBinding 'Foo().MyNullableBooleanProperty.Value', ResolvingMode=LegacyStaticTyping}"/>
The default DXBinding.ResolvingMode property value is null, when it is defined, the CompatibilitySettings.DXBindingResolvingMode property value is ignored.