Browse Source

-Bug fix when restoring layout from xml. all of the "Sides" like leftside and rightside objects were being nulled out causing null reference exceptions when you tried to "unpin" a panel on one of the sides.

pull/1271/head
Paul J Aicher 9 years ago
parent
commit
8fa3191ea9
  1. 197
      ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutRoot.cs

197
ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutRoot.cs

@ -17,12 +17,9 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text;
using System.Windows;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Windows.Markup; using System.Windows.Markup;
using System.Xml.Serialization; using System.Xml.Serialization;
using Standard;
using System.Xml; using System.Xml;
using System.Xml.Schema; using System.Xml.Schema;
@ -334,7 +331,7 @@ namespace Xceed.Wpf.AvalonDock.Layout
#region ActiveContent #region ActiveContent
[field:NonSerialized] [field: NonSerialized]
private WeakReference _activeContent = null; private WeakReference _activeContent = null;
private bool _activeContentSet = false; private bool _activeContentSet = false;
@ -669,96 +666,88 @@ namespace Xceed.Wpf.AvalonDock.Layout
return null; return null;
} }
public void ReadXml( XmlReader reader ) public void ReadXml(XmlReader reader)
{ {
reader.MoveToContent(); reader.MoveToContent();
if( reader.IsEmptyElement ) if (reader.IsEmptyElement)
{ {
reader.Read(); reader.Read();
return; return;
} }
var layoutPanelElements = ReadRootPanel( reader ); var layoutPanelElements = ReadRootPanel(reader);
if( layoutPanelElements != null ) if (layoutPanelElements != null)
{ {
//Create the RootPanel with the first child //Create the RootPanel with the first child
RootPanel = new LayoutPanel( layoutPanelElements.First() ); RootPanel = new LayoutPanel(layoutPanelElements.First());
//Add all children to RootPanel //Add all children to RootPanel
for( int i = 1; i < layoutPanelElements.Count; ++i ) for (int i = 1; i < layoutPanelElements.Count; ++i)
{ {
RootPanel.Children.Add( layoutPanelElements[ i ] ); RootPanel.Children.Add(layoutPanelElements[i]);
} }
} }
TopSide = ( LayoutAnchorSide )ReadElement( reader ); TopSide = GetLayoutAnchorSide(reader);
if( TopSide != null ) RightSide = GetLayoutAnchorSide(reader);
{ LeftSide = GetLayoutAnchorSide(reader);
TopSide.Children.Add( ( LayoutAnchorGroup )ReadElement( reader ) ); BottomSide = GetLayoutAnchorSide(reader);
reader.Read();
} FloatingWindows.Clear();
RightSide = ( LayoutAnchorSide )ReadElement( reader ); var floatingWindows = ReadElementList(reader);
if( RightSide != null ) foreach (var floatingWindow in floatingWindows)
{ {
RightSide.Children.Add( ( LayoutAnchorGroup )ReadElement( reader ) ); FloatingWindows.Add((LayoutFloatingWindow)floatingWindow);
reader.Read();
} }
LeftSide = ( LayoutAnchorSide )ReadElement( reader );
if( LeftSide != null ) Hidden.Clear();
var hidden = ReadElementList(reader);
foreach (var hiddenObject in hidden)
{ {
LeftSide.Children.Add( ( LayoutAnchorGroup )ReadElement( reader ) ); Hidden.Add((LayoutAnchorable)hiddenObject);
reader.Read();
} }
BottomSide = ( LayoutAnchorSide )ReadElement( reader );
if( BottomSide != null )
{
BottomSide.Children.Add( ( LayoutAnchorGroup )ReadElement( reader ) );
reader.Read();
} }
FloatingWindows.Clear(); private LayoutAnchorSide GetLayoutAnchorSide(XmlReader reader)
var floatingWindows = ReadElementList( reader );
foreach( var floatingWindow in floatingWindows )
{ {
FloatingWindows.Add( ( LayoutFloatingWindow )floatingWindow ); var side = (LayoutAnchorSide)ReadElement(reader);
} if (side != null)
Hidden.Clear();
var hidden = ReadElementList( reader );
foreach( var hiddenObject in hidden )
{ {
Hidden.Add( ( LayoutAnchorable )hiddenObject ); side.Children.Add((LayoutAnchorGroup)ReadElement(reader));
reader.Read();
} }
return side ?? new LayoutAnchorSide();
} }
private List<ILayoutPanelElement> ReadRootPanel( XmlReader reader ) private List<ILayoutPanelElement> ReadRootPanel(XmlReader reader)
{ {
var result = new List<ILayoutPanelElement>(); var result = new List<ILayoutPanelElement>();
var startElementName = reader.LocalName; var startElementName = reader.LocalName;
reader.Read(); reader.Read();
if( reader.LocalName.Equals(startElementName) && (reader.NodeType == XmlNodeType.EndElement) ) if (reader.LocalName.Equals(startElementName) && (reader.NodeType == XmlNodeType.EndElement))
{ {
return null; return null;
} }
while( reader.NodeType == XmlNodeType.Whitespace ) while (reader.NodeType == XmlNodeType.Whitespace)
{ {
reader.Read(); reader.Read();
} }
if( reader.LocalName.Equals("RootPanel")) if (reader.LocalName.Equals("RootPanel"))
{ {
reader.Read(); reader.Read();
while( true ) while (true)
{ {
//Read all RootPanel children //Read all RootPanel children
var element = ReadElement( reader ) as ILayoutPanelElement; var element = ReadElement(reader) as ILayoutPanelElement;
if( element != null ) if (element != null)
{ {
result.Add( element ); result.Add(element);
} }
else if( reader.NodeType == XmlNodeType.EndElement ) else if (reader.NodeType == XmlNodeType.EndElement)
{ {
break; break;
} }
@ -770,11 +759,11 @@ namespace Xceed.Wpf.AvalonDock.Layout
return result; return result;
} }
private List<object> ReadElementList( XmlReader reader ) private List<object> ReadElementList(XmlReader reader)
{ {
var resultList = new List<object>(); var resultList = new List<object>();
if( reader.IsEmptyElement ) if (reader.IsEmptyElement)
{ {
reader.Read(); reader.Read();
return resultList; return resultList;
@ -782,25 +771,25 @@ namespace Xceed.Wpf.AvalonDock.Layout
var startElementName = reader.LocalName; var startElementName = reader.LocalName;
reader.Read(); reader.Read();
if( reader.LocalName.Equals(startElementName) && (reader.NodeType == XmlNodeType.EndElement) ) if (reader.LocalName.Equals(startElementName) && (reader.NodeType == XmlNodeType.EndElement))
{ {
return null; return null;
} }
while( reader.NodeType == XmlNodeType.Whitespace ) while (reader.NodeType == XmlNodeType.Whitespace)
{ {
reader.Read(); reader.Read();
} }
while( true ) while (true)
{ {
var result = ReadElement( reader ) as LayoutFloatingWindow; var result = ReadElement(reader) as LayoutFloatingWindow;
if( result == null ) if (result == null)
{ {
break; break;
} }
resultList.Add( result ); resultList.Add(result);
} }
reader.ReadEndElement(); reader.ReadEndElement();
@ -808,56 +797,56 @@ namespace Xceed.Wpf.AvalonDock.Layout
return resultList; return resultList;
} }
private object ReadElement( XmlReader reader ) private object ReadElement(XmlReader reader)
{ {
if( reader.NodeType == XmlNodeType.EndElement ) if (reader.NodeType == XmlNodeType.EndElement)
{ {
return null; return null;
} }
while( reader.NodeType == XmlNodeType.Whitespace ) while (reader.NodeType == XmlNodeType.Whitespace)
{ {
reader.Read(); reader.Read();
} }
XmlSerializer serializer; XmlSerializer serializer;
switch( reader.LocalName ) switch (reader.LocalName)
{ {
case "LayoutAnchorablePaneGroup": case "LayoutAnchorablePaneGroup":
serializer = new XmlSerializer( typeof( LayoutAnchorablePaneGroup ) ); serializer = new XmlSerializer(typeof(LayoutAnchorablePaneGroup));
break; break;
case "LayoutAnchorablePane": case "LayoutAnchorablePane":
serializer = new XmlSerializer( typeof( LayoutAnchorablePane ) ); serializer = new XmlSerializer(typeof(LayoutAnchorablePane));
break; break;
case "LayoutAnchorable": case "LayoutAnchorable":
serializer = new XmlSerializer( typeof( LayoutAnchorable ) ); serializer = new XmlSerializer(typeof(LayoutAnchorable));
break; break;
case "LayoutDocumentPaneGroup": case "LayoutDocumentPaneGroup":
serializer = new XmlSerializer( typeof( LayoutDocumentPaneGroup ) ); serializer = new XmlSerializer(typeof(LayoutDocumentPaneGroup));
break; break;
case "LayoutDocumentPane": case "LayoutDocumentPane":
serializer = new XmlSerializer( typeof( LayoutDocumentPane ) ); serializer = new XmlSerializer(typeof(LayoutDocumentPane));
break; break;
case "LayoutDocument": case "LayoutDocument":
serializer = new XmlSerializer( typeof( LayoutDocument ) ); serializer = new XmlSerializer(typeof(LayoutDocument));
break; break;
case "LayoutAnchorGroup": case "LayoutAnchorGroup":
serializer = new XmlSerializer( typeof( LayoutAnchorGroup ) ); serializer = new XmlSerializer(typeof(LayoutAnchorGroup));
break; break;
case "LayoutPanel": case "LayoutPanel":
serializer = new XmlSerializer( typeof( LayoutPanel ) ); serializer = new XmlSerializer(typeof(LayoutPanel));
break; break;
case "LayoutDocumentFloatingWindow": case "LayoutDocumentFloatingWindow":
serializer = new XmlSerializer( typeof( LayoutDocumentFloatingWindow ) ); serializer = new XmlSerializer(typeof(LayoutDocumentFloatingWindow));
break; break;
case "LayoutAnchorableFloatingWindow": case "LayoutAnchorableFloatingWindow":
serializer = new XmlSerializer( typeof( LayoutAnchorableFloatingWindow ) ); serializer = new XmlSerializer(typeof(LayoutAnchorableFloatingWindow));
break; break;
case "LeftSide": case "LeftSide":
case "RightSide": case "RightSide":
case "TopSide": case "TopSide":
case "BottomSide": case "BottomSide":
if( reader.IsEmptyElement ) if (reader.IsEmptyElement)
{ {
reader.Read(); reader.Read();
return null; return null;
@ -865,81 +854,81 @@ namespace Xceed.Wpf.AvalonDock.Layout
reader.Read(); reader.Read();
return new LayoutAnchorSide(); return new LayoutAnchorSide();
default: default:
var type = LayoutRoot.FindType( reader.LocalName ); var type = LayoutRoot.FindType(reader.LocalName);
if( type == null ) if (type == null)
{ {
throw new ArgumentException( "AvalonDock.LayoutRoot doesn't know how to deserialize " + reader.LocalName ); throw new ArgumentException("AvalonDock.LayoutRoot doesn't know how to deserialize " + reader.LocalName);
} }
serializer = new XmlSerializer( type ); serializer = new XmlSerializer(type);
break; break;
} }
return serializer.Deserialize( reader ); return serializer.Deserialize(reader);
} }
public void WriteXml( XmlWriter writer ) public void WriteXml(XmlWriter writer)
{ {
writer.WriteStartElement( "RootPanel" ); writer.WriteStartElement("RootPanel");
if( RootPanel != null ) if (RootPanel != null)
{ {
RootPanel.WriteXml( writer ); RootPanel.WriteXml(writer);
} }
writer.WriteEndElement(); writer.WriteEndElement();
writer.WriteStartElement( "TopSide" ); writer.WriteStartElement("TopSide");
if( TopSide != null ) if (TopSide != null)
{ {
TopSide.WriteXml( writer ); TopSide.WriteXml(writer);
} }
writer.WriteEndElement(); writer.WriteEndElement();
writer.WriteStartElement( "RightSide" ); writer.WriteStartElement("RightSide");
if( RightSide != null ) if (RightSide != null)
{ {
RightSide.WriteXml( writer ); RightSide.WriteXml(writer);
} }
writer.WriteEndElement(); writer.WriteEndElement();
writer.WriteStartElement( "LeftSide" ); writer.WriteStartElement("LeftSide");
if( LeftSide != null ) if (LeftSide != null)
{ {
LeftSide.WriteXml( writer ); LeftSide.WriteXml(writer);
} }
writer.WriteEndElement(); writer.WriteEndElement();
writer.WriteStartElement( "BottomSide" ); writer.WriteStartElement("BottomSide");
if( BottomSide != null ) if (BottomSide != null)
{ {
BottomSide.WriteXml( writer ); BottomSide.WriteXml(writer);
} }
writer.WriteEndElement(); writer.WriteEndElement();
// Write all floating windows (can be LayoutDocumentFloatingWindow or LayoutAnchorableFloatingWindow). // Write all floating windows (can be LayoutDocumentFloatingWindow or LayoutAnchorableFloatingWindow).
// To prevent "can not create instance of abstract type", the type is retrieved with GetType().Name // To prevent "can not create instance of abstract type", the type is retrieved with GetType().Name
writer.WriteStartElement( "FloatingWindows" ); writer.WriteStartElement("FloatingWindows");
foreach( var layoutFloatingWindow in FloatingWindows ) foreach (var layoutFloatingWindow in FloatingWindows)
{ {
writer.WriteStartElement( layoutFloatingWindow.GetType().Name ); writer.WriteStartElement(layoutFloatingWindow.GetType().Name);
layoutFloatingWindow.WriteXml( writer ); layoutFloatingWindow.WriteXml(writer);
writer.WriteEndElement(); writer.WriteEndElement();
} }
writer.WriteEndElement(); writer.WriteEndElement();
writer.WriteStartElement( "Hidden" ); writer.WriteStartElement("Hidden");
foreach( var layoutAnchorable in Hidden ) foreach (var layoutAnchorable in Hidden)
{ {
layoutAnchorable.WriteXml( writer ); layoutAnchorable.WriteXml(writer);
} }
writer.WriteEndElement(); writer.WriteEndElement();
} }
internal static Type FindType( string name ) internal static Type FindType(string name)
{ {
foreach( var assembly in AppDomain.CurrentDomain.GetAssemblies() ) foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
{ {
foreach( var type in assembly.GetTypes() ) foreach (var type in assembly.GetTypes())
{ {
if( type.Name.Equals( name ) ) if (type.Name.Equals(name))
return type; return type;
} }
} }

Loading…
Cancel
Save