Avalon dock - Null Exception and Duplicate LayoutAnchorable After XmlLayoutSerializer.Deserialize Float an existing Window

Nov 13, 2014 at 12:12 PM
Edited Nov 13, 2014 at 12:29 PM
Similar issue has been previously logged in following link,
https://avalondock.codeplex.com/workitem/16204

I am able to replicate the issue associated with LayoutAnchorable.Float() and this happens specifically after Layout Reload using XmlLayoutSerializer.Deserialize()

I am using latest version of AvalonDock control i.e. Version 2.3.0.0

To reproduce -
1 - Run the application, Click Button - 1 or Button - 2 - Will get NullPointerException.
2 - In order to get Away from NullPointerException - I tried (Uncomment the line in LoadLayOut function Last line.
_mainRoot.Manager = layoutSerializer.Manager;

As I found layoutRoot's manger was null during Null exception - But then Floating window starts appearing but existing one docked in the Window remains.

May I please request help with following,
A- Best way to get rid of null exception.
B- Why does existing docked window remains on mainWindow if I tried 2 above?


PS: IN case sample code download is a problem,

UI-
<Window x:Class="AvalonBug.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="Auto" Width="1136"               
        xmlns:ad="http://schemas.xceed.com/wpf/xaml/avalondock" 
        xmlns:dockTheme="clr-namespace:Xceed.Wpf.AvalonDock.Themes;assembly=Xceed.Wpf.AvalonDock.Themes.Aero">
    <Window.Resources>
        <ResourceDictionary>
            <dockTheme:AeroTheme x:Key="aeroDockTheme"/>
        </ResourceDictionary>
    </Window.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="210"/>
            <RowDefinition Height="400"/>
        </Grid.RowDefinitions>
        <Button Content="1" Grid.Row="0" Height="20" Width="20" HorizontalAlignment="Left" Margin="10" Click="Button_Click"/>
        <Button Content="2" Grid.Row="0" Height="20" Width="20" HorizontalAlignment="Left" Margin="40,10,10,10" Click="Button_Click_1" />
        
        <ad:DockingManager Grid.Row="2" x:Name="_mainDock" IsManipulationEnabled="False" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" 
                               Theme="{StaticResource aeroDockTheme}">
            <ad:LayoutRoot x:Name="_mainRoot">
                <ad:LayoutPanel Orientation="Vertical" IsMaximized="True" x:Name="_mainResizingPanel">
                    <ad:LayoutAnchorablePane x:Name="_mainDockablePane" IsMaximized="True">
                    </ad:LayoutAnchorablePane>
                </ad:LayoutPanel>
            </ad:LayoutRoot>
        </ad:DockingManager>
        <TextBlock Grid.Row="1" Height="200" Width="1100" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="5" Name="txtLayout" TextWrapping="Wrap"/>
    </Grid>
</Window>
Code Behind:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

using Xceed.Wpf.AvalonDock;
using Xceed.Wpf.AvalonDock.Controls;
using Xceed.Wpf.AvalonDock.Layout;
using Xceed.Wpf.AvalonDock.Layout.Serialization;

using System.IO;
using System.Xml;
using System.Xml.Serialization;

namespace AvalonBug
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        LayoutAnchorable dc = null;
        LayoutAnchorable dc1 = null;
        public MainWindow()
        {
            InitializeComponent();
            
            LoadLayOut();            
            dc = new LayoutAnchorable();
            dc.Title = "Test1";
            dc.ContentId = "dc" + dc.Title;
            dc.Content = new TextBlock() { Text = dc.Title };
            dc.Parent = _mainRoot;
            _mainDockablePane.Children.Add(dc);

            dc1 = new LayoutAnchorable();
            dc1.Title = "Test2";
            dc1.ContentId = "dc" + dc1.Title;
            dc1.Content = new TextBlock() { Text = dc1.Title };
            _mainDockablePane.Children.Add(dc1);
        }

        void LoadLayOut()
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location) + "\\Lib\\" + "SampleLayout.xml");
            txtLayout.Text = doc.InnerXml;

            if (!string.IsNullOrEmpty(doc.InnerXml))
            {
                XmlLayoutSerializer layoutSerializer = new XmlLayoutSerializer(_mainDock);
                layoutSerializer.LayoutSerializationCallback += (s, c) =>
                {
                    object o = c.Content;
                };

                layoutSerializer.Deserialize(new StringReader(doc.InnerXml));
                //_mainRoot.Manager = layoutSerializer.Manager;
            }
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            if (null != dc)
            {
                dc.Float();
            }
        }

        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            if (null != dc1)
            {
                dc1.Float();
            }
        }
    }
}
Docking Profile XML
<?xml version="1.0" encoding="utf-16"?>
<LayoutRoot xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <RootPanel Orientation="Vertical" IsMaximized="True">
    <LayoutAnchorablePaneGroup Orientation="Horizontal" FloatingWidth="501" FloatingHeight="264" FloatingLeft="67" FloatingTop="208">
      <LayoutAnchorablePane FloatingWidth="501" FloatingHeight="264" FloatingLeft="67" FloatingTop="208">
        <LayoutAnchorable AutoHideMinWidth="100" AutoHideMinHeight="100" Title="Test2" IsSelected="True" ContentId="dcTest2" FloatingLeft="67" FloatingTop="208" FloatingWidth="501" FloatingHeight="264" LastActivationTimeStamp="11/13/2014 20:46:42" />
      </LayoutAnchorablePane>
    </LayoutAnchorablePaneGroup>
    <LayoutAnchorablePane Id="6867f671-c910-45a0-aa73-93e4cbc1cd03" IsMaximized="True">
      <LayoutAnchorable AutoHideMinWidth="100" AutoHideMinHeight="100" Title="Test1" IsSelected="True" ContentId="dcTest1" LastActivationTimeStamp="11/13/2014 20:46:36" />
    </LayoutAnchorablePane>
  </RootPanel>
  <TopSide />
  <RightSide />
  <LeftSide />
  <BottomSide />
  <FloatingWindows />
  <Hidden />
</LayoutRoot>