Version

Using xamCalculationManager with xamDataGrid

Topic Overview

Purpose

This topic explains how you can use the xamCalculationManager™ control in combination with the xamDataGrid™ control to perform calculations using field values as sources and targets for the computations.

In this topic

This document contains the following sections:

  • Required Background

  • Introduction

  • Overview

  • Steps

Introduction

This topic covers the integration of the xamCalculationManager with the xamDataGrid controls; however you can apply the same steps for the other DataPresenter controls. Other controls eligible to participate in calculations conducted by the xamCalculationManager component derive from the DataPresenterBase class. These controls include:

  • xamDataPresenter™

  • xamDataGrid

  • xamDataCards™

  • xamDataCarousel™

Various parts of these controls can be used as sources and targets of calculations, including cells and summaries.

Preview

The following screenshot is a preview of the final result. Values in the Passing column are calculated based on the values of the Completions and Attempts columns. The formula for the Passing column is: Completion/Attempt*100, rounded to two decimal places. Above the grid is the xamFormulaEditor control where users can edit the formula for the Passing field of the grid. Below the grid is the Average Passing summary which is calculated by the xamCalculationManager control. Under the summary are two text blocks that demonstrate that you can use the xamCalculationManger control to access the value of a property of object registered with the control. In this case the Passing field in the third data record and the average passing score are calculated and shown in the summary.

xamCalculationManager Using with xamDataGrid.png

Overview

Following is a conceptual overview of the process:

  1. Create a new WPF project and add the required references.

  2. Add the required XML namespaces.

  3. Add the xamCalculationManager.

  4. Configure the datasource for the xamDataGrid.

  5. Add the xamDataGrid.

  6. Configure the CalculationAdapter.

  7. Configure the xamDataGrid FieldLayout.

  8. Add external references to calculated values.

  9. Add a xamFormulaEditor.

  10. Build and run your solution.

Steps

  1. Create a new WPF project and add the required references

    Start Microsoft Visual Studio and create a new Microsoft® Windows® Presentation Foundation project. Next, add the following NuGet package references to your project:

    • Infragistics.WPF.CalculationManager

    • Infragistics.WPF.DataGrids

    • Infragistics.WPF.DataGrids.Calculation

    • Infragistics.WPF.FormulaEditor

For more information on setting up the NuGet feed and adding NuGet packages, you can take a look at the following documentation: NuGet Feeds.

  1. Add the required XML namespaces

    In order to use the xamCalculationManger component in combination with the xamDataGrid control you must add the Infragistics XAML xml namespace and the Infragistics DataPresenter xml namespace declarations to the opening Window tag of the MainWindow.xaml file of your application:

    In XAML:

    <Window …
        xmlns:ig="http://schemas.infragistics.com/xaml"
        xmlns:igDP="http://infragistics.com/DataPresenter">
  2. Add the xamCalculationManager

    After adding the namespaces the next step is to add a xamCalculationManager control to your application. Place its declaration in the resources section of the window or in the main grid container. The only difference between these two approaches is how you reference the calculation manager in code. If you add it in the grid container then you will access the calculation manager through the x:Name. If you declare it as a StaticResource, then you will access it through the x:Key, using the StaticResource markup extension.

    If you choose to place it in the main grid container, the xamCalculationManager declaration should look like this:

    In XAML:

    <ig:XamCalculationManager x:Name="CalculationManager" />
  3. Configure the datasource for the xamDataGrid

    As a datasource for the xamDataGrid control you can use the Quarterbacks.xml file through an XmlDataProvider.

    1. First add the xml file to the root of your project in the solution explorer of Visual Studio

    2. Next, in the Window.Resources section add an XmlDataProvider and set its Source property to "Quarterbacks.xml"

    3. Set the XPath property to "/QuarterBack" and specify a key through which you can reference this resource later

    In XAML:

    <XmlDataProvider Source="Quarterbacks.xml"
        x:Key="QuarterbackData" XPath="/QuarterBack" />
  4. Add the xamDataGrid

    As soon as you have configured the XmlDataProvider you can move on to configuring the xamDataGrid.

    1. Begin by adding the XamDataGrid tags. Then set the control’s DataSource property to the XmlDataProvider instance:

      In XAML:

      <igDP:XamDataGrid
          DataSource="{Binding Source={StaticResource QuarterbackData}, XPath=season}"
      …
    2. Next set the CalculationManager attached property.

      In XAML:

      ig:XamCalculationManager.CalculationManager=
          "{Binding ElementName=CalculationManager}"
  5. Configure the CalculationAdapter

    Next, set the xamDataGrid’s CalculationAdapter property to an instance of the DataPresenterCalculationAdapter class. As a result of this and the previous step, the xamDataGrid will be able to participate in xamCalculationManager calculations. In order to reference formulas of the calculation manager for xamDataGrid fields, you need to set the ReferenceId property of the DataPresenterCalculationAdapter.

    In XAML:

    <igDP:XamDataGrid … >
        <igDP:XamDataGrid.CalculationAdapter>
            <igDP:DataPresenterCalculationAdapter
                ReferenceId="dataPresenterAdapter"/>
            </igDP:XamDataGrid.CalculationAdapter>
        …
    </igDP:XamDataGrid>
  6. Configure the xamDataGrid FieldLayout

    1. Turn off automatic field generation.

      Note
      Note:

      This step is not required for the xamCalculationManager to work with the xamDataGrid. However it is mentioned here because it minimizes the number of fields and thus makes the application simpler.

      By default the xamDataGrid will automatically create a field for every public property of the datasource objects. To prevent this behavior you need to do the following:

      1. Declare tags for the FieldLayoutSettings property of the xamDataGrid

      2. Add a FieldLayoutSettings object within the tags of the FieldLayoutSettings property

      3. Set the AutoGenerateFields property to False

      In XAML:

      <igDP:XamDataGrid.FieldLayoutSettings>
          <igDP:FieldLayoutSettings
              AutoGenerateFields="False" />
      </igDP:XamDataGrid.FieldLayoutSettings>
    2. Define the FieldLayout.

      1. Declare the tags for the xamDataGrid’s FieldLayouts property

      2. Add a FieldLayout to the FieldLayoutCollection of the grid and set its CalculationReferenceId property to a string that you can later use to reference the fields in the layout from formulas of the xamCalculationManager

      3. Declare the tags for the Fields collection of the FieldLayout

      4. Declare the tags for the SumamaryDefinitions

      In XAML:

      <igDP:XamDataGrid.FieldLayouts>
          <igDP:FieldLayout CalculationReferenceId="Quarterback">
              <igDP:FieldLayout.Fields>
              </igDP:FieldLayout.Fields>
              <igDP:FieldLayout.SummaryDefinitions>
              </igDP:FieldLayout.SummaryDefinitions>
          </igDP:FieldLayout>
      </igDP:XamDataGrid.FieldLayouts>
    3. Add fields to the FieldLayout FieldCollection.

      For information on how to define a FieldLayout refer to the Define a Field Layout topic. For the current sample you need a couple of numeric fields on whose values will be based the values of the calculated fields and a couple of text fields to identify different records.

      1. Add fields matching the datasource

      2. Declare tags for the Settings property of the Fields and add FieldSettings objects inside the tags

      3. Set the EditAsType property of the FieldSettings objects for the numeric fields to Int32

      4. Declare tags for the CalculationSettings of the numeric fields and add a FieldCalculationSettings object inside them

      5. Set the ReferenceId property of the FieldCalculationSettings objects to a string that you can use later to reference field values in xamCalculationManager formulas

      Note
      Note:

      This step is optional and if you do not specify a ReferenceId you can use the Field’s Name instead.

      In XAML:

      <igDP:Field Name="year" Label="Year"/>
      <igDP:Field Name="team" Label="Team"/>
      <igDP:Field Name="comp" Label="Completions">
          <igDP:Field.Settings>
              <igDP:FieldSettings EditAsType="{x:Type sys:Int32}" />
          </igDP:Field.Settings>
          <igDP:Field.CalculationSettings>
              <igDP:FieldCalculationSettings ReferenceId="compref" />
          </igDP:Field.CalculationSettings>
      </igDP:Field>
      <igDP:Field Name="att" Label="Attempts">
          <igDP:Field.Settings>
              <igDP:FieldSettings EditAsType="{x:Type sys:Int32}" />
          </igDP:Field.Settings>
          <igDP:Field.CalculationSettings>
              <igDP:FieldCalculationSettings ReferenceId="attref" />
          </igDP:Field.CalculationSettings>
      </igDP:Field>
    4. Add an unbound fields whose values will be calculated.

      Using the xamCalculationManager component you can calculate the values for unbound fields in the xamDataGrid. Each value is calculated using a predefined formula, which can be changed in code at runtime or edited through the xamFormulaEditor. When a formula is changed all values affected by the formula are recalculated. The process of adding a calculated unbound field is as follows:

      1. Add a field (in this case NumericField) and set its Name and Label (optional) properties

      2. Set its BindingType property to Unbound

      3. Declare tags for the CalculationSettings property of the field

      4. Add a FieldCalculationSettings object inside the CalculationSettings tags

      5. Set the Formula and ReferenceId properties to the FieldCalculationSettings object

      In XAML:

      <igDP:NumericField Name="pct" Label="Passing" BindingType="Unbound">
          <igDP:NumericField.CalculationSettings>
              <igDP:FieldCalculationSettings
                  Formula="round([comp]/[attref]*100,2)"
                  ReferenceId="pctref" />
          </igDP:NumericField.CalculationSettings>
      </igDP:NumericField>

      The most important part of the code snippet above is how values of other fields in the xamDataGrid control are used as sources for the formula. To reference a field you can use the value of its Name property (in the example above – "comp") or the value of the ReferenceId of its FieldCalculationSettings object ("attref").

    5. Add a calculated summary to the FieldLayout SummaryDefinitionCollection.

      Another feature of the xamCalculationManager integration with the xamDataGrid is that you can create custom summaries based on field values.

      1. Add a summary definition and set its Key

      2. Declare tags for the CalculationSettings property of the SummaryDefinition

      3. Add a SummaryCalculationSettings objects inside the tags. Set its Formula and ReferenceId properties

      In XAML:

      <igDP:SummaryDefinition Position="Left" Key="Average Passing">
          <igDP:SummaryDefinition.CalculationSettings>
              <igDP:SummaryCalculationSettings
                  Formula="average([pctref])"
                  ReferenceId="pctavgref" />
          </igDP:SummaryDefinition.CalculationSettings>
      </igDP:SummaryDefinition>

      This summary calculates the average of all values in pct fields. In the same way you can create your own summaries that use the build in and/or user defined functions of the xamCalculationManager component. As sources for summary calculations you can use field values from all records in the xamDataGrid control.

  7. Add external references to calculated values

    You can reference calculated values through the xamCalculationManager

    1. Add two text blocks and set the XamCalculationManager’s CalculationManager attached property to the calculation manager that you earlier declared

    2. Declare tags for the ControlSettings attached property of the XamCalculationManager attached property

    3. Add a ControlCalculationSettings object and set its Formula property

    In XAML:

    <TextBlock
        ig:XamCalculationManager.CalculationManager=
            "{Binding ElementName=CalculationManager}">
        <ig:XamCalculationManager.ControlSettings>
            <ig:ControlCalculationSettings
                Formula="[//dataPresenterAdapter/Quarterback(2)/pctref]" />
        </ig:XamCalculationManager.ControlSettings>
    </TextBlock>

    This code will display the value of the pct field in for third record of the datasource. You can also use references to summaries calculated by the xamCalculationManager component. The following displays the value of the calculated Average Passing summary.

    In XAML:

    <TextBlock
        ig:XamCalculationManager.CalculationManager=
            "{Binding ElementName=CalculationManager}">
        <ig:XamCalculationManager.ControlSettings>
            <ig:ControlCalculationSettings
                Formula="[//dataPresenterAdapter/Quarterback/pctavgref]" />
        </ig:XamCalculationManager.ControlSettings>
    </TextBlock>
  8. Add a xamFormulaEditor

    Another feature that you may want to use in combination with the xamDataGrid and the xamCalculationManager is integration with the xamFormulaEditor controler. Using the editor allows users to define custom formulas for fields and summaries. To take advantage of this feature, add a xamFormulaEditor to your application and set its Target property to a Field or Summary of the xamDataGrid control.

    In XAML:

    <ig:XamFormulaEditor
        Target="{Binding ElementName=dataGrid,
            Path=FieldLayouts[0].Fields[pct]}" Margin="5" />

    This code creates a xamFormulaEditor control where the users can edit the formula applied to the pct fields.

  9. Build and run your solution

Code Example: Using xamCalculationManager with xamDataGrid

The code below demonstrates the end result of the procedure above.

In XAML:

<Window …
    xmlns:ig="http://schemas.infragistics.com/xaml"
    xmlns:igDP="http://infragistics.com/DataPresenter"
    xmlns:sys="clr-namespace:System;assembly=mscorlib">

    <Window.Resources>
        <XmlDataProvider Source="Quarterbacks.xml"
            x:Key="QuarterbackData" XPath="/QuarterBack" />
    </Window.Resources>

    <Grid>
        <StackPanel>
            <ig:XamCalculationManager x:Name="CalculationManager" />
            <ig:XamFormulaEditor Margin="5"
                Target="{Binding ElementName=dataGrid, Path=FieldLayouts[0].Fields[pct]}" />
            <igDP:XamDataGrid x:Name="dataGrid"
                ig:XamCalculationManager.CalculationManager=
                    "{Binding ElementName=CalculationManager}"
                DataSource="{Binding Source={StaticResource QuarterbackData}, XPath=season}">

                <igDP:XamDataGrid.CalculationAdapter>
                    <igDP:DataPresenterCalculationAdapter
                        ReferenceId="dataPresenterAdapter" />
                </igDP:XamDataGrid.CalculationAdapter>

                <igDP:XamDataGrid.FieldLayoutSettings>
                    <igDP:FieldLayoutSettings AutoGenerateFields="False" />
                </igDP:XamDataGrid.FieldLayoutSettings>

                <igDP:XamDataGrid.FieldLayouts>
                    <igDP:FieldLayout CalculationReferenceId="Quarterback">
                        <igDP:FieldLayout.Fields>
                            <igDP:Field Name="year" Label="Year"/>
                            <igDP:Field Name="team" Label="Team"/>
                            <igDP:Field Name="comp" Label="Completions">
                                <igDP:Field.Settings>
                                    <igDP:FieldSettings
                                        EditAsType="{x:Type sys:Int32}" />
                                </igDP:Field.Settings>
                            </igDP:Field>
                            <igDP:Field Name="att" Label="Attempts">
                                <igDP:Field.CalculationSettings>
                                    <igDP:FieldCalculationSettings
                                        ReferenceId="attref" />
                                </igDP:Field.CalculationSettings>
                                <igDP:Field.Settings>
                                    <igDP:FieldSettings
                                        EditAsType="{x:Type sys:Int32}" />
                                </igDP:Field.Settings>
                            </igDP:Field>

                            <igDP:NumericField Name="pct" Label="Passing" BindingType="Unbound">
                                <igDP:NumericField.CalculationSettings>
                                    <igDP:FieldCalculationSettings
                                        Formula="round([comp]/[attref]*100,2)" ReferenceId="pctref" />
                                </igDP:NumericField.CalculationSettings>
                            </igDP:NumericField>
                        </igDP:FieldLayout.Fields>

                        <igDP:FieldLayout.SummaryDefinitions>
                            <igDP:SummaryDefinition
                                Position="Left" Key="Average Passing">
                                <igDP:SummaryDefinition.CalculationSettings>
                                    <igDP:SummaryCalculationSettings
                                        Formula="average([pctref])" ReferenceId="pctavgref" />
                                </igDP:SummaryDefinition.CalculationSettings>
                            </igDP:SummaryDefinition>
                        </igDP:FieldLayout.SummaryDefinitions>

                    </igDP:FieldLayout>
                </igDP:XamDataGrid.FieldLayouts>
            </igDP:XamDataGrid>
        <TextBlock Text="Third record Passing:" />
        <TextBlock ig:XamCalculationManager.CalculationManager=
            "{Binding ElementName=CalculationManager}">
                <ig:XamCalculationManager.ControlSettings>
                    <ig:ControlCalculationSettings
                        Formula="[//dataPresenterAdapter/Quarterback(2)/pctref]" />
                </ig:XamCalculationManager.ControlSettings>
            </TextBlock>
        <TextBlock Text="Average passing:"/>
            <TextBlock ig:XamCalculationManager.CalculationManager=
                "{Binding ElementName=CalculationManager}">
                <ig:XamCalculationManager.ControlSettings>
                    <ig:ControlCalculationSettings
                        Formula="[//dataPresenterAdapter/Quarterback/pctavgref]" />
                </ig:XamCalculationManager.ControlSettings>
            </TextBlock>
        </StackPanel>
    </Grid>
</Window>