Back to Devexpress

How to: Edit a Cell with the Cell Editing Template

wpf-401118-controls-and-libraries-pivot-grid-examples-binding-to-data-how-to-edit-cell-value.md

latest7.9 KB
Original Source

How to: Edit a Cell with the Cell Editing Template

  • Jul 11, 2019
  • 3 minutes to read

The PivotGrid control does not support the data editing functionality out of the box because it displays aggregated data. This example demonstrates how to implement a custom CellTemplate with the in-place editing functionality.

This example implements the base editing features. It does not allow going to the next cell by pressing the tab or arrow keys.

The PivotGridEditHelper class implements the in-place cell editor. When editing is finished, the editor calls the pvotGridControl1_OnCellEdit method. This method retrieves the underlying data for the edited cell and adjusts them so that their sum equals the new value entered in the cell.

View Example: How to Edit a Cell with the Cell Editing Template

xaml
<dx:ThemedWindow
    x:Class="HowToEditCell.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
    xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors"
    xmlns:dxpg="http://schemas.devexpress.com/winfx/2008/xaml/pivotgrid"
    xmlns:local="clr-namespace:HowToEditCell"
    Width="800"
    Height="450"
    Loaded="Window_Loaded"
    Title="How to Edit Cell">

    <Grid>
        <dxpg:PivotGridControl
            x:Name="pivotGridControl1"
            local:PivotGridEditHelper.OnCellEdit="pivotGridControl1_OnCellEdit"
            local:PivotGridEditHelper.UseHelper="{Binding RelativeSource={RelativeSource Self}}">
            <dxpg:PivotGridControl.Fields>
                <dxpg:PivotGridField
                    x:Name="fieldSales"
                    Area="DataArea"
                    Caption="Product Sales"
                    FieldName="ExtendedPrice">
                    <dxpg:PivotGridField.CellTemplate>
                        <DataTemplate>
                            <dxe:TextEdit
                                x:Name="edit"
                                HorizontalContentAlignment="Right"
                                DisplayFormatString="c2"
                                EditMode="InplaceInactive"
                                EditValue="{Binding Value, Mode=OneWay}"
                                local:PivotGridEditHelper.LostFocusCommand="{x:Static local:PivotGridEditHelper.Enter}"
                                Mask="[0-9]*\.[0-9]{0,2}"
                                MaskType="RegEx">
                                <dxe:TextEdit.InputBindings>
                                    <KeyBinding
                                        Key="Enter"
                                        Command="{x:Static local:PivotGridEditHelper.Enter}"
                                        CommandParameter="{Binding ElementName=edit}" />
                                    <MouseBinding
                                        Command="{x:Static local:PivotGridEditHelper.StartEdit}"
                                        CommandParameter="{Binding ElementName=edit}"
                                        MouseAction="LeftClick" />
                                </dxe:TextEdit.InputBindings>
                            </dxe:TextEdit>
                        </DataTemplate>
                    </dxpg:PivotGridField.CellTemplate>
                </dxpg:PivotGridField>
                <dxpg:PivotGridField
                    x:Name="fieldYear"
                    AllowFilter="False"
                    Area="ColumnArea"
                    Caption="Year"
                    FieldName="OrderDate"
                    GroupInterval="DateYear" />
                <dxpg:PivotGridField
                    x:Name="fieldCategoryName"
                    Area="RowArea"
                    AreaIndex="0"
                    Caption="Category"
                    FieldName="CategoryName" />
                <dxpg:PivotGridField
                    x:Name="fieldProductName"
                    Area="RowArea"
                    AreaIndex="1"
                    Caption="Product"
                    FieldName="ProductName" />
                <dxpg:PivotGridField
                    Area="DataArea"
                    Caption="Percent Of Column"
                    CellFormat="p"
                    FieldName="ExtendedPrice"
                    Name="fieldExtendedPrice2"
                    SummaryDisplayType="PercentOfColumn" />
            </dxpg:PivotGridControl.Fields>
        </dxpg:PivotGridControl>
    </Grid>

</dx:ThemedWindow>
csharp
using System;
using System.Collections.ObjectModel;
using System.Windows;
using DevExpress.Xpf.Core;
using DevExpress.Xpf.PivotGrid;

namespace HowToEditCell {
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : ThemedWindow {

        public ObservableCollection<MyOrderRow> OrderSourceList { get; set; }

        public MainWindow() {
            InitializeComponent();
        }

        void Window_Loaded(object sender, RoutedEventArgs e) {
            OrderSourceList = DatabaseHelper.CreateData();
            pivotGridControl1.DataSource = OrderSourceList;
            pivotGridControl1.BestFit();
        }

        void pivotGridControl1_OnCellEdit(DependencyObject sender, PivotCellEditEventArgs args) {
            PivotGridControl pivotGrid = (PivotGridControl)sender;
            PivotGridField fieldExtendedPrice = pivotGrid.Fields["ExtendedPrice"];
            PivotDrillDownDataSource ds = args.CreateDrillDownDataSource();
            decimal difference = args.NewValue - args.OldValue;
            decimal factor = (difference == args.NewValue) ? (difference / ds.RowCount) : (difference / args.OldValue);
            for(int i = 0; i < ds.RowCount; i++) {
                decimal value = Convert.ToDecimal(ds[i][fieldExtendedPrice]);
                decimal newValue = (value == 0m) ? factor : value * (1m + factor);
                ds.SetValue(i, fieldExtendedPrice, newValue);
            }
        }
    }
}
vb
Imports System
Imports System.Collections.ObjectModel
Imports System.Windows
Imports DevExpress.Xpf.Core
Imports DevExpress.Xpf.PivotGrid

Namespace HowToEditCell
    ''' <summary>
    ''' Interaction logic for MainWindow.xaml
    ''' </summary>
    Partial Public Class MainWindow
        Inherits ThemedWindow

        Public Property OrderSourceList() As ObservableCollection(Of MyOrderRow)

        Public Sub New()
            InitializeComponent()
        End Sub

        Private Sub Window_Loaded(ByVal sender As Object, ByVal e As RoutedEventArgs)
            OrderSourceList = DatabaseHelper.CreateData()
            pivotGridControl1.DataSource = OrderSourceList
            pivotGridControl1.BestFit()
        End Sub

        Private Sub pivotGridControl1_OnCellEdit(ByVal sender As DependencyObject, ByVal args As PivotCellEditEventArgs)
            Dim pivotGrid As PivotGridControl = CType(sender, PivotGridControl)
            Dim fieldExtendedPrice As PivotGridField = pivotGrid.Fields("ExtendedPrice")
            Dim ds As PivotDrillDownDataSource = args.CreateDrillDownDataSource()
            Dim difference As Decimal = args.NewValue - args.OldValue
            Dim factor As Decimal = If(difference = args.NewValue, (difference / ds.RowCount), (difference / args.OldValue))
            For i As Integer = 0 To ds.RowCount - 1
                Dim value As Decimal = Convert.ToDecimal(ds(i)(fieldExtendedPrice))
                Dim newValue As Decimal = If(value = 0D, factor, value * (1D + factor))
                ds.SetValue(i, fieldExtendedPrice, newValue)
            Next i
        End Sub
    End Class
End Namespace