FunctionBindingBehavior

  • 8 minutes to read

The FunctionBindingBehavior class is a special behavior that allows you to bind the function result to your View.

Getting Started

Suppose that you have a function in your View Model that filters some collection, and you want to bind the function result to your View.

Below is a code snippet of ViewModel.

public class MainViewModel {
    protected MainViewModel() { ... }

    public static MainViewModel Create() {
        return ViewModelSource.Create(()=>new MainViewModel());
    }

    public virtual ObservableCollection<DataItem> Points { get; set; }

    public IList<DataItem> GetFilteredItems(DateTime start, DateTime end) {
        return this.Points.Where(x => x.Date.Date >= start && x.Date.Date <= end).ToList();
    }
}

To bind the View's ChartControl and ViewModel's GetFilteredItems function, use the FunctionBindingBehavior. For this, add the behavior to the ChartControl's dxmvvm:Interaction.Behaviors collection.

<dxc:ChartControl ... >
    <dxc:ChartControl.Diagram>
        <dxc:SimpleDiagram2D>
            <dxc:SimpleDiagram2D.Series>
                <dxc:FunnelSeries2D x:Name="Series" ... >
                    ...
                </dxc:FunnelSeries2D>
            </dxc:SimpleDiagram2D.Series>
        </dxc:SimpleDiagram2D>
    </dxc:ChartControl.Diagram>
    ...
    <dxmvvm:Interaction.Behaviors>
        <dxmvvm:FunctionBindingBehavior />
    </dxmvvm:Interaction.Behaviors>
</dxc:ChartControl>

Specify the FunctionBindingBehavior's properties in their corresponding order.

<dxmvvm:Interaction.Behaviors>
    <dxmvvm:FunctionBindingBehavior         
        Target="{Binding ElementName=Series}"       
        Property="DataSource" 
        Source="{Binding}"
        Function="GetFilteredItems" 
        Arg1="{Binding SelectionRangeStart, ElementName=rangeControl}" 
        Arg2="{Binding SelectionRangeEnd, ElementName=rangeControl}"/>
</dxmvvm:Interaction.Behaviors>
  • The Target property contains an object whose property will be populated (by default, the target-object is the behavior's associated object). Since the ChartControl shows data in a series, the ChartControl's Series FunnelSeries2D is used as Target.
  • The property of target-object should be specified using the Property property. The FunnelSeries2D shows data specified in the DataSource property. Thus, set Property to DataSource.
  • The Source property contains an object whose function will be bound to the target-property specified in Function (by default, the source-object is an object located in the data context of the associated object.). Due to the fact that the source-function is defined at the ViewModel level, bind the Source property to the ViewModel.
  • The source-function name is specified by the Function property.
  • The FunctionBindingBehavior also provides several properties that correspond to the source-function parameters: Arg1, Arg2... Arg15. You can specify no more than 15 arguments.

Invoking the Bound Function

By default, the FunctionBindingBehavior automatically re-invokes the Function when one of the arguments is changed (updated). If you need to manually re-invoke the Function, you can use the POCOViewModelExtensions.UpdateFunctionBinding extension method.

public static class POCOViewModelExtensions {
    public static void UpdateFunctionBinding<T>(this T viewModel, Expression<Action<T>> methodExpression) { ... }
    ...
}

Below is a code snippet that illustrates how to use the UpdateFunctionBinding method.

public class MainViewModel {
    ...
    public void Update() {
        this.UpdateFunctionBinding(x => x.GetFilteredItems(default(DateTime), default(DateTime)));
    }
}

Arguments Conversion

The FunctionBindingBehavior automatically converts its specified arguments to the parameterized type, if possible. Suppose that you have the following source-function in your View Model.

public enum DocumentType { Text, Data }

public IList<Documents> ShowDocument(DocumentType parameter) {
...
}

In this case, the parameter specified in the Arg1 property will be automatically converted to the DocumentType parameterized type.

Declaration by Using SmartTag

To assign the FunctionBindingBehavior to the required control at design time, click the Smart Tag button SmartTagButton at the top right corner of the control.

FunctionBindingBehavior_SmartTag_01

Open the MVVM tab and add the FunctionBindingBehavior item using the Add Behavior menu.

FunctionBindingBehavior_SmartTag_02

Specify the Target (by default, it is the behavior's associated object).

FunctionBindingBehavior_SmartTag_03

Choose the target's property from the drop-down list.

FunctionBindingBehavior_SmartTag_04

Select the source object (by default, the source object is the DataContext of the target object) and the function of the source object, and specify its arguments. Smart Tag will generate argument property lines depending on the maximum number of the chosen function parameters. The maximum number of argument property lines is 15.

FunctionBindingBehavior_SmartTag_05

The following screenshot demonstrates the result.

FunctionBindingBehavior_SmartTag_06

The auto generated XAML for the above is the following.

<Grid>
   ...
   <dxc:ChartControl Name="chartControl1" ...>
      <dxc:ChartControl.Diagram>
          <dxc:SimpleDiagram2D>
              <dxc:SimpleDiagram2D.Series>
                  <dxc:FunnelSeries2D x:Name="Series" ... >
                      ...
                  </dxc:FunnelSeries2D>
              </dxc:SimpleDiagram2D.Series>
          </dxc:SimpleDiagram2D>
      </dxc:ChartControl.Diagram>
      ...
      <dxmvvm:Interaction.Behaviors>
          <dxmvvm:FunctionBindingBehavior
              Property="DataSource"
              Target="{Binding ElementName=Series}"
              Function="GetFilteredItems"
              Arg1="{Binding SelectionRangeStart, ElementName=rangeControl}"
              Arg2="{Binding SelectionRangeEnd, ElementName=rangeControl}"/>
      </dxmvvm:Interaction.Behaviors>
   </dxc:ChartControl>
   <dxe:RangeControl Name="rangeControl" ...>
      ...
   </dxe:RangeControl>
</Grid>

Example

Imports System
Imports System.Linq
Imports System.Collections.Generic
Imports DevExpress.Mvvm.POCO

Namespace FunctionBindingExample.Common
    Public Class DataItem
        Protected Sub New(ByVal [date] As Date, ByVal valueSummary As Double, ByVal stageName As String)
            Me.Date = [date]
            Me.ValueSummary = valueSummary
            Me.StageName = stageName
        End Sub

        Public Shared Function Create(ByVal [date] As Date, ByVal valueSummary As Double, ByVal stageName As String) As DataItem
            Return ViewModelSource.Create(Function() New DataItem([date], valueSummary, stageName))
        End Function

        Public Property [Date]() As Date
        Public Property ValueSummary() As Double
        Public Property StageName() As String
    End Class
End Namespace