Back to Devexpress

How to: Customize the Cell Appearance

wpf-9199-controls-and-libraries-pivot-grid-examples-appearance-how-to-customize-the-appearance-of-cells.md

latest12.5 KB
Original Source

How to: Customize the Cell Appearance

  • Jul 09, 2019
  • 6 minutes to read

The following example demonstrates how to customize the appearance of the pivot grid cells.

xaml
<Window xmlns:dxpg="http://schemas.devexpress.com/winfx/2008/xaml/pivotgrid"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="540" Width="895"
        x:Class="CustomAppearance.MainWindow"
        Loaded="Window_Loaded">
    <Grid>
        <dxpg:PivotGridControl CustomCellAppearance="OnCustomAppearance" GridLayout="OnGridLayout"
                               VerticalAlignment="Top" HorizontalAlignment="Left"
                               Name="pivotGridControl1">
            <dxpg:PivotGridControl.Fields>
                <dxpg:PivotGridField Name="fieldCategoryName" FieldName="CategoryName" Area="RowArea"
                                     Caption="Product Category" />
                <dxpg:PivotGridField Name="fieldProductName" FieldName="ProductName" Area="RowArea"
                                     Caption="Product Name" />
                <dxpg:PivotGridField Name="fieldCustomer" FieldName="Sales Person" Area="FilterArea" 
                                     Caption="Customer" />
                <dxpg:PivotGridField Name="fieldYear" FieldName="OrderDate" Area="ColumnArea"
                                     Caption="Year" GroupInterval="DateYear" />
                <dxpg:PivotGridField Name="fieldQuarter" FieldName="OrderDate" Area="ColumnArea"
                                     Caption="Quarter" ValueFormat="Quarter 0" 
                                     GroupInterval="DateQuarter" />
                <dxpg:PivotGridField Name="fieldMonth" FieldName="OrderDate" Area="ColumnArea"
                                     Caption="Month" GroupInterval="DateMonth" />
                <dxpg:PivotGridField Name="fieldExtendedPrice" FieldName="Extended Price" Area="DataArea"
                                     CellFormat="c0" />
            </dxpg:PivotGridControl.Fields>
        </dxpg:PivotGridControl>
    </Grid>
</Window>
vb
Imports Microsoft.VisualBasic
Imports System
Imports System.Windows
Imports System.Windows.Media
Imports CustomAppearance.DataSet1TableAdapters
Imports DevExpress.Xpf.PivotGrid

Namespace CustomAppearance
    Partial Public Class MainWindow
        Inherits Window
        Private salesPersonDataTable As New DataSet1.SalesPersonDataTable()
        Private salesPersonDataAdapter As New SalesPersonTableAdapter()
        Private minValue, maxValue, minTotalValue, maxTotalValue As Decimal
        Private maxMinCalculated As Boolean
        Public Sub New()
            InitializeComponent()
            pivotGridControl1.DataSource = salesPersonDataTable
        End Sub
        Private Sub Window_Loaded(ByVal sender As Object, ByVal e As RoutedEventArgs)
            salesPersonDataAdapter.Fill(salesPersonDataTable)
            pivotGridControl1.CollapseAll()
        End Sub

        ' Handles the CustomCellAppearance event. Sets the current cell's foreground color
        ' to a color generated in a custom manner.
        Private Sub OnCustomAppearance(ByVal sender As Object, ByVal e As PivotCustomCellAppearanceEventArgs)
            If Not(TypeOf e.Value Is Decimal) Then
                Return
            End If
            Dim value As Decimal = CDec(e.Value)
            Dim isGrandTotal As Boolean = Me.IsGrandTotal(e)
            If IsValueNotFit(value, isGrandTotal) Then
                ResetMaxMin()
            End If
            EnsureMaxMin()
            If IsValueNotFit(value, isGrandTotal) Then
                Return
            End If
            e.Foreground = New SolidColorBrush(GetColorByValue(value, Me.IsGrandTotal(e)))
        End Sub

        Private Function IsValueNotFit(ByVal value As Decimal, ByVal isGrandToatl As Boolean) As Boolean
            If isGrandToatl Then
                Return value < minTotalValue OrElse value > maxTotalValue
            Else
                Return value < minValue OrElse value > maxValue
            End If
        End Function
        Private Sub OnGridLayout(ByVal sender As Object, ByVal e As RoutedEventArgs)
            ResetMaxMin()
        End Sub

        ' Generates a custom color for a cell based on the cell value's share 
        ' in the maximum summary or total value (for summary and total cells),
        ' or in the maximum Grand Total value (for Grand Total cells).
        Private Function GetColorByValue(ByVal value As Decimal, ByVal isGrandTotal As Boolean) As Color
            Dim variation As Integer
            If isGrandTotal Then
                variation = Convert.ToInt32(510 * (value - minTotalValue) / (maxTotalValue - minTotalValue))
            Else
                variation = Convert.ToInt32(510 * (value - minValue) / (maxValue - minValue))
            End If
            Dim r, b As Byte
            If variation >= 255 Then
                r = Convert.ToByte(510 - variation)
                b = 255
            Else
                r = 255
                b = Convert.ToByte(variation)
            End If
            Return Color.FromRgb(r, 0, b)
        End Function
        Private Function IsGrandTotal(ByVal e As PivotCustomSummaryEventArgs) As Boolean
            Return e.RowField Is Nothing OrElse e.ColumnField Is Nothing
        End Function
        Private Function IsGrandTotal(ByVal e As PivotCellBaseEventArgs) As Boolean
            Return e.RowValueType = FieldValueType.GrandTotal OrElse e.ColumnValueType = FieldValueType.GrandTotal
        End Function

        ' Calculates the maximum and minimum summary and Grand Total values.
        Private Sub EnsureMaxMin()
            If maxMinCalculated Then
                Return
            End If
            For i As Integer = 0 To pivotGridControl1.RowCount - 1
                For j As Integer = 0 To pivotGridControl1.ColumnCount - 1
                    Dim val As Object = pivotGridControl1.GetCellValue(j, i)
                    If Not(TypeOf val Is Decimal) Then
                        Continue For
                    End If
                    Dim value As Decimal = CDec(val)
                    Dim isGrandTotal As Boolean = pivotGridControl1.GetFieldValueType(True, j) = FieldValueType.GrandTotal OrElse pivotGridControl1.GetFieldValueType(False, i) = FieldValueType.GrandTotal
                    If isGrandTotal Then
                        If value > maxTotalValue Then
                            maxTotalValue = value
                        End If
                        If value < minTotalValue Then
                            minTotalValue = value
                        End If
                    Else
                        If value > maxValue Then
                            maxValue = value
                        End If
                        If value < minValue Then
                            minValue = value
                        End If
                    End If
                Next j
            Next i
            If minTotalValue = maxTotalValue Then
                maxTotalValue += 1
            End If
            If minValue = maxValue Then
                maxValue += 1
            End If
            maxMinCalculated = True
        End Sub

        ' Resets the maximum and minimum summary and Grand Total values.
        Private Sub ResetMaxMin()
            minValue = Decimal.MaxValue
            maxValue = Decimal.MinValue
            minTotalValue = Decimal.MaxValue
            maxTotalValue = Decimal.MinValue
            maxMinCalculated = False
        End Sub
    End Class
End Namespace
csharp
using System;
using System.Windows;
using System.Windows.Media;
using CustomAppearance.DataSet1TableAdapters;
using DevExpress.Xpf.PivotGrid;

namespace CustomAppearance {
    public partial class MainWindow : Window {
        DataSet1.SalesPersonDataTable salesPersonDataTable = new DataSet1.SalesPersonDataTable();
        SalesPersonTableAdapter salesPersonDataAdapter = new SalesPersonTableAdapter();
        decimal minValue, maxValue, minTotalValue, maxTotalValue;
        bool maxMinCalculated;
        public MainWindow() {
            InitializeComponent();
            pivotGridControl1.DataSource = salesPersonDataTable;
        }
        void Window_Loaded(object sender, RoutedEventArgs e) {
            salesPersonDataAdapter.Fill(salesPersonDataTable); 
            pivotGridControl1.CollapseAll();
        }

        // Handles the CustomCellAppearance event. Sets the current cell's foreground color
        // to a color generated in a custom manner.
        void OnCustomAppearance(object sender, PivotCustomCellAppearanceEventArgs e) {
            if(!(e.Value is decimal)) return;
            decimal value = (decimal)e.Value;
            bool isGrandTotal = IsGrandTotal(e);
            if(IsValueNotFit(value, isGrandTotal))
                ResetMaxMin();
            EnsureMaxMin();
            if(IsValueNotFit(value, isGrandTotal))
                return;
            e.Foreground =
                new SolidColorBrush(GetColorByValue(value, IsGrandTotal(e)));
        }

        bool IsValueNotFit(decimal value, bool isGrandToatl) {
            if(isGrandToatl)
                return value < minTotalValue || value > maxTotalValue;
            else
                return value < minValue || value > maxValue;
        }
        void OnGridLayout(object sender, RoutedEventArgs e) {
            ResetMaxMin();
        }

        // Generates a custom color for a cell based on the cell value's share 
        // in the maximum summary or total value (for summary and total cells),
        // or in the maximum Grand Total value (for Grand Total cells).
        Color GetColorByValue(decimal value, bool isGrandTotal) {
            int variation;
            if(isGrandTotal) {
                variation = 
                    Convert.ToInt32(510 * (value - minTotalValue) / (maxTotalValue - minTotalValue));
            } else {
                variation = 
                    Convert.ToInt32(510 * (value - minValue) / (maxValue - minValue));
            }
            byte r, b;
            if(variation >= 255) {
                r = Convert.ToByte(510 - variation);
                b = 255;
            } else {
                r = 255;
                b = Convert.ToByte(variation);
            }
            return Color.FromRgb(r, 0, b);
        }
        bool IsGrandTotal(PivotCustomSummaryEventArgs e) {
            return e.RowField == null || e.ColumnField == null;
        }
        bool IsGrandTotal(PivotCellBaseEventArgs e) {
            return e.RowValueType == FieldValueType.GrandTotal || 
                e.ColumnValueType == FieldValueType.GrandTotal;
        }

        // Calculates the maximum and minimum summary and Grand Total values.
        void EnsureMaxMin() {
            if(maxMinCalculated) return;
            for(int i = 0; i < pivotGridControl1.RowCount; i++)
                for(int j = 0; j < pivotGridControl1.ColumnCount; j++) {
                    object val = pivotGridControl1.GetCellValue(j, i);
                    if(!(val is decimal)) continue;
                    decimal value = (decimal)val;
                    bool isGrandTotal =
                      pivotGridControl1.GetFieldValueType(true, j) == FieldValueType.GrandTotal ||
                      pivotGridControl1.GetFieldValueType(false, i) == FieldValueType.GrandTotal;
                    if(isGrandTotal) {
                        if(value > maxTotalValue)
                            maxTotalValue = value;
                        if(value < minTotalValue)
                            minTotalValue = value;
                    } else {
                        if(value > maxValue)
                            maxValue = value;
                        if(value < minValue)
                            minValue = value;
                    }
                }
            if(minTotalValue == maxTotalValue)
                maxTotalValue++;
            if(minValue == maxValue)
                maxValue++;
            maxMinCalculated = true;
        }

        // Resets the maximum and minimum summary and Grand Total values.
        void ResetMaxMin() {
            minValue = decimal.MaxValue;
            maxValue = decimal.MinValue;
            minTotalValue = decimal.MaxValue;
            maxTotalValue = decimal.MinValue;
            maxMinCalculated = false;
        }
    }
}