xtzy89
2021-08-17 10:02
采纳率: 100%
浏览 77

WPF 控件绑定的集合改变时报错

WPF窗体中有一个DateGrid和两个Button控件,一个Button不停地往DateGrid添加数据,另一个Button不停的删除数据,操作过程中不停的拉动DateGrid滚动条,此时报“System.ArgumentException:“高度必须为非负值。”异常”
代码:

public partial class MainWindow : Window
    {
        public ObservableCollection<Student> StudentList = new ObservableCollection<Student>();
        private static object lockObject = new object();
        private static Mutex mut = new Mutex();
        private int id = 1;
        public MainWindow()
        {
            InitializeComponent();
            this.studentList.ItemsSource = StudentList;
        }
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                Task.Run(() =>
                {
                    while (true)
                    {
                        //mut.WaitOne();
                        lock (lockObject)
                        {
                            Dispatcher.Invoke(() =>
                            {
                                ////for (int i = 0; i < 100; i++)
                                StudentList.Add(new Student() { ID = id++, Name = "Test" + id++, Age = id++ });

                            });
                            Task.Delay(500);
                        }
                        //mut.ReleaseMutex();
                    }
                });
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message + "\r" + ex.StackTrace);
                return;
            }

        }

        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            Task.Run(() =>
            {
                while (StudentList.Count > 0)
                {
                    //mut.WaitOne();
                    lock (lockObject)
                    {
                        Dispatcher.Invoke(() =>
                        {
                            //if (StudentList.Count > 0)
                            StudentList.RemoveAt(0);
                        });
                        Task.Delay(500);
                    }
                    //mut.ReleaseMutex();
                }
            });
        }
    }

异常信息:

System.ArgumentException
  HResult=0x80070057
  Message=高度必须为非负值。
  Source=WindowsBase
  StackTrace:
   在 System.Windows.Rect.set_Height(Double value)
   在 System.Windows.Controls.VirtualizingStackPanel.ExtendViewport(IHierarchicalVirtualizationAndScrollInfo virtualizationInfoProvider, Boolean isHorizontal, Rect viewport, VirtualizationCacheLength cacheLength, VirtualizationCacheLengthUnit cacheUnit, Size stackPixelSizeInCacheBeforeViewport, Size stackLogicalSizeInCacheBeforeViewport, Size stackPixelSizeInCacheAfterViewport, Size stackLogicalSizeInCacheAfterViewport, Size stackPixelSize, Size stackLogicalSize, Int32& itemsInExtendedViewportCount)
   在 System.Windows.Controls.VirtualizingStackPanel.IsExtendedViewportFull()
   在 System.Windows.Controls.VirtualizingStackPanel.ShouldItemsChangeAffectLayoutCore(Boolean areItemChangesLocal, ItemsChangedEventArgs args)
   在 System.Windows.Controls.VirtualizingPanel.OnItemsChangedInternal(Object sender, ItemsChangedEventArgs args)
   在 System.Windows.Controls.Panel.OnItemsChanged(Object sender, ItemsChangedEventArgs args)
   在 System.Windows.Controls.ItemContainerGenerator.OnItemAdded(Object item, Int32 index)
   在 System.Windows.Controls.ItemContainerGenerator.OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs args)
   在 System.Windows.WeakEventManager.ListenerList`1.DeliverEvent(Object sender, EventArgs e, Type managerType)
   在 System.Windows.WeakEventManager.DeliverEvent(Object sender, EventArgs args)
   在 System.Collections.Specialized.CollectionChangedEventManager.OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs args)
   在 System.Collections.Specialized.NotifyCollectionChangedEventHandler.Invoke(Object sender, NotifyCollectionChangedEventArgs e)
   在 System.Windows.Data.CollectionView.OnCollectionChanged(NotifyCollectionChangedEventArgs args)
   在 System.Windows.Controls.ItemCollection.OnViewCollectionChanged(Object sender, NotifyCollectionChangedEventArgs e)
   在 System.Windows.WeakEventManager.ListenerList`1.DeliverEvent(Object sender, EventArgs e, Type managerType)
   在 System.Windows.WeakEventManager.DeliverEvent(Object sender, EventArgs args)
   在 System.Collections.Specialized.CollectionChangedEventManager.OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs args)
   在 System.Windows.Data.CollectionView.OnCollectionChanged(NotifyCollectionChangedEventArgs args)
   在 System.Windows.Data.ListCollectionView.ProcessCollectionChangedWithAdjustedIndex(NotifyCollectionChangedEventArgs args, Int32 adjustedOldIndex, Int32 adjustedNewIndex)
   在 System.Windows.Data.ListCollectionView.ProcessCollectionChanged(NotifyCollectionChangedEventArgs args)
   在 System.Windows.Data.CollectionView.OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs args)
   在 System.Collections.ObjectModel.ObservableCollection`1.OnCollectionChanged(NotifyCollectionChangedEventArgs e)
   在 System.Collections.ObjectModel.ObservableCollection`1.InsertItem(Int32 index, T item)
   在 System.Collections.ObjectModel.Collection`1.Add(T item)
   在 DataGridDemo.MainWindow.<Button_Click>b__5_1() 在 F:\1.Study\WPF\WpfStyles\src\DataGridDemo\MainWindow.xaml.cs 中: 第 49 行
   在 System.Windows.Threading.DispatcherOperation.InvokeDelegateCore()
   在 System.Windows.Threading.DispatcherOperation.InvokeImpl()

  此异常最初是在此调用堆栈中引发的: 
    [外部代码]
    DataGridDemo.MainWindow.Button_Click.AnonymousMethod__5_1() (位于 MainWindow.xaml.cs 中)
    [外部代码]

之前是没有加锁,复现概率很高,加了锁之后会好点,不过还是会有问题。错误如下图:

img

  • 收藏

2条回答 默认 最新

  • xtzy89 2021-08-18 14:40
    已采纳

    github上有提这个bug,看起来像是控件本身的问题。
    https://github.com/dotnet/wpf/issues/2854

    已采纳该答案
    打赏 评论
  • CSDN专家-showbo 2021-08-17 11:13

    应该是datagrid内部更新ui出现了错误。你测试这么快速的插入删除有什么目的吗?1秒钟至少都几百条数据。。

    打赏 评论

相关推荐 更多相似问题