# Binding to a Collection of Fields | WPF Controls | DevExpress Documentation

When engineering a WPF application using the Model View ViewModel (MVVM) architectural pattern, you may be required to describe fields in a Model or ViewModel. The Pivot Grid can be bound to a collection of objects containing field settings, described in a Model or ViewModel, thus minimizing the need for ‘code-behind’.

## View Model Implementation

Note

In this tutorial PivotGrid is bound to the Sales Person view of the Northwind database. You can find it at *C:\Users\Public\Documents\DevExpress Demos 26.1\Components\Data\nwind.mdb*.

Create a view model. In this tutorial the view model includes the following classes:

- *ViewModel* - the Sales Person view model.
- *Field* - describes the Pivot Grid fields. This class provides properties that correspond to settings common to all Pivot Grid fields.
- *FieldTemplateSelector* - describes the Pivot Grid template selector. This class allows you to choose the required template based on the specified condition.

- C#

<section id="tabpanel_zN7pFzQpso_tabid-csharp" role="tabpanel" data-tab="tabid-csharp">
<pre><code data-code-links="{&quot;/ (System.Windows)(?:;|$)/&quot;:&quot;https://learn.microsoft.com/dotnet/api/system.windows&quot;,&quot;/ (System.Windows.Controls)(?:;|$)/&quot;:&quot;https://learn.microsoft.com/dotnet/api/system.windows.controls&quot;,&quot;/ (System.Collections.ObjectModel)(?:;|$)/&quot;:&quot;https://learn.microsoft.com/dotnet/api/system.collections.objectmodel&quot;,&quot;/ (DevExpress.Xpf.PivotGrid)(?:;|$)/&quot;:&quot;/WPF/DevExpress.Xpf.PivotGrid&quot;}" class="lang-csharp">using System.Windows;
using System.Windows.Controls;
using System.Collections.ObjectModel;
using DevExpress.Xpf.PivotGrid;

namespace Model{
  public class ViewModel {

    // The collection of Pivot Grid fields.
    public ObservableCollection&lt;Field&gt; Fields { get; private set; }

    // The view model that contains the field settings.
    public ViewModel() {
      Fields = new ObservableCollection&lt;Field&gt;() {
        new Field() { FieldName=&quot;CategoryName&quot;, AreaIndex=0, FieldArea = FieldArea.RowArea, UniqueName=&quot;fieldCategory&quot; },
        new Field() { FieldName=&quot;Country&quot;, AreaIndex=0, FieldArea = FieldArea.ColumnArea, UniqueName=&quot;fieldCountry&quot; },
        new Field() { FieldName=&quot;Sales Person&quot;, AreaIndex=1, FieldArea = FieldArea.ColumnArea, UniqueName=&quot;fieldSalesPerson&quot; },
        new Field() { FieldName=&quot;OrderDate&quot;, AreaIndex=0, FieldArea = FieldArea.FilterArea, UniqueName=&quot;fieldOrderYear&quot;,
            Interval = FieldGroupInterval.DateYear, FieldCaption = &quot;Year&quot;, GroupName=&quot;groupYearMonth&quot;, GroupIndex=0 },
        new Field() { FieldName=&quot;Extended Price&quot;, AreaIndex=0, FieldArea = FieldArea.DataArea, UniqueName=&quot;fieldPrice&quot; },
      };            
    }
  }

  public class Field {
    public string FieldName { get; set; }
    public string UniqueName { get; set; }
    public string FieldCaption { get; set; }
    public FieldArea FieldArea { get; set; }
    public int AreaIndex { get; set; }
    public FieldGroupInterval Interval { get; set; }
    public string GroupName { get; set; }
    public int GroupIndex { get; set; }
  }

  public class FieldTemplateSelector : DataTemplateSelector {
    public override DataTemplate SelectTemplate(object item, DependencyObject container) {
      Field field = (Field)item;
        if(field.Interval == FieldGroupInterval.DateYear) {
          return (DataTemplate)((Control)container).FindResource(&quot;IntervalFieldTemplate&quot;);
        }
      return (DataTemplate)((Control)container).FindResource(&quot;DefaultFieldTemplate&quot;);
    }
  }
}
</code></pre></section>

Note

If the Fields collection might be changed after it has been assigned to the Pivot Grid control, it should implement the [INotifyCollectionChanged](https://docs.microsoft.com/en-us/dotnet/api/system.collections.specialized.inotifycollectionchanged) interface, so that changes made within a View Model are automatically reflected by the Pivot Grid.

## Field Templates and Selector

The Pivot Grid Control generates fields based on field templates. Using a template, you can create an unlimited number of fields in an unlimited number of Pivot Grid controls. In this example, there are two field templates: *DefaultFieldTemplate* and *ComboColumnTemplate*.

To avoid performance issues when binding to field properties, use the **dxci:DependencyObjectExtensions.DataContext** attached property. See the example below.

- XAML

<section id="tabpanel_zN7pFzQpso-1_tabid-xaml" role="tabpanel" data-tab="tabid-xaml">
<pre><code class="lang-xaml">&lt;!-- --&gt;
xmlns:dxci=&quot;http://schemas.devexpress.com/winfx/2008/xaml/core/internal&quot;
&lt;!-- --&gt;
    &lt;DataTemplate x:Key=&quot;DefaultFieldTemplate&quot;&gt;
      &lt;ContentControl&gt;
        &lt;dxpg:PivotGridField FieldName=&quot;{Binding Path=(dxci:DependencyObjectExtensions.DataContext).FieldName, RelativeSource={RelativeSource Self}}&quot;
                   Area=&quot;{Binding Path=(dxci:DependencyObjectExtensions.DataContext).FieldArea, RelativeSource={RelativeSource Self}}&quot;
                   AreaIndex=&quot;{Binding Path=(dxci:DependencyObjectExtensions.DataContext).AreaIndex, RelativeSource={RelativeSource Self}}&quot;
                   Caption=&quot;{Binding Path=(dxci:DependencyObjectExtensions.DataContext).FieldCaption, RelativeSource={RelativeSource Self}}&quot;
                   dx:XamlHelper.Name=&quot;{Binding Path=(dxci:DependencyObjectExtensions.DataContext).UniqueName, RelativeSource={RelativeSource Self}}&quot;
                   &gt;
        &lt;/dxpg:PivotGridField&gt;
      &lt;/ContentControl&gt;
    &lt;/DataTemplate&gt;
</code></pre></section>

To choose the required template based on the specified condition, use the Template Selector. In this example, the template selector is represented by the **FieldTemplateSelector** class:

- XAML
- C#

<section id="tabpanel_zN7pFzQpso-2_tabid-xaml1" role="tabpanel" data-tab="tabid-xaml1">
<pre><code class="lang-xaml">&lt;Window x:Class=&quot;WpfPivotTestExample.MainWindow&quot;
        x:Name=&quot;Form1&quot; Title=&quot;MainWindow&quot; Height=&quot;362&quot; Width=&quot;627&quot;
        xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
        xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;
        xmlns:local=&quot;clr-namespace:WpfPivotTestExample&quot;
        xmlns:dxpg=&quot;http://schemas.devexpress.com/winfx/2008/xaml/pivotgrid&quot; 
        xmlns:dx=&quot;http://schemas.devexpress.com/winfx/2008/xaml/core&quot; 
        xmlns:dxci=&quot;http://schemas.devexpress.com/winfx/2008/xaml/core/internal&quot;
        xmlns:nwindDataSetTableAdapters=&quot;clr-namespace:WpfPivotTestExample.nwindDataSetTableAdapters&quot; 
        xmlns:model=&quot;clr-namespace:Model&quot; 
        xmlns:view=&quot;clr-namespace:View&quot;&gt;
    &lt;Window.DataContext&gt;
        &lt;local:ViewModel /&gt;
    &lt;/Window.DataContext&gt;
    &lt;Window.Resources&gt;
        &lt;local:FieldTemplateSelector x:Key=&quot;FieldTemplateSelector&quot; /&gt;
        &lt;dx:TypedSimpleSource x:Key=&quot;TypedSimpleSource&quot; AdapterType=&quot;{x:Type nwindDataSetTableAdapters:SalesPersonTableAdapter}&quot; 
                              ContextType=&quot;{x:Type local:nwindDataSet}&quot; Path=&quot;SalesPerson&quot; /&gt;
        &lt;DataTemplate x:Key=&quot;DefaultFieldTemplate&quot;&gt;
            &lt;ContentControl&gt;
                &lt;dxpg:PivotGridField FieldName=&quot;{Binding Path=(dxci:DependencyObjectExtensions.DataContext).FieldName, RelativeSource={RelativeSource Self}}&quot;
                                     Area=&quot;{Binding Path=(dxci:DependencyObjectExtensions.DataContext).FieldArea, RelativeSource={RelativeSource Self}}&quot;
                                     AreaIndex=&quot;{Binding Path=(dxci:DependencyObjectExtensions.DataContext).AreaIndex, RelativeSource={RelativeSource Self}}&quot;
                                     Caption=&quot;{Binding Path=(dxci:DependencyObjectExtensions.DataContext).FieldCaption, RelativeSource={RelativeSource Self}}&quot;
                                     dx:XamlHelper.Name=&quot;{Binding Path=(dxci:DependencyObjectExtensions.DataContext).UniqueName, RelativeSource={RelativeSource Self}}&quot;
                                     &gt;
                &lt;/dxpg:PivotGridField&gt;
            &lt;/ContentControl&gt;
        &lt;/DataTemplate&gt;
        &lt;DataTemplate x:Key=&quot;IntervalFieldTemplate&quot;&gt;
            &lt;ContentControl&gt;
                &lt;dxpg:PivotGridField FieldName=&quot;{Binding Path=(dxci:DependencyObjectExtensions.DataContext).FieldName, RelativeSource={RelativeSource Self}}&quot;
                                     Area=&quot;{Binding Path=(dxci:DependencyObjectExtensions.DataContext).FieldArea, RelativeSource={RelativeSource Self}}&quot;
                                     AreaIndex=&quot;{Binding Path=(dxci:DependencyObjectExtensions.DataContext).AreaIndex, RelativeSource={RelativeSource Self}}&quot;
                                     Caption=&quot;{Binding Path=(dxci:DependencyObjectExtensions.DataContext).FieldCaption, RelativeSource={RelativeSource Self}}&quot;
                                     dx:XamlHelper.Name=&quot;{Binding Path=(dxci:DependencyObjectExtensions.DataContext).UniqueName, RelativeSource={RelativeSource Self}}&quot;
                                     GroupInterval=&quot;{Binding Path=(dxci:DependencyObjectExtensions.DataContext).Interval, RelativeSource={RelativeSource Self}}&quot;
                                     HeaderImage=&quot;{dx:DXImage Image=Calendar_16x16.png}&quot;&gt;                                     
                &lt;/dxpg:PivotGridField&gt;
            &lt;/ContentControl&gt;
        &lt;/DataTemplate&gt;
    &lt;/Window.Resources&gt;
    &lt;Grid&gt;
        &lt;!-- --&gt;
    &lt;/Grid&gt;
&lt;/Window&gt;
</code></pre></section>
<section id="tabpanel_zN7pFzQpso-2_tabid-csharp1" role="tabpanel" data-tab="tabid-csharp1" aria-hidden="true" hidden="hidden">
<pre><code data-code-links="{&quot;/ (System.Windows)(?:;|$)/&quot;:&quot;https://learn.microsoft.com/dotnet/api/system.windows&quot;,&quot;/ (System.Windows.Controls)(?:;|$)/&quot;:&quot;https://learn.microsoft.com/dotnet/api/system.windows.controls&quot;}" class="lang-csharp">using System.Windows;
using System.Windows.Controls;
using Model;

namespace View {
    public class FieldTemplateSelector : DataTemplateSelector {
        public override DataTemplate SelectTemplate(object item, DependencyObject container) {
            Field field = (Field)item;
            if(field.Interval == FieldGroupInterval.DateYear) {
                return (DataTemplate)((Control)container).FindResource(&quot;IntervalFieldTemplate&quot;);
            }
            return (DataTemplate)((Control)container).FindResource(&quot;DefaultFieldTemplate&quot;);
        }
    }
}
</code></pre></section>

If all Pivot Grid fields can be described using a single template, you have no need to create a field template selector. Instead, assign this template to the Pivot Grid’s [PivotGridControl.FieldGeneratorTemplate](/WPF/DevExpress.Xpf.PivotGrid.PivotGridControl.FieldGeneratorTemplate) property.

You can create a style to specify settings common to all fields generated using different templates. You can specify bindings to ViewModel properties within a style. This style should be assigned to the [PivotGridControl.FieldGeneratorStyle](/WPF/DevExpress.Xpf.PivotGrid.PivotGridControl.FieldGeneratorStyle) property.

## Customizing the WPF DXPivotGrid

Finally, specify the Pivot Grid’s [PivotGridControl.DataSource](/WPF/DevExpress.Xpf.PivotGrid.PivotGridControl.DataSource), [PivotGridControl.FieldsSource](/WPF/DevExpress.Xpf.PivotGrid.PivotGridControl.FieldsSource) and [PivotGridControl.FieldGeneratorTemplateSelector](/WPF/DevExpress.Xpf.PivotGrid.PivotGridControl.FieldGeneratorTemplateSelector).

| Member | Description |
| --- | --- |
| [PivotGridControl.DataSource](/WPF/DevExpress.Xpf.PivotGrid.PivotGridControl.DataSource) | Specifies the Pivot Grid’s data source. |
| [PivotGridControl.FieldsSource](/WPF/DevExpress.Xpf.PivotGrid.PivotGridControl.FieldsSource) | Specifies the source from which the Pivot Grid generates fields. |
| [PivotGridControl.FieldGeneratorTemplateSelector](/WPF/DevExpress.Xpf.PivotGrid.PivotGridControl.FieldGeneratorTemplateSelector) | Specifies the field template selector, which returns a template for each field based on the specified condition. |

The following code shows how to configure the Pivot Grid control using the ViewModel.

- XAML

<section id="tabpanel_zN7pFzQpso-3_tabid-xaml" role="tabpanel" data-tab="tabid-xaml">
<pre><code class="lang-xaml">&lt;Grid&gt;
        &lt;dxpg:PivotGridControl x:Name=&quot;pivotGridControl1&quot; 
                               DataSource=&quot;{Binding Data, Source={StaticResource TypedSimpleSource}}&quot;
                               FieldsSource=&quot;{Binding Fields }&quot; 
                               FieldGeneratorTemplateSelector=&quot;{StaticResource FieldTemplateSelector}&quot;                               
        &lt;/dxpg:PivotGridControl&gt;
    &lt;/Grid&gt;
</code></pre></section>

The image below shows the result. As you can see, the *OrderDate* field has a Calendar icon in its [field header](/WPF/7993/controls-and-libraries/pivot-grid/ui-elements/field-header).

![pivot-field-template](/WPF/images/pivot-field-template128861.png)

## Example

[How to: Bind the Pivot Grid to Fields and Groups specified in ViewModel](/WPF/118813/controls-and-libraries/pivot-grid/examples/binding-to-data/how-to-bind-the-pivot-grid-to-fields-and-groups-specified-in-viewmodel)

See Also

[Binding to a Collection of Groups](/WPF/115407/controls-and-libraries/pivot-grid/mvvm-enhancements/binding-to-a-collection-of-groups)