使用Message.Attach时,Caliburn.Micro和/或WindowsBase中的NullReferenceException

时间:2012-10-08 08:46:51

标签: c# wpf mvvm caliburn.micro

现在我有一个奇怪的。这种情况仅在Windows XP上独立构建时发生(调试/发布,并不重要)。在Windows 7下工作得很好。无论如何,由于我必须确保应用程序在XP下工作,我不得不做一些解决方法。我不得不做遥控器 在XP机器上进行调试,然后给我First chance exception of type 'NullReferenceException' in Caliburn.Micro.dll First chance exception of type 'NullReferenceException' in WindowsBase.dll,然后使用下面提供的日志崩溃。

无论如何,这里是背景,我有一个带有匹配GridView视图的GridViewModel,它的主要部分是WPF的DataGrid(因此得名),我猜这就是问题所在。在于:

<DataGrid CanUserAddRows="False"  EnableRowVirtualization="True" Grid.Row="0" x:Name="DataGrid" AlternatingRowBackground="#EBEBEB" ScrollViewer.VerticalScrollBarVisibility="Visible"
          ScrollViewer.CanContentScroll="True" ItemsSource="{Binding CollectionView}" IsReadOnly="True" RowDetailsVisibilityMode="VisibleWhenSelected" AutoGenerateColumns="False"                                      
                        here->>   cal:Message.Attach="[Event SelectionChanged] = [Action GridSelectionChanged($eventArgs)]">

后来也在这里:

<DataGrid.CellStyle>
    <Style TargetType="{x:Type DataGridCell}">
        <Setter Property="cal:Message.Attach" Value="[Event PreviewMouseLeftButtonUp] = [Action PreviewMouseLeftButtonUp($view, $eventArgs)]"/>
    </Style>                    
</DataGrid.CellStyle>
<DataGrid.ItemContainerStyle>
    <Style TargetType="{x:Type DataGridRow}">
        <Setter Property="cal:Message.Attach" Value="[Event PreviewMouseRightButtonUp] = [Action PreviewMouseRightButtonUp($source, $eventArgs)]"/>
    </Style>
</DataGrid.ItemContainerStyle>

现在在XP下运行应用程序并使用DataGrid的滚动条单击任何行,或者有时甚至最大化窗口会显示以下内容:

[Exception] - Object reference not set to an instance of an object.
[Stack Trace] -    at Caliburn.Micro.ActionMessage.<.cctor>b__14(ActionExecutionContext context)
   at Caliburn.Micro.ActionMessage.<.cctor>b__15(ActionExecutionContext context)
   at Caliburn.Micro.ActionMessage.UpdateContext()
   at Caliburn.Micro.ActionMessage.ElementLoaded(Object sender, RoutedEventArgs e)
   at Caliburn.Micro.View.<>c__DisplayClass3.<ExecuteOnLoad>b__0(Object s, RoutedEventArgs e)
   at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
   at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
   at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
   at System.Windows.UIElement.RaiseEvent(RoutedEventArgs e)
   at System.Windows.BroadcastEventHelper.BroadcastEvent(DependencyObject root, RoutedEvent routedEvent)
   at System.Windows.BroadcastEventHelper.BroadcastLoadedEvent(Object root)
   at MS.Internal.LoadedOrUnloadedOperation.DoWork()
   at System.Windows.Media.MediaContext.FireLoadedPendingCallbacks()
   at System.Windows.Media.MediaContext.FireInvokeOnRenderCallbacks()
   at System.Windows.Media.MediaContext.RenderMessageHandlerCore(Object resizedCompositionTarget)
   at System.Windows.Media.MediaContext.RenderMessageHandler(Object resizedCompositionTarget)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
   at System.Windows.Threading.DispatcherOperation.InvokeImpl()
   at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state)
   at System.Threading.ExecutionContext.runTryCode(Object userData)
   at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext 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 MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
   at System.Windows.Threading.Dispatcher.InvokeImpl(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.Threading.Dispatcher.Run()
   at System.Windows.Application.RunDispatcher(Object ignore)
   at System.Windows.Application.RunInternal(Window window)
   at System.Windows.Application.Run(Window window)
   at MyAwesomeApplication.App.Main()

现在奇怪的是,如果我在应用程序的其他部分执行以下操作:

<ListView.ItemContainerStyle>
    <Style TargetType="{x:Type ListViewItem}">
        <Setter Property="IsEnabled" Value="{Binding IsRowEnabled}"/>
        <Setter Property="cal:Message.Attach" Value="[Event MouseDoubleClick] = [Action InvoiceRow()]"/>
    </Style>
</ListView.ItemContainerStyle>

在XP和7下都可以正常使用。

现在我的解决方法是摆脱我的GridView.xaml中的Attach ed操作,转而使用好的ol&#39;代码隐藏中的事件,后者又调用视图模型中已经准备好的方法,例如:

private void DataGridOnSelectionChanged(object sender, SelectionChangedEventArgs selectionChangedEventArgs)
{
    var model = (GridViewModel) DataContext;

    model.GridSelectionChanged(selectionChangedEventArgs);
}

我知道,它看起来并不太漂亮,但就目前而言,这是我确保应用程序在XP下运行的唯一方式。知道为什么它一开始崩溃了吗?

[编辑]

尽管堆栈跟踪有点复杂,但似乎NullReferenceException确实发生了,但在我的代码中的某处,即在动作处理程序中。这只是一个初步的想法,我在其他应用程序中摆脱了同样的错误...

3 个答案:

答案 0 :(得分:2)

我遇到了同样的问题,但显然你不能再使用“cal:Message.Attach”对同一个控件进行两次不同的事件。您可以尝试使用交互触发器:

Examples of interaction triggers

答案 1 :(得分:1)

此示例显示您在同一控件上处理多个事件。希望这会对你有所帮助。

 <TextBox cal:Message.Attach="[Event TextChanged] = [Action DoAnything]; [Event KeyDown] = [Action DoAnything2]"/>

答案 2 :(得分:1)

嗯,事实证明在动作处理程序中发布版本下有一个奇怪的竞赛,毕竟我的错误与Caliburn.Micro本身并不相关。

仍然不知道为什么它在XP下只是如此'致命',但幸运的是我不需要再支持它了。