[Version 2.0] NullReferenceException when deserialize with layoutSerializer

May 16, 2012 at 1:12 PM

Hello AvalonDock team,

when I load a saved layout with the MVVMTestApp, I get an NullReferenceException in class LayoutGroup<T> in the method ReadXml(... on Children.Add((T)serializer.Desserialize(reader)).

The serializer is null, because the reader.LocalName is "LastActivationTimeStamp".

 

Now the steps to generate the exception:

-Start the MVVMTestApp

-Select File->New two times, so you have two open LayoutDocuments in an LayoutDocumentPanel

- Save the layout with Layout->Save

- Load the Layout and then you get the NullReferenceException

Thanks!

May 16, 2012 at 3:17 PM

It seems more an issue than a discussion :) fixed in latest version, please download it,thx

Aug 23, 2013 at 12:24 AM
Hello.

I faced with the same exception, but the reason is different.
The xml file:
<?xml version="1.0"?>
<LayoutRoot xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <RootPanel Orientation="Vertical">
    <LayoutPanel Orientation="Horizontal">
      <LayoutPanel Orientation="Horizontal">
        <LayoutDocumentPaneGroup Orientation="Horizontal">
          <LayoutDocumentPane />
        </LayoutDocumentPaneGroup>
      </LayoutPanel>
      <LayoutAnchorablePane Id="3ba1644a-5939-4180-9b12-b599c572386e" DockWidth="200">
        <LayoutAnchorable AutoHideMinWidth="100" AutoHideMinHeight="100" Title="Assets" IsSelected="True" ContentId="AssetsViewTool" LastActivationTimeStamp="08/23/2013 02:37:27" />
      </LayoutAnchorablePane>
    </LayoutPanel>
    <LayoutAnchorablePaneGroup Orientation="Horizontal" DockHeight="257.5" FloatingWidth="200" FloatingHeight="515" FloatingLeft="323" FloatingTop="577">
      <LayoutAnchorablePane DockHeight="257.5" FloatingWidth="200" FloatingHeight="515" FloatingLeft="323" FloatingTop="577">
        <LayoutAnchorable AutoHideMinWidth="100" AutoHideMinHeight="100" Title="Output" IsSelected="True" ContentId="OutputContentId" FloatingLeft="323" FloatingTop="577" FloatingWidth="200" FloatingHeight="515" LastActivationTimeStamp="08/23/2013 02:37:29" PreviousContainerId="3ba1644a-5939-4180-9b12-b599c572386e" PreviousContainerIndex="1" />
      </LayoutAnchorablePane>
    </LayoutAnchorablePaneGroup>
  </RootPanel>
  <TopSide />
  <RightSide />
  <LeftSide />
  <BottomSide />
  <FloatingWindows />
  <Hidden />
</LayoutRoot>
Cause of it is formated (new lines and tabs) when it is deserializing the reader.LocalName is empthy, cause reader.NodeType == Whitespace.
So i've changed the while cycle in ReadXml:
public virtual void ReadXml(System.Xml.XmlReader reader)
{
    reader.MoveToContent();
    if (reader.IsEmptyElement)
    {
        reader.Read();
        ComputeVisibility();
        return;
    }

    string localName = reader.LocalName;
    reader.Read();

    while (true)
    {
        reader.MoveToContent();

        if (reader.LocalName == localName && reader.NodeType == System.Xml.XmlNodeType.EndElement)
            break;

        XmlSerializer serializer = null;

        switch (reader.LocalName)
        {
            case "LayoutAnchorablePaneGroup":
                serializer = new XmlSerializer(typeof(LayoutAnchorablePaneGroup));
                break;
            case "LayoutAnchorablePane":
                serializer = new XmlSerializer(typeof(LayoutAnchorablePane));
                break;
            case "LayoutAnchorable":
                serializer = new XmlSerializer(typeof(LayoutAnchorable));
                break;
            case "LayoutDocumentPaneGroup":
                serializer = new XmlSerializer(typeof(LayoutDocumentPaneGroup));
                break;
            case "LayoutDocumentPane":
                serializer = new XmlSerializer(typeof(LayoutDocumentPane));
                break;
            case "LayoutDocument":
                serializer = new XmlSerializer(typeof(LayoutDocument));
                break;
            case "LayoutAnchorGroup":
                serializer = new XmlSerializer(typeof(LayoutAnchorGroup));
                break;
            case "LayoutPanel":
                serializer = new XmlSerializer(typeof(LayoutPanel));
                break;

            default:
                throw new InvalidDataException("Invalid name of block: " + reader.LocalName + ";");
        }

        Children.Add((T)serializer.Deserialize(reader));
    }

    reader.ReadEndElement();
}
and it's work.