Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Null Reference Exception inserting documents when isActive is set before insertion #17

Closed
Dirkster99 opened this issue Apr 19, 2019 · 1 comment

Comments

@Dirkster99
Copy link
Owner

Dirkster99 commented Apr 19, 2019

Original Issue: #1481

I have an application using the AvalonDock library, and to fix an issue with new documents not showing content correctly (#1480), we have to set the IsActive property on the LayoutDocument to true in the BeforeInsertDocument method of the ILayoutUpdateStrategy implementation.

With this setup, the library throws a Null Reference Exception under these circumstances:

  1. Open enough new documents such that the tab headers fill the available width of the screen.
  2. The next document you open will be added at the start of the list instead of the end
  3. Click inside the document to give it focus
  4. Open another new document
  5. AvalonDock throws a Null Reference Exception

I have been able to produce a sample application that produces the same error; which is simply the DocumentOpenSample modified to set the IsActive property as described.

DocumentOpenSample.zip

@Dirkster99
Copy link
Owner Author

The source of the problem and the fix is located in Xceed.Wpf.AvalonDock.Controls.DocumentPaneTabPanel class at line 54 where the following code crashes at the line where the if statement checks

  • the layoutContent with
  • if( layoutContent.IsSelected && !doc.IsVisible )

This fix lets the rest of the code work as before but won't crash on your test case :-) So, the better solution is to move the layoutContent variable inside the if statement (because its only used there) and use a boolean to determine whether the layoutContent is selected or not:

DocumentOpenSample_V2.zip

    protected override Size ArrangeOverride( Size finalSize )
    {
      var visibleChildren = Children.Cast<UIElement>().Where( ch => ch.Visibility != System.Windows.Visibility.Collapsed );
      var offset = 0.0;
      var skipAllOthers = false;
      foreach( TabItem doc in visibleChildren )
      {
        if( skipAllOthers || offset + doc.DesiredSize.Width > finalSize.Width )
        {
          bool isLayoutContentSelected = false;
          var layoutContent = doc.Content as LayoutContent;

          if (layoutContent != null)
            isLayoutContentSelected = layoutContent.IsSelected;

          if (isLayoutContentSelected && !doc.IsVisible )
          {
            var parentContainer = layoutContent.Parent as ILayoutContainer;
            var parentSelector = layoutContent.Parent as ILayoutContentSelector;
            var parentPane = layoutContent.Parent as ILayoutPane;
            int contentIndex = parentSelector.IndexOf( layoutContent );
            if( contentIndex > 0 &&
                parentContainer.ChildrenCount > 1 )
            {
              parentPane.MoveChild( contentIndex, 0 );
              parentSelector.SelectedContentIndex = 0;
              return ArrangeOverride( finalSize );
            }
          }
          doc.Visibility = System.Windows.Visibility.Hidden;
          skipAllOthers = true;
        }
        else
        {
          doc.Visibility = System.Windows.Visibility.Visible;
          doc.Arrange( new Rect( offset, 0.0, doc.DesiredSize.Width, finalSize.Height ) );
          offset += doc.ActualWidth + doc.Margin.Left + doc.Margin.Right;
        }
      }
      return finalSize;

    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant