WpfToolkit DataGrid and 'DeferRefresh' is not allowed during an AddNew or EditItem transaction

Jun 26, 2009 at 1:37 PM

I'm getting an InvalidOperationException of "'DeferRefresh' is not allowed during an AddNew or EditItem transaction" when using a DataGrid in the RowDetails of another DataGrid.  Its a master detail scenario and when I click too quickly on anythign after editing a child item the exception is thrown. 

When running the sample below if you double-click on the open cell below "Child Name" and then quickly click on the Name column header above "parent one" the exception is thrown.

I'm looking for suggestions about why the exception is thrown and how I can protect against it. 

Xaml:

<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:toolkit="clr-namespace:Microsoft.Windows.Controls;assembly=WpfToolkit"
    x:Name="window"
    Title="Window1" Height="300" Width="300">
    <Grid>
        <toolkit:DataGrid x:Name="dataGridParents" AutoGenerateColumns="False" SelectionMode="Single" IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding ElementName=window, Path=Parents}">
            <toolkit:DataGrid.Columns>
                <toolkit:DataGridTextColumn Header="Name" Binding="{Binding Name}"/>
            </toolkit:DataGrid.Columns>
            <toolkit:DataGrid.RowDetailsTemplate>
                <DataTemplate>
                    <Grid Width="Auto" Margin="30,0,0,0">
                        <toolkit:DataGrid x:Name="dataGridChildren" InitializingNewItem="dataGridChildren_InitializingNewItem" AutoGenerateColumns="false" SelectionMode="Single" ItemsSource="{Binding ElementName=dataGridParents, Path=SelectedItem.Children}" BorderBrush="{x:Null}">
                            <toolkit:DataGrid.Columns>
                                <toolkit:DataGridTextColumn Header="Child Name" Binding="{Binding Name}"/>
                            </toolkit:DataGrid.Columns>
                        </toolkit:DataGrid>
                    </Grid>
                </DataTemplate>
            </toolkit:DataGrid.RowDetailsTemplate>
        </toolkit:DataGrid>
    </Grid>
</Window>

Code Behind:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApplication1
{
    public class Person : System.ComponentModel.INotifyPropertyChanged
    {
        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;

        private string _name;
        private Person _parent;
        private System.Collections.ObjectModel.ObservableCollection<Person> _children = new System.Collections.ObjectModel.ObservableCollection<Person>();

        public string Name
        {
            get { return _name; }
            set
            {
                if (_name != value)
                {
                    _name = value;
                    if (PropertyChanged != null)
                    {
                        PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs("Name"));
                    }
                }
            }
        }

        public Person Parent
        {
            get { return _parent; }
            set
            {
                if (_parent != value)
                {
                    _parent = value;
                    if (PropertyChanged != null)
                    {
                        PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs("Parent"));
                    }
                }
            }
        }

        public System.Collections.ObjectModel.ObservableCollection<Person> Children
        {
            get { return _children; }
            set 
            {
                if (_children != value)
                {
                    _children = value;
                    if (PropertyChanged != null)
                    {
                        PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs("Children"));
                    }
                }
            }
        }

    }

    /// <summary>

    /// Interaction logic for Window1.xaml

    /// </summary>

    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
        }

        private System.Collections.ObjectModel.ObservableCollection<Person> _parents = 
            new System.Collections.ObjectModel.ObservableCollection<Person>() { new Person(){Name="parent one"}, new Person(){Name="parent two"} };

        public System.Collections.ObjectModel.ObservableCollection<Person> Parents
        {
            get { return _parents; }
        }

        private void dataGridChildren_InitializingNewItem(object sender, Microsoft.Windows.Controls.InitializingNewItemEventArgs e)
        {
            Person child = e.NewItem as Person;
            if (child != null)
            {
                Person parent = (Person)dataGridParents.SelectedItem;
                child.Parent = parent;
            }
        }
    }
}

Exception:

System.InvalidOperationException was unhandled
  Message="'DeferRefresh' is not allowed during an AddNew or EditItem transaction."
  Source="PresentationFramework"
  StackTrace:
       at System.Windows.Data.CollectionView.DeferRefresh()
       at System.Windows.Controls.ItemCollection.SetCollectionView(CollectionView view)
       at System.Windows.Controls.ItemCollection.SetItemsSource(IEnumerable value)
       at System.Windows.Controls.ItemsControl.OnItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
       at System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
       at System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
       at System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args)
       at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, OperationType operationType)
       at System.Windows.StyleHelper.ApplyTemplatedParentValue(DependencyObject container, FrameworkObject child, Int32 childIndex, FrugalStructList`1& childRecordFromChildIndex, DependencyProperty dp, FrameworkElementFactory templateRoot)
       at System.Windows.StyleHelper.InvalidatePropertiesOnTemplateNode(DependencyObject container, FrameworkObject child, Int32 childIndex, FrugalStructList`1& childRecordFromChildIndex, Boolean isDetach, FrameworkElementFactory templateRoot)
       at System.Windows.StyleHelper.LoadOptimizedTemplateContent(DependencyObject container, ParserContext parserContext, OptimizedTemplateContent optimizedTemplateContent, FrameworkTemplate frameworkTemplate, IComponentConnector componentConnector, IStyleConnector styleConnector, List`1 affectedChildren, UncommonField`1 templatedNonFeChildrenField)
       at System.Windows.FrameworkTemplate.LoadContent(DependencyObject container, List`1 affectedChildren, UncommonField`1 templatedNonFeChildrenField)
       at System.Windows.StyleHelper.ApplyTemplateContent(UncommonField`1 dataField, DependencyObject container, FrameworkElementFactory templateRoot, Int32 lastChildIndex, HybridDictionary childIndexFromChildID, FrameworkTemplate frameworkTemplate)
       at System.Windows.FrameworkTemplate.ApplyTemplateContent(UncommonField`1 templateDataField, FrameworkElement container)
       at System.Windows.FrameworkElement.ApplyTemplate()
       at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
       at System.Windows.UIElement.Measure(Size availableSize)
       at System.Windows.Controls.Grid.MeasureCell(Int32 cell, Boolean forceInfinityV)
       at System.Windows.Controls.Grid.MeasureCellsGroup(Int32 cellsHead, Size referenceSize, Boolean ignoreDesiredSizeU, Boolean forceInfinityV)
       at System.Windows.Controls.Grid.MeasureOverride(Size constraint)
       at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
       at System.Windows.UIElement.Measure(Size availableSize)
       at System.Windows.ContextLayoutManager.UpdateLayout()
       at System.Windows.ContextLayoutManager.UpdateLayoutCallback(Object arg)
       at System.Windows.Media.MediaContext.InvokeOnRenderCallback.DoWork()
       at System.Windows.Media.MediaContext.FireInvokeOnRenderCallbacks()
       at System.Windows.Media.MediaContext.RenderMessageHandlerCore(Object resizedCompositionTarget)
       at System.Windows.Media.MediaContext.RenderMessageHandler(Object resizedCompositionTarget)
       at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter)
       at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
       at System.Windows.Threading.Dispatcher.WrappedInvoke(Delegate callback, Object args, Boolean isSingleParameter, 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)
       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.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter)
       at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
       at System.Windows.Threading.Dispatcher.WrappedInvoke(Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
       at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Boolean isSingleParameter)
       at System.Windows.Threading.Dispatcher.Invoke(DispatcherPriority priority, Delegate method, Object arg)
       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 WpfApplication1.App.Main() in s:\test\WpfApplication1\obj\Debug\App.g.cs:line 0
       at System.AppDomain._nExecuteAssembly(Assembly 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.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException: 

Jul 1, 2009 at 2:14 PM

I'm still looking for help on this one.  On the June release I still get the exception.