PresentationFramework中的NullReference异常 [英] NullReference Exception in PresentationFramework

查看:49
本文介绍了PresentationFramework中的NullReference异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Below is a minimal example, I couldn't possibly reduce it any more than this.

我像这样在ViewModel中创建一个实时筛选的CollectionView:

I create a live filtered CollectionView in the ViewModel like this:

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;
            }
        }
    }
}

GUI上有一个按钮,用于修改People集合中的Person对象:

The GUI has a button that modifies a Person object in the People collection:

<Window x:Class="AntiBonto.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:vm="clr-namespace:AntiBonto.ViewModel"
        mc:Ignorable="d"
        Title="AntiBonto" Width="1024" Height="768">
    <Window.DataContext>
        <vm:MainWindow/>
    </Window.DataContext>
    <Window.Resources>
        <FrameworkElement x:Key="DataContextProxy" DataContext="{Binding}"/> <!-- workaround, see http://stackoverflow.com/questions/7660967 -->
    </Window.Resources>
    <TabControl>
        <TabItem Header="Tab2">
            <StackPanel>
                <Button Content="Does" Click="Button_Click"/>
                <ContentControl Visibility="Collapsed" Content="{StaticResource DataContextProxy}"/>
                <!-- workaround part 2 -->
                <DataGrid ItemsSource="{Binding Ujoncok}" CanUserAddRows="False" CanUserDeleteRows="False" AutoGenerateColumns="False">
                    <DataGrid.Columns>
                        <DataGridComboBoxColumn Header="Who" ItemsSource="{Binding DataContext.Team, Source={StaticResource DataContextProxy}, Mode=OneWay}"/>
                    </DataGrid.Columns>
                </DataGrid>
            </StackPanel>
        </TabItem>
    </TabControl>
</Window>

我从XML文件中加载数据,如下所示:

I load the data from an XML file like this:

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文件是这样的:

and the XML file is this:

<?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>

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

When I click the button once or twice, I get a NullReference exception. There is no inner exception. The exception does not arise in my code, but in framework code, so it does not show the source, I cannot find out which object is null and where the exception comes from. I didn't manage to set up "stepping into .NET sources", it still tells me that there is no source available.

这是堆栈跟踪:

在System.Windows.Data.ListCollectionView.RestoreLiveShaping()处的

System.Windows.Threading.ExceptionWrapper.InternalRealCall(委托回调,对象args,Int32 numArgs)System.Windows.Threading.ExceptionWrapper.TryCatchWhen(对象源,委托回调,对象args,Int32 numArgs,委托catchHandler)在System.Windows.Threading.DispatcherOperation.InvokeImpl()在System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object州)System.Threading.ExecutionContext.RunInternal(ExecutionContextexecutionContext,ContextCallback回调,对象状态,布尔值reserveSyncCtx)位于System.Threading.ExecutionContext.Run(ExecutionContextexecutionContext,ContextCallback回调,对象状态,布尔值reserveSyncCtx)位于System.Threading.ExecutionContext.Run(ExecutionContextexecutionContext,ContextCallback回调,对象状态)位于MS.Internal.CulturePreservingExecutionContext.Run(CulturePreservingExecutionContextexecutionContext,ContextCallback回调,对象状态)位于System.Windows.Threading.DispatcherOperation.Invoke()在System.Windows.Threading.Dispatcher.ProcessQueue()在System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd,Int32msg,IntPtr wParam,IntPtr lParam,布尔值和处理)MS.Win32.HwndWrapper.WndProc(IntPtr hwnd,Int32 msg,IntPtr wParam,IntPtr lParam,布尔值和处理)MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)在System.Windows.Threading.ExceptionWrapper.InternalRealCall(委托回调,对象args,Int32 numArgs)System.Windows.Threading.ExceptionWrapper.TryCatchWhen(对象源,委托回调,对象args,Int32 numArgs,委托catchHandler)在System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority优先级,TimeSpan超时,委托方法,对象参数,Int32numArgs)在MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd,Int32msg,IntPtr wParam,IntPtr lParam)MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)位于System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame帧)System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame框架)在System.Windows.Application.RunDispatcher(Object ignore)在System.Windows.Application.RunInternal(窗口窗口)位于System.Windows.Application.Run(窗口"窗口)位于System.Windows.Application.Run()中的AntiBonto.App.Main()D:\ Marci \Programozás\ AntiBonto \ AntiBonto \ obj \ Debug \ App.g.cs:第0行位于System.AppDomain._nExecuteAssembly(RuntimeAssembly程序集,字符串[]args)位于System.AppDomain.ExecuteAssembly(String assemblyFile,证据assemblySecurity,String [] args)在Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()在System.Threading.ThreadHelper.ThreadStart_Context(对象状态)位于System.Threading.ExecutionContext.RunInternal(ExecutionContextexecutionContext,ContextCallback回调,对象状态,布尔值reserveSyncCtx)位于System.Threading.ExecutionContext.Run(ExecutionContextexecutionContext,ContextCallback回调,对象状态,布尔值reserveSyncCtx)位于System.Threading.ExecutionContext.Run(ExecutionContextexecutionContext,ContextCallback回调,对象状态)位于System.Threading.ThreadHelper.ThreadStart()

at System.Windows.Data.ListCollectionView.RestoreLiveShaping() 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 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 AntiBonto.App.Main() in D:\Marci\Programozás\AntiBonto\AntiBonto\obj\Debug\App.g.cs:line 0 at System.AppDomain._nExecuteAssembly(RuntimeAssembly 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.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 System.Threading.ThreadHelper.ThreadStart()

推荐答案

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

I have no idea why, but this fixed the bug:

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) { }

我正在尝试调试异常发生的位置,并且我想在集合更改时设置一个断点.订阅该事件使异常消失.

I was trying to debug where the exception happens, and I wanted to set a breakpoint when the collection changes. Subscribing to the event made the exception go away.

这篇关于PresentationFramework中的NullReference异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆