2017-08-11 38 views
0

我有我自己的ApplicationModalAdorner。有時我從GetLayoutClip()得到一個InvalidOperationException,我重寫。致電TransformToAncestor會導致異常。我無法重現異常(我在日誌中看到了很多異常)。也許窗口不完整呈現?我正在尋找一個複製品(可能在一個簡單的應用程序中)以及此異常的原因/解決方案。我在同一分鐘裏有幾次例外。我更喜歡沒有Dispatcher的解決方案。ApplicationModalAdorner GetLayoutClip()InvalidOperationException

相關調用堆棧部分:

Wrapped Exception: System.InvalidOperationException: An exception occured while handling another exception; 
    bij System.Windows.Media.Visual.TrySimpleTransformToAncestor(Visual ancestor, Boolean inverse, GeneralTransform& generalTransform, Matrix& simpleTransform) 
    bij System.Windows.Media.Visual.TransformToAncestor(Visual ancestor) 
    bij x.x.x.ApplicationModalAdorner.WindowRect() 
    bij x.x.x.ApplicationModalAdorner.GetLayoutClip(Size layoutSlotSize) 
    bij System.Windows.UIElement.ensureClip(Size layoutSlotSize) 
    bij System.Windows.UIElement.Arrange(Rect finalRect) 
    bij System.Windows.Documents.AdornerLayer.ArrangeOverride(Size finalSize) 
    bij System.Windows.FrameworkElement.ArrangeCore(Rect finalRect) 
    bij System.Windows.UIElement.Arrange(Rect finalRect) 
    bij System.Windows.Documents.AdornerDecorator.ArrangeOverride(Size finalSize) 
    bij System.Windows.FrameworkElement.ArrangeCore(Rect finalRect) 
    bij System.Windows.UIElement.Arrange(Rect finalRect) 
    bij System.Windows.Controls.Control.ArrangeOverride(Size arrangeBounds) 
    bij System.Windows.FrameworkElement.ArrangeCore(Rect finalRect) 
    bij System.Windows.UIElement.Arrange(Rect finalRect) 
    bij MS.Internal.Helper.ArrangeElementWithSingleChild(UIElement element, Size arrangeSize) 
    bij System.Windows.Controls.ContentPresenter.ArrangeOverride(Size arrangeSize) 
    bij System.Windows.FrameworkElement.ArrangeCore(Rect finalRect) 
    bij System.Windows.UIElement.Arrange(Rect finalRect) 
    bij System.Windows.Controls.Grid.ArrangeOverride(Size arrangeSize) 
    bij System.Windows.FrameworkElement.ArrangeCore(Rect finalRect) 
    bij System.Windows.UIElement.Arrange(Rect finalRect) 

代碼

public class ApplicationModalAdorner : Adorner 
{ 
    private SolidColorBrush _brush; 

    private XamDialogWindow Window 
    { 
     get 
     { 
      return (XamDialogWindow)AdornedElement; 
     } 
    } 

    private Window MainWindow 
    { 
     get 
     { 
      if (Application.Current != null) 
      { 
       return Application.Current.MainWindow; 
      } 
      return null; 
     } 
    } 

    public ApplicationModalAdorner(UIElement adornedElement) 
     : base(adornedElement) 
    { 
     _brush = (SolidColorBrush)FindResource("ModalBackgroundBrush"); 

     Window.Moved += WindowMoved; 
     Window.WindowStateChanged += WindowStateChanged; 
     MainWindow.SizeChanged += MainWindowSizeChanged; 
    } 

    // There is no WindowClosed event. Infragistics states that when a window is closed, 
    // the WindowStateChanged event gets triggerd and the value will be Hidden. Because 
    // the ApplicationModal windows cannot be hidden, this is a nice way to clean events. 
    private void WindowStateChanged(object sender, WindowStateChangedEventArgs e) 
    { 
     if (e.NewWindowState == Infragistics.Controls.Interactions.WindowState.Hidden) 
     { 
      Window.Moved -= WindowMoved; 
      Window.WindowStateChanged -= WindowStateChanged; 
      if (MainWindow != null) 
      { 
       MainWindow.SizeChanged -= MainWindowSizeChanged; 
      } 
     } 
    } 

    private void WindowMoved(object sender, MovedEventArgs e) 
    { 
     InvalidateVisual(); 
    } 

    private void MainWindowSizeChanged(object sender, SizeChangedEventArgs e) 
    { 
     InvalidateVisual(); 
    } 

    protected override void OnRender(DrawingContext drawingContext) 
    { 
     drawingContext.DrawRectangle(_brush, null, WindowRect()); 
     base.OnRender(drawingContext); 
    } 

    protected override Geometry GetLayoutClip(Size layoutSlotSize) 
    { 
     var xamDialogWindowRect = new Rect(new Point(Window.Left, Window.Top), layoutSlotSize); 
     var geometryGroup = new GeometryGroup(); 
     geometryGroup.Children.Add(new RectangleGeometry(WindowRect())); 
     geometryGroup.Children.Add(new RectangleGeometry(xamDialogWindowRect)); 
     return geometryGroup; 
    } 

    private Rect WindowRect() 
    { 
     var transformToAncestor = Window.TransformToAncestor(MainWindow); 
     var topLeft = transformToAncestor.Inverse.Transform(new Point(0, 0)); 
     var bottomRight = transformToAncestor.Inverse.Transform(new Point(MainWindow.ActualWidth, MainWindow.ActualHeight)); 
     return new Rect(topLeft, bottomRight); 
    } 

    public override GeneralTransform GetDesiredTransform(GeneralTransform transform) 
    { 
     InvalidateVisual(); 
     return base.GetDesiredTransform(transform); 
    } 
    } 
} 
+0

*「處理另一個異常時發生異常」*我可能對那裏提到的另一個異常感興趣......當整個事物已經處於奇怪狀態時得到一個異常並不像第一個失敗點。 – grek40

+0

@ grek40第一個異常是相同的異常,我得到了幾個相同的異常之後彼此短小 – Sybren

+0

您是否在第一次執行代碼時獲得相同的異常(斷點)? – grek40

回答

0

你的窗口中不存在可視化樹。您有兩種選擇:

  1. 收聽加載的事件。然後,加載時,開始監聽其他事件(Moved,WindowStateChanged,SizeChanged)。
  2. 在必要時使用調度程序,然後希望最好。

至於你請求一個示例應用程序,我可以向你保證,你所看到的問題是令人難以置信難以重現。

+0

我聯繫了Infragistics關於它,他們在他們的控件中遇到過同樣的問題,他們的解決方法是嘗試/捕獲修復它們的異常。 – Sybren