I'm using a xamPivotGrid with a FlatDataSource whose ItemsSource is an observable collection.
When an item in the observable collection changes, the pivot grid updates appropriately.
I have a problem when several items in the collection change at once. In this case, an exception is thrown is thrown from Infragistics.Olap.FlatData.FlatDataModelProvider. The stacktrace is at the end of this post.
I'd really appreciate any ideas how to fix or work around this problem.
The problem can be reproduced with the following XAML and C# code....
XAML
<Window x:Class="WpfPivot.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" xmlns:igDP="http://infragistics.com/DataPresenter" xmlns:ig="http://schemas.infragistics.com/xaml">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.7*" />
<ColumnDefinition Width="0.3*" />
</Grid.ColumnDefinitions>
<ig:XamPivotGrid Grid.Column="0" Grid.Row="0" Name="grid" DataSource="{Binding}" />
<ig:XamPivotDataSelector Grid.Column="1" Grid.Row="0" Name="selector" DataSource="{Binding}" />
</Grid>
</Window>
Codebehind
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading;
using System.Windows;
using Infragistics.Olap;
using Infragistics.Olap.FlatData;
namespace WpfPivot
{
public partial class MainWindow : Window
private readonly Random _rand;
public MainWindow()
_rand = new Random();
InitializeComponent();
Loaded += OnLoaded;
}
public void OnLoaded(object sender, RoutedEventArgs args)
var data = GetData();
var flatDataSource = new FlatDataSource
Cube = DataSourceBase.GenerateInitialCube("cube"),
ItemsSource = data,
};
DataContext = flatDataSource;
PeriodicallyChangeData(data,4);
private void PeriodicallyChangeData(IList<MyPivotItemType> data, int numberToUpdatePerIteration)
new Thread(() =>
while (true)
Dispatcher.Invoke((Action) (() =>
for (int i = 0; i < numberToUpdatePerIteration; i++)
var item = data[_rand.Next() % data.Count];
item.Quantity += (decimal) _rand.NextDouble() - .5m;
data.Remove(item);
data.Add(item);
}));
Thread.Sleep(1000);
}).Start();
private IList<MyPivotItemType> GetData()
var data = (
from broker in new[] {"Al", "Abe", "Alan", "Ariel", "Adrian", "Anthony", "Anabelle", "Abdullah", "Alexander"}
from account in new[] {"Bo", "Ben", "Brad", "Bella", "Barney", "Bernard", "Beatrice", "Broderick", "Barrington"}
from asset in new[] {"lead", "feathers", "dirt", "platinum"}
select new MyPivotItemType {
Broker = broker,
Asset = asset,
Account = account,
Quantity = (decimal) _rand.NextDouble()*100 - 50
).ToList();
return new ObservableCollection<MyPivotItemType>(data);
internal class MyPivotItemType
public string Asset { get; set; }
public string Broker { get; set; }
public string Account { get; set; }
public decimal Quantity { get; set; }
Exception details
System.ArgumentOutOfRangeException
{"Non-negative number required.\r\nParameter name: length"}
at System.Array.Copy(Array sourceArray, Int32 sourceIndex, Array destinationArray, Int32 destinationIndex, Int32 length, Boolean reliable)
at Infragistics.Olap.FlatData.DataTableMetadata.Insert(Int32 index, DataRowMetadata rowMetadata)
at Infragistics.Olap.FlatData.FlatDataModelProvider.UpdateLiveData(IEnumerable`1 liveChangedData)
at Infragistics.Olap.FlatData.FlatDataModelProvider.UpdateLiveData(Boolean isForced)
at Infragistics.Olap.FlatData.FlatDataModelProvider.<>c__DisplayClass1f.<OnUpdateHierarchiesData>b__1d(Object e)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
at System.Windows.Threading.DispatcherOperation.InvokeImpl()
at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state)
at System.Threading.ExecutionContext.runTryCode(Object userData)
at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Windows.Threading.DispatcherOperation.Invoke()
at System.Windows.Threading.Dispatcher.ProcessQueue()
at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
at System.Windows.Threading.Dispatcher.Run()
at System.Windows.Application.RunDispatcher(Object ignore)
at System.Windows.Application.RunInternal(Window window)
at System.Windows.Application.Run(Window window)
at System.Windows.Application.Run()
at WpfPivot.App.Main() in D:\projects\scratch\WpfPivotSimpler\WpfPivot\obj\x86\Debug\App.g.cs:line 0
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ThreadHelper.ThreadStart()
Hello,
Thank you for your post. I have been looking into it and the code you have provided and I created a sample project using it and modified it, so now the exception doesn’t occurs. Basically I changed the way the item is added to the DataSource after it has been updated and removed, because since you use a different thread and a dispatcher, more than one item is being updated and the Insert method of the DataTableMetadata class’ Insert method calls the Array’s Insert method which takes as argument length of an array, but the count is less because of the threading and dispatching.
Hope this helps you.
Thanks for your answer - it's helped me a lot.
Adam