C# PresentationFramework中的NullReference异常
下面是一个最小的例子,我不可能再减少它了 我在ViewModel中创建一个实时过滤的CollectionView,如下所示: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;
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) { }