2

今、私は奇妙なものを持っています。これは、スタンドアロンビルドの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の両方で、完全に正常に動作します。

ここでの回避策はAttach、GridView.xamlのedアクションを削除して、コードビハインドの古き良きイベントを優先することです。これにより、ビューモデルで既に準備されているメソッドが呼び出されます。

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

    model.GridSelectionChanged(selectionChangedEventArgs);
}

見た目はあまりきれいではありませんが、今のところ、アプリがXPで動作することを確認する唯一の方法です。そもそもなぜクラッシュするのか、何か考えはありますか?

[編集]

スタックトレースは少し複雑ですが、NullReferenceException実際に発生しているように見えますが、私のコードのどこか、つまりアクションハンドラーにあります。これは、他のアプリの同じバグから抜け出したという予備的な考えです...

4

3 に答える 3

2

同じ問題が発生しましたが、2つの異なるイベントに対して、同じコントロールで「cal:Message.Attach」を2回以上使用できないようです。インタラクショントリガーを使用してみることができます。

インタラクショントリガーの例

于 2012-10-08T09:12:58.390 に答える
1

このサンプルは、同じコントロールで複数のイベントを処理する方法を示しています。これがお役に立てば幸いです。

 <TextBox cal:Message.Attach="[Event TextChanged] = [Action DoAnything]; [Event KeyDown] = [Action DoAnything2]"/>
于 2012-10-08T13:26:24.560 に答える
1

さて、アクションハンドラーにリリースバージョンの下で奇妙なレースがあったことがわかりました。結局のところ、私の間違いは、Caliburn.Micro自体とは実際には関係ありません。

XPでなぜこれほど「致命的」だったのかはまだわかりませんが、幸いなことに、これ以上長くサポートする必要はありません。

于 2013-06-05T17:58:16.110 に答える