C# PresentationFramework中的NullReference异常

C# PresentationFramework中的NullReference异常,c#,.net,wpf,C#,.net,Wpf,下面是一个最小的例子,我不可能再减少它了 我在ViewModel中创建一个实时过滤的CollectionView,如下所示: using System.Collections.Generic; using System.Collections.ObjectModel; using System.Collections.Specialized; using System.ComponentModel; using System.Windows.Data; using System.Windows;

下面是一个最小的例子,我不可能再减少它了

我在ViewModel中创建一个实时过滤的CollectionView,如下所示:

using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Windows.Data;
using System.Windows;

namespace AntiBonto.ViewModel
{
    [Serializable]
    public class Person
    {
        public event PropertyChangedEventHandler PropertyChanged;

        protected void RaisePropertyChanged([CallerMemberName] String propertyName = "")
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
        public string Name { get; set; }
        public override string ToString()
        {
            return Name;
        }

        private int num;
        public int Num
        {
            get { return num; }
            set { num = value; RaisePropertyChanged(); }
        }
    }

    class ObservableCollection2<T> : ObservableCollection<T>
    {
        public ObservableCollection2() : base() { }
        public ObservableCollection2(T[] t) : base(t) { }
        public void AddRange(IEnumerable<T> collection)
        {
            foreach (var i in collection)
            {
                Items.Add(i);
            }
            OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
        }
    }

    class MainWindow: ViewModelBase
    {
        public MainWindow() { }
        private ObservableCollection2<Person> people = new ObservableCollection2<Person>();
        public ObservableCollection2<Person> People
        {
            get
            {
                return people;
            }
            set
            {
                people = value;
                RaisePropertyChanged();
            }
        }
        public ICollectionView Team
        {
            get
            {
                CollectionViewSource cvs = new CollectionViewSource { Source = People, IsLiveFilteringRequested = true, LiveFilteringProperties = { "Num" } };
                cvs.View.Filter = p => ((Person)p).Num != 11;
                return cvs.View;
            }
        }

        public ICollectionView Ujoncok
        {
            get
            {
                CollectionViewSource cvs = new CollectionViewSource { Source = People, IsLiveFilteringRequested = true, LiveFilteringProperties = { "Num" } };
                cvs.View.Filter = p => ((Person)p).Num == 11;
                return cvs.View;
            }
        }
    }
}
using System;
using System.IO;
using System.Linq;
using System.Windows;
using System.Xml.Serialization;

namespace AntiBonto
{
    [Serializable]
    public class AppData
    {
        public Person[] Persons;
    }
    public partial class MainWindow : System.Windows.Window
    {
        public MainWindow()
        {
            InitializeComponent();
            Loaded += MainWindow_Loaded;
        }
        private string filepath = "state.xml";
        private AppData AppData
        {
            get { return new AppData { Persons = viewModel.People.ToArray()}; }
            set { viewModel.People.AddRange(value.Persons);}
        }

        private void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            var xs = new XmlSerializer(typeof(AppData));
            if (File.Exists(filepath))
            {
                using (var file = new StreamReader(filepath))
                {
                    AppData = (AppData)xs.Deserialize(file);
                }
            }
        }     

        private ViewModel.MainWindow viewModel { get { return (ViewModel.MainWindow)DataContext; } }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            Person p = viewModel.People.First(q => q.Name == "Ferencz Katalin");
            if (p.Num == 11)
                p.Num = 0;
            else
                p.Num= 11;
        }
    }
}
XML文件如下所示:

<?xml version="1.0" encoding="utf-8"?>
<AppData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Persons>
    <Person>
      <Name>Person1</Name>
      <Num>0</Num>
    </Person>
    <Person>
      <Name>Person2</Name>
      <Num>0</Num>
    </Person>
  </Persons>
</AppData>

人1
0
人2
0
当我单击该按钮一两次时,会出现
NullReference
异常。内部没有例外。异常不会出现在我的代码中,而是出现在框架代码中,因此它不会显示源代码,我无法找出哪个对象为null以及异常来自何处。我没有设置“进入.NET源代码”,它仍然告诉我没有可用的源代码

以下是堆栈跟踪:

位于System.Windows.Data.ListCollectionView.RestoreLiveShaping()处 System.Windows.Threading.ExceptionWrapper.InternalRealCall(委托 回调,对象args,Int32 numArgs)位于 System.Windows.Threading.ExceptionWrapper.TryCatchWhen(对象源, 委托回调、对象参数、Int32 numArgs、委托catchHandler) 位于System.Windows.Threading.DispatcherOperation.InvokeImpl()的 System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(对象 国家)在 System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext、ContextCallback回调、对象状态、布尔值 在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext、ContextCallback回调、对象状态、布尔值 在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext、ContextCallback回调、对象状态)位于 MS.Internal.CulturePreservingExecutionContext.Run(CulturePreservingExecutionContext executionContext、ContextCallback回调、对象状态)位于 System.Windows.Threading.DispatcherOperation.Invoke()位于 位于的System.Windows.Threading.Dispatcher.ProcessQueue() System.Windows.Threading.Dispatcher.WndProcHook(IntPtr-hwnd,Int32 msg、IntPtr wParam、IntPtr lParam、Boolean和handled)位于 MS.Win32.hwndwapper.WndProc(IntPtr-hwnd、Int32-msg、IntPtr-wParam、, 在 位于的MS.Win32.HwndSubclass.DispatcherCallbackOperation(对象o) System.Windows.Threading.ExceptionWrapper.InternalRealCall(委托 回调,对象args,Int32 numArgs)位于 System.Windows.Threading.ExceptionWrapper.TryCatchWhen(对象源, 委托回调、对象参数、Int32 numArgs、委托catchHandler) 在 System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority 优先级、TimeSpan超时、委托方法、对象参数、Int32 在MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd,Int32 msg、IntPtr wParam、IntPtr lParam)位于 MS.Win32.unsafentivemethods.DispatchMessage(MSG&MSG)位于 System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame 帧)在 System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame框架) 位于System.Windows.Application.RunDispatcher(对象忽略)处 System.Windows.Application.RunInternal(窗口窗口)位于 System.Windows.Application.Run(窗口)在 中的AntiBonto.App.Main()处的System.Windows.Application.Run() D:\Marci\Programozás\AntiBonto\AntiBonto\obj\Debug\App.g.cs:第0行 System.AppDomain.\u下一个安全程序集(运行时程序集,字符串[]) args)位于System.AppDomain.ExecuteAssembly(字符串汇编文件, 证据汇编安全性,字符串[]args)位于 Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()位于 位于的System.Threading.ThreadHelper.ThreadStart_上下文(对象状态) System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext、ContextCallback回调、对象状态、布尔值 在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext、ContextCallback回调、对象状态、布尔值 在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext、ContextCallback回调、对象状态)位于 System.Threading.ThreadHelper.ThreadStart()


我花了很长时间试图调试系统。Windows,但一无所获,欢迎您尝试

在一个至少能起作用的创可贴解决方案方面,我发现<代码>新的CopyDeVIEWStase<代码>引起了这个问题,而<代码> CopyDeVIEWStask.GETDebug视图没有。

您提到这有两个问题:

1)我一直在修改基本集合,需要刷新过滤器

您可以通过使用ObservableCollections和侦听版本,然后更新筛选的实例来解决这个问题

因此,对于每次需要CollectionViewSource的新时间,创建一个新的ObservableCollection,并跟踪它,向原始ObservableCollection添加一个侦听器,并将更新推送到CollectionViewSource的版本

优雅?不,功能性的?对

2)我正在使用GetDefaultView不提供的实时整形功能。

使用GetDefaultView,我始终可以使用它,您可以显示您在何处创建视图吗


我注意到的一个相似之处是,我使用了ObservableCollection的一个扩展。如果只使用标准的ObservableCollection,您是否会遇到问题?

我不知道为什么,但这修复了错误:

public ICollectionView Team
{
    get
    {
        CollectionViewSource cvs = new CollectionViewSource { Source = People, IsLiveFilteringRequested = true, LiveFilteringProperties = { "Num" } };
        cvs.View.Filter = p => ((Person)p).Num != 11;
        cvs.View.CollectionChanged += EmptyEventHandler;
        return cvs.View;
    }
}
private void EmptyEventHandler(object sender, NotifyCollectionChangedEventArgs e) { }

我试图调试异常发生的位置,并希望在集合更改时设置断点。订阅该活动使异常消失。

@RenéVogt不,不是。我不会称之为重复,因为它与另一个问题共享同一个非常通用的异常。@Joe:它可能不是规范的完全重复“什么是NullReferenceException…”问题,但这个问题仍然缺乏研究,也没有提供可靠的重现问题的好方法。如果只能使用thir再现问题
public ICollectionView Team
{
    get
    {
        CollectionViewSource cvs = new CollectionViewSource { Source = People, IsLiveFilteringRequested = true, LiveFilteringProperties = { "Num" } };
        cvs.View.Filter = p => ((Person)p).Num != 11;
        cvs.View.CollectionChanged += EmptyEventHandler;
        return cvs.View;
    }
}
private void EmptyEventHandler(object sender, NotifyCollectionChangedEventArgs e) { }