Reputation: 14328
Now I have a weird one. This happens only under Windows XP on a stand-alone build (debug/release, doesn't matter). Works perfectly fine under Windows 7. Anyway, since I have to ensure that the app works under XP, I had to do a little workaround. I had to do the remote
debugging on a machine with XP, which gave me First chance exception of type 'NullReferenceException' in Caliburn.Micro.dll
, then
First chance exception of type 'NullReferenceException' in WindowsBase.dll
, and then crashed with the log provided below.
Anyway, here's the background, I have a GridViewModel with a matching GridView view, main part of it being WPF's DataGrid (hence the name), and I guess that's the problem lies:
<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)]">
And later on also here:
<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>
now running the app under XP and clicking on any row, using the DataGrid's scrollbar or, sometimes, even maximizing the window gives the following:
[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()
Now the weird thing is, if I do the following in some other part of the application:
<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>
it works perfectly fine, both under XP and 7.
Now my workaround is to get rid of the Attach
ed actions in my GridView.xaml in favor of good ol' events in the code-behind, which in turn call the already prepared methods in the view model, e.g :
private void DataGridOnSelectionChanged(object sender, SelectionChangedEventArgs selectionChangedEventArgs)
{
var model = (GridViewModel) DataContext;
model.GridSelectionChanged(selectionChangedEventArgs);
}
I know, it doesn't look too pretty, but for now it's the only way I see to ensure that the app works under XP. Any idea why it crashes in the first place?
[EDIT]
Although the stack trace is a bit convoluted, it seems that the NullReferenceException
indeed happens, but somewhere in my code, namely in the action handler. That's just a preliminary idea that I got out of the same bug in other app...
Upvotes: 2
Views: 1437
Reputation: 14328
Well, it turns out there was a weird race under release version in the action handler, my mistake after all, not really related to Caliburn.Micro per se.
Still don't know why it was only so 'fatal' under XP, but fortunately I won't have to support it for much longer.
Upvotes: 1
Reputation: 126
This sample show you to handle more then one event on the same control. Hope this helps you.
<TextBox cal:Message.Attach="[Event TextChanged] = [Action DoAnything]; [Event KeyDown] = [Action DoAnything2]"/>
Upvotes: 1
Reputation: 1326
I had the same problem, but apparently you can't use the "cal:Message.Attach" more then once on the same control for two different events. You could try using the interaction triggers:
Examples of interaction triggers
Upvotes: 2