代码之家  ›  专栏  ›  技术社区  ›  fractor

如果调用ListCollectionView.AddNewItem. 为什么?

  •  0
  • fractor  · 技术社区  · 6 年前

    我有下面的WPF申请表。

    主窗口.xaml

    <Window 
        x:Class="DeferRefreshTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:system="clr-namespace:System;assembly=mscorlib">
        <ListBox ItemsSource="{Binding Names}">
            <ListBox.ItemTemplate>
                <DataTemplate DataType="system:String">
                    <TextBlock Text="{Binding}" />
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Window>
    

    主窗口.xaml.cs

    using System.Collections.Generic;
    using System.Windows.Data;
    
    namespace DeferRefreshTest
    {
        public partial class MainWindow
        {
            public MainWindow()
            {
                InitializeComponent();
    
                var names = new[] { "A name" };
                Names = new ListCollectionView(new List<string>());
                AddNames(names);
    
                DataContext = this;
            }
    
            void AddNames(IEnumerable<string> names)
            {
                foreach (var name in names)
                {
                    Names.AddNewItem(name);
                }
            }
    
            public ListCollectionView Names { get; }
        }
    }
    

    运行应用程序时,出现以下异常。

    System.InvalidOperationException
      HResult=0x80131509
      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, Func`2 GetSourceItem)
       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, Boolean coerceWithCurrentValue, OperationType operationType)
       at System.Windows.DependencyObject.InvalidateProperty(DependencyProperty dp, Boolean preserveCurrentValue)
       at System.Windows.Data.BindingExpressionBase.Invalidate(Boolean isASubPropertyChange)
       at System.Windows.Data.BindingExpression.TransferValue(Object newValue, Boolean isASubPropertyChange)
       at System.Windows.Data.BindingExpression.Activate(Object item)
       at System.Windows.Data.BindingExpression.AttachToContext(AttachAttempt attempt)
       at System.Windows.Data.BindingExpression.MS.Internal.Data.IDataBindEngineClient.AttachToContext(Boolean lastChance)
       at MS.Internal.Data.DataBindEngine.Task.Run(Boolean lastChance)
       at MS.Internal.Data.DataBindEngine.Run(Object arg)
       at MS.Internal.Data.DataBindEngine.OnLayoutUpdated(Object sender, EventArgs e)
       at System.Windows.ContextLayoutManager.fireLayoutUpdateEvent()
       at System.Windows.ContextLayoutManager.UpdateLayout()
       at System.Windows.UIElement.UpdateLayout()
       at System.Windows.Interop.HwndSource.SetLayoutSize()
       at System.Windows.Interop.HwndSource.set_RootVisualInternal(Visual value)
       at System.Windows.Interop.HwndSource.set_RootVisual(Visual value)
       at System.Windows.Window.SetRootVisual()
       at System.Windows.Window.SetRootVisualAndUpdateSTC()
       at System.Windows.Window.SetupInitialState(Double requestedTop, Double requestedLeft, Double requestedWidth, Double requestedHeight)
       at System.Windows.Window.CreateSourceWindow(Boolean duringShow)
       at System.Windows.Window.CreateSourceWindowDuringShow()
       at System.Windows.Window.SafeCreateWindowDuringShow()
       at System.Windows.Window.ShowHelper(Object booleanBox)
       at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
       at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
       at System.Windows.Threading.DispatcherOperation.InvokeImpl()
       at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state)
       at MS.Internal.CulturePreservingExecutionContext.CallbackWrapper(Object obj)
       at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at MS.Internal.CulturePreservingExecutionContext.Run(CulturePreservingExecutionContext 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, Int32 numArgs)
       at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
       at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(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.Application.RunDispatcher(Object ignore)
       at System.Windows.Application.RunInternal(Window window)
       at System.Windows.Application.Run(Window window)
       at System.Windows.Application.Run()
       at DeferRefreshTest.App.Main()
    

    Names = new ListCollectionView(new List<string>());
    AddNames(names);
    

    Names = new ListCollectionView(new List<string>(names));
    //AddNames(names);
    

    我的问题是,为什么会出现这种错误?

    (Stack Overflow说“看起来你的文章大部分是代码,请添加更多细节”,所以我添加了这个多余的文本。请忽略。)

    0 回复  |  直到 6 年前
        1
  •  0
  •   mm8    6 年前

    呼叫 AddNewItem 开始 添加事务。你应该打电话 CommitNew() CancelNew() 结束每笔交易:

    void AddNames(IEnumerable<string> names)
    {
        foreach (var name in names)
        {
            Names.AddNewItem(name);
            Names.CommitNew();
        }
    }