简体   繁体   English

当我的鼠标悬停过快时,FixedPage 会导致 ArgumentNullException

[英]FixedPage causes ArgumentNullException when I mouse over too quickly

I am encountering a situation in which WPF successfully creates an Image element on one of my views but appears to take a second or two to properly set up the logical parent of that element.我遇到了一种情况,WPF 在我的一个视图上成功创建了一个 Image 元素,但似乎需要一两秒钟才能正确设置该元素的逻辑父元素。 If I mouse over in that time window, my application crashes due to an ArgumentNullException from the LogicalTreeHelper.如果我将鼠标悬停在该时间窗口上,我的应用程序将由于来自 LogicalTreeHelper 的 ArgumentNullException 而崩溃。

If I wait for the second or so, everything works fine and there are no problems.如果我等待第二个左右,一切正常,没有问题。 But I can hardly ask my users to do that.但我很难要求我的用户这样做。

Note that this only happens when my UserControl, is housed in FixedPage in a FixedDocument shown by a DocumentViewer.请注意,这仅在我的 UserControl 位于 DocumentViewer 显示的 FixedDocument 中的 FixedPage 中时发生。 When I use the same control in other contexts, (away from FixedDocument et al), it works without issue.当我在其他上下文中使用相同的控件时(远离 FixedDocument 等),它可以正常工作。

Does anyone know anything about this "window" or what might be the cause of it?有没有人知道这个“窗口”或者它的原因是什么?

This is the code in FixedPage.cs that's trying to get the parent of my item.这是 FixedPage.cs 中的代码,它试图获取我的项目的父项。 I've added comments.我已经添加了评论。

    internal int[] _CreateChildIndex(DependencyObject e)
    {
        ArrayList childPath = new ArrayList();
        while (e != this)
        { 
            // *** 'e' is an Image control, created by my view ***
            // *** This value 'parent' is NULL if I mouse over too quickly ***

            DependencyObject parent = LogicalTreeHelper.GetParent(e);
            int childIndex = -1;
            if (parent is FixedPage)
            {
                childIndex = ((FixedPage)parent).Children.IndexOf((UIElement)e);
            }
            else if (parent is Canvas)
            {
                childIndex = ((Canvas)parent).Children.IndexOf((UIElement)e);
            }
            else
            {
                // *** Because 'parent' is null, we end up here.  This call throws ***
                IEnumerable currentChildrens = LogicalTreeHelper.GetChildren(parent);

Here is the code that throws这是抛出的代码

public static IEnumerable GetChildren(DependencyObject current)
{
    if (current == null)
    {
        throw new ArgumentNullException("current"); 
    }

This is the call stack from the mouseover.这是鼠标悬停的调用堆栈。 None of my code in here except the App.Run method.除了 App.Run 方法之外,我这里没有任何代码。

System.Windows.LogicalTreeHelper.GetChildren    C#
System.Windows.Documents.FixedPage._CreateChildIndex    C#
System.Windows.Documents.FixedTextView.GetTextPositionFromPoint C#
MS.Internal.Documents.TextViewBase.System.Windows.Documents.ITextView.GetTextPositionFromPoint  C#
MS.Internal.Documents.DocumentPageTextView.GetTextPositionFromPoint C#
MS.Internal.Documents.MultiPageTextView.GetTextPositionFromPoint    C#
MS.Internal.Documents.TextViewBase.System.Windows.Documents.ITextView.GetTextPositionFromPoint  C#
System.Windows.Documents.TextEditorMouse.IsPointWithinInteractiveArea   C#
System.Windows.Documents.TextEditorMouse.OnQueryCursor  C#
System.Windows.RoutedEventArgs.InvokeHandler    C#
System.Windows.EventRoute.InvokeHandlersImpl    C#
System.Windows.UIElement.RaiseEventImpl C#
System.Windows.UIElement.RaiseTrustedEvent  C#
System.Windows.Input.InputManager.ProcessStagingArea    C#
System.Windows.Input.MouseDevice.UpdateCursorPrivate    C#
System.Windows.Input.MouseDevice.PostProcessInput   C#
System.Windows.Input.InputManager.RaiseProcessInputEventHandlers    C#
System.Windows.Input.InputManager.ProcessStagingArea    C#
System.Windows.Input.InputProviderSite.ReportInput  C#
System.Windows.Interop.HwndMouseInputProvider.ReportInput   C#
System.Windows.Interop.HwndMouseInputProvider.FilterMessage C#
System.Windows.Interop.HwndSource.InputFilterMessage    C#
MS.Win32.HwndWrapper.WndProc    C#
MS.Win32.HwndSubclass.DispatcherCallbackOperation   C#
System.Windows.Threading.ExceptionWrapper.InternalRealCall  C#
System.Windows.Threading.ExceptionWrapper.TryCatchWhen  C#
System.Windows.Threading.Dispatcher.LegacyInvokeImpl    C#
MS.Win32.HwndSubclass.SubclassWndProc   C#
[Native to Managed Transition]  
UserCallWinProcCheckWow Unknown
DispatchMessageWorker   Unknown
[Managed to Native Transition]  
System.Windows.Threading.Dispatcher.PushFrameImpl   C#
System.Windows.Threading.Dispatcher.PushFrame   C#
System.Windows.Threading.Dispatcher.Run C#
System.Windows.Application.RunDispatcher    C#
System.Windows.Application.RunInternal  C#
System.Windows.Application.Run  C#
MyCompany.App.Main  Unknown   
[Native to Managed Transition]  
coreclr_t::execute_assembly C++
run_app_for_context C++
run_app C++
corehost_main   C++
execute_app C++
`anonymous namespace'::read_config_and_execute  C++
fx_muxer_t::handle_exec_host_command    C++
fx_muxer_t::execute C++
hostfxr_main_startupinfo    C++
exe_start   C++
wmain   C++
[Inline Frame] invoke_main  C++
__scrt_common_main_seh  C++
BaseThreadInitThunk()  Unknown
RtlUserThreadStart()   Unknown

Below is a very much abbreviated version of my view (a UserControl) with the ItemsControl that creates the Image element下面是我的视图(一个 UserControl)的一个非常简化的版本,其中包含创建 Image 元素的 ItemsControl

<UserControl
    x:Class="Core.Views.LayerView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:cv="clr-namespace:Core.View"
    >
    <Canvas>
        <ItemsControl ItemsSource="MyItems">
            <ItemsControl.Resources>
                <DataTemplate x:Key="PathOutputTemplate" DataType="{x:Type ShapeVm}">
                    <Path Stroke="Yellow" StrokeThickness="6" Data={Binding Geometry} />
                </DataTemplate>
                <DataTemplate x:Key="ImageOutputTemplate" DataType={x:Type ImageOutputVm}>
                    <Image Source="{Binding ImageSource}"/>
                </DataTemplate>
            </ItemsControl.Resources>
            <ItemsControl.ItemTemplateSelector>
              <cv:OutputTemplateSelector
                PathTemplate="{StaticResource PathOutputTemplate}"
                ImageTemplate="{StaticResource ImageOutputTemplate}"
                />
            </ItemsControl.ItemTemplateSelector>
        </ItemsControl>
    </Canvas>
</UserControl>

I encountered this problem today when creating a new report and wanted to post my workaround for any future developer that hits this issue.我今天在创建新报告时遇到了这个问题,并希望为将来遇到此问题的任何开发人员发布我的解决方法。 This is really a workaround and not a fix for the underlying issue as I didn't have time to dig deeper.这确实是一种解决方法,而不是解决潜在问题的方法,因为我没有时间深入挖掘。

The workaround consisted of adding a Border control with Transparent background over my image controls, essentially preventing any mouse events from triggering below:解决方法包括在我的图像控件上添加一个带有透明背景的边框控件,基本上防止在下面触发任何鼠标事件:

<Grid>
    <My-content-that-must-not-be-moused-over/>
    <Border Background="Transparent"></Border>
<Grid>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM