例外"操作成功完成"提高财产变更事件

时间:2016-05-04 12:41:53

标签: c# wpf

我得到的可能是我见过的最不实用的例外(在VBA之外),System.ComponentModel.Win32Exception:"操作成功完成"

enter image description here

堆栈追踪:

   at MS.Win32.UnsafeNativeMethods.CreateWindowEx(Int32 dwExStyle, String lpszClassName, String lpszWindowName, Int32 style, Int32 x, Int32 y, Int32 width, Int32 height, HandleRef hWndParent, HandleRef hMenu, HandleRef hInst, Object pvParam)
   at MS.Win32.HwndWrapper..ctor(Int32 classStyle, Int32 style, Int32 exStyle, Int32 x, Int32 y, Int32 width, Int32 height, String name, IntPtr parent, HwndWrapperHook[] hooks)
   at System.Windows.Interop.HwndSource.Initialize(HwndSourceParameters parameters)
   at System.Windows.Interop.HwndSource..ctor(HwndSourceParameters parameters)
   at System.Windows.Controls.Primitives.Popup.PopupSecurityHelper.BuildWindow(Int32 x, Int32 y, Visual placementTarget, Boolean transparent, HwndSourceHook hook, AutoResizedEventHandler handler)
   at System.Windows.Controls.Primitives.Popup.BuildWindow(Visual targetVisual)
   at System.Windows.Controls.Primitives.Popup.CreateWindow(Boolean asyncCall)
   at System.Windows.Controls.Primitives.Popup.OnIsOpenChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
   at System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
   at System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
   at System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args)
   at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType)
   at System.Windows.DependencyObject.InvalidateProperty(DependencyProperty dp, Boolean preserveCurrentValue)
   at System.Windows.Data.BindingExpressionBase.Invalidate(Boolean isASubPropertyChange)
   at System.Windows.Data.BindingExpression.TransferValue(Object newValue, Boolean isASubPropertyChange)
   at MS.Internal.Data.ClrBindingWorker.NewValueAvailable(Boolean dependencySourcesChanged, Boolean initialValue, Boolean isASubPropertyChange)
   at MS.Internal.Data.PropertyPathWorker.UpdateSourceValueState(Int32 k, ICollectionView collectionView, Object newValue, Boolean isASubPropertyChange)
   at MS.Internal.Data.ClrBindingWorker.OnSourcePropertyChanged(Object o, String propName)
   at System.Windows.WeakEventManager.ListenerList`1.DeliverEvent(Object sender, EventArgs e, Type managerType)
   at System.ComponentModel.PropertyChangedEventManager.OnPropertyChanged(Object sender, PropertyChangedEventArgs args)
   at System.ComponentModel.PropertyChangedEventHandler.Invoke(Object sender, PropertyChangedEventArgs e)
   at MVVMSeaCores.Controls.HelpTip.NotifyOfPropertyChange(String propertyName) in D:\Projects\MVVMSeaCores\MVVMSeaCores\Controls\HelpTip.cs:line 140
   at MVVMSeaCores.Controls.HelpTip.set_IsOpen(Boolean value) in D:\Projects\MVVMSeaCores\MVVMSeaCores\Controls\HelpTip.cs:line 181
   at MVVMSeaCores.Controls.HelpTipManager.OpenNext() in D:\Projects\MVVMSeaCores\MVVMSeaCores\Controls\HelpTip.cs:line 102
   at MVVMSeaCores.Controls.HelpTipManager.AddedToScreen(HelpTip helpTip) in D:\Projects\MVVMSeaCores\MVVMSeaCores\Controls\HelpTip.cs:line 115
   at MVVMSeaCores.Controls.HelpTipManager.HelpTip_PropertyChanged(Object sender, PropertyChangedEventArgs e) in D:\Projects\MVVMSeaCores\MVVMSeaCores\Controls\HelpTip.cs:line 67
   at System.ComponentModel.PropertyChangedEventHandler.Invoke(Object sender, PropertyChangedEventArgs e)
   at MVVMSeaCores.Controls.HelpTip.NotifyOfPropertyChange(String propertyName) in D:\Projects\MVVMSeaCores\MVVMSeaCores\Controls\HelpTip.cs:line 140
   at MVVMSeaCores.Controls.HelpTip.set_IsOnscreen(Boolean value) in D:\Projects\MVVMSeaCores\MVVMSeaCores\Controls\HelpTip.cs:line 195
   at MVVMSeaCores.Controls.HelpPopup.View1_Loaded(Object sender, RoutedEventArgs e) in D:\Projects\MVVMSeaCores\MVVMSeaCores\Controls\HelpPopup.xaml.cs:line 181
   at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
   at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
   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.Interop.HwndTarget.OnResize()
   at System.Windows.Interop.HwndTarget.HandleMessage(WindowMessage msg, IntPtr wparam, IntPtr lparam)
   at System.Windows.Interop.HwndSource.HwndTargetFilterMessage(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)

它一直发生在一条线上,为一个属性IsOpen引发一个属性更改事件,但它似乎随机发生(有时一切正常!):

    private void NotifyOfPropertyChange(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName)); //<-here
        }
    }

对于上下文,IsOpen绑定到弹出窗口的开放属性:

<Popup x:Name="Popup"
               DataContext="{Binding HelpTip, ElementName=userControl}"
               IsOpen="{Binding IsOpen}"
               StaysOpen="True" PopupAnimation="Fade"
               AllowsTransparency="True"
               Placement="{Binding Placement, ElementName=userControl}">

并由静态类设置,它确保一次只在屏幕上显示一个静态类,使用加载的事件来更新静态管理器类中的IsOnscreen属性和此方法:

    private static void HelpTip_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
        HelpTip helpTip = sender as HelpTip;
        if (helpTip != null)
        {
            //is this on screen or not?
            switch (e.PropertyName)
            {
                case "IsOnscreen":
                    //Update our onscreen lists and perform related behaviour
                    if (helpTip.IsOnscreen)
                    {
                        AddedToScreen(helpTip);
                    }
                    else
                    {
                        RemovedFromScreen(helpTip);
                    }
                    break;
                case "IsOpen":
                    lock (helpTip.Lock)
                    {
                        if (!helpTip.IsOpen)
                        {
                            OpenNext();
                        }
                    }
                    break;
            }
        }
    }

OpenNext选择添加到屏幕上的helpTip之一并使用IsOpen将其设置为打开,这似乎是导致错误。

起初我认为它可能是并发性问题,但我删除了所有线程和简化的东西,现在一切都在主线程上完成。

我从来没有通知财产变更的东西之前失败了,我不知道会出现什么问题。看看这个:System.ComponentModel.Win32Exception: The operation completed successfully它似乎与使用太多手柄有关(但我不确定我是如何达到开启和关闭6或7个弹出窗口的限制 - 编辑:也使用taskmanager检查,它在崩溃时使用大约530.)或使用太大的图形或太大的缓冲区,我不认为我做的两件事,因为这些弹出窗口只是少数组件。

2 个答案:

答案 0 :(得分:1)

不是很好的答案。但至少这是一项工作。该错误发生在MS.Win32.UnsafeNativeMethods.CreateWindowEx中,并且是WPF打开Popup的结果。这似乎是WPF中的一个错误,而且我没办法解决它。我还不确定为什么它会特别影响这些弹出窗口。 (其他弹出窗口工作正常,显然这不是弹出窗口的常见问题,但它对我来说非常可重复。)

我使用了以下(不是很愉快)的工作。简单地使用绑定到它的东西关闭并打开弹出窗口的IsOpen不起作用 - 一旦它崩溃打开,弹出窗口就完全被破坏,直到它被卸载(更改视图)并再次加载。

所以解决方案是捕获错误,从它的父节点中删除弹出窗口,然后安排它在调度线程上异步添加。我不得不停止简单地绑定到IsOpen,而是听取代码隐藏中的属性更改。

我发现此错误的其他实例与互联网上的弹出窗口没有关系,尽管还有其他各种原因。这对未来的某些人来说可能有用:

    private void HelpPopup_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        if (e.PropertyName.Equals("IsOpen"))
        {
            //re-try opening
            try {
                Popup.IsOpen = (sender as HelpTip).IsOpen;
            }
            catch (System.ComponentModel.Win32Exception ex)
            {
                Canvas parent = Popup.Parent as Canvas;
                Popup.IsOpen = false;
                parent.Children.Remove(Popup);
                Application.Current.Dispatcher.BeginInvoke(new Action(() => {
                    Popup.IsOpen = true;
                    parent.Children.Add(Popup);

                    //known method of updating position (for some reason it was incorrectly positioned on open)
                    var offset = Popup.HorizontalOffset;
                    Popup.HorizontalOffset = offset + 1;
                    Popup.HorizontalOffset = offset;

                }), DispatcherPriority.SystemIdle);

            }
        }
    }

答案 1 :(得分:0)

如果在弹出窗口中使用任何网格,则应提供该网格的高度。否则它将占用无限高度,并且在渲染过程中,它将尝试显示具有无限高度网格的弹出窗口并将被崩溃。

相关问题