Problem with deserialization of dynamically created ToolWind

Docking/MDI for WPF Forum

Posted 9 years ago by Andreas Boerzel - Software Architect, REALTECH Software Products GmbH
Version: 9.2.0514
Avatar
I want to serialize and deserialize the layout of a DockSite that contains dynamically created ToolWindows using the DockSiteLayoutSerializer. The serialization works fine, but the deserialization does not work as expected!

Code snipped:
  public partial class GroupPanel : ToolWindow, ITimerange, INotifiyTimerangeChanged
 {
. . . 
 }

 public class PanelLayout
 {
    private string _layout;

    [XmlAttribute()]
    public string Layout
    {
       get
       {
          return _layout;
       }
       set
       {
          _layout = value;
       }
    }
}

public partial class Dashboard : DocumentWindow, ITimerange, INotifiyTimerangeChanged
{
      public void Save()
      {
         XmlDocument xmlDasboard = new XmlDocument();

         XmlNode xmlDashboardNode = xmlDasboard.CreateElement("Dashboard");

         XmlAttribute attrDashboardName = xmlDasboard.CreateAttribute("Name");
         attrDashboardName.Value = this.Title;
         xmlDashboardNode.Attributes.Append(attrDashboardName);

         XmlAttribute attrDashboardVersion = xmlDasboard.CreateAttribute("Version");
         attrDashboardVersion.Value = "1.0";
         xmlDashboardNode.Attributes.Append(attrDashboardVersion);

         xmlDasboard.AppendChild(xmlDashboardNode);


         XmlNode xmlLayoutNode = xmlDasboard.CreateElement("Layout");

         if (_layoutSerializer == null)
         {
            _layoutSerializer = new DockSiteLayoutSerializer();
         }

         _layoutSerializer.CustomTypes.Add(typeof(PanelLayout));  // Register the custom data type
 _layoutSerializer.ObjectSerializedHandler = new EventHandler<ItemSerializationEventArgs>(OnObjectSerialized);

         xmlLayoutNode.InnerXml = _layoutSerializer.SaveToString(_dockSite);
         xmlDashboardNode.AppendChild(xmlLayoutNode);

         xmlDasboard.Save(@"c:\temp\dashboard.xml");
      }

public void Load()
{
         XmlDocument xmlDasboard = new XmlDocument();

         xmlDasboard.Load(@"c:\temp\dashboard.xml");

         XmlNode dashboard = xmlDasboard.SelectSingleNode("//Dashboard");

         string version = dashboard.Attributes["Version"].Value;

         if (version != "1.0")
         {
            return;
         }
    
         for (int n = _workspace.ToolWindows.Count - 1; n >= 0; n--)
         {
            ToolWindow window = _workspace.ToolWindows[n];
            window.Destroy();
         }

         Title = dashboard.Attributes["Name"].Value;

         XmlNode layout = xmlDasboard.SelectSingleNode("//Dashboard/Layout");

         if (_layoutSerializer == null)
         {
            _layoutSerializer = new DockSiteLayoutSerializer();
         }

         _layoutSerializer.CustomTypes.Add(typeof(PanelLayout));  // Register the custom data type
         _layoutSerializer.ObjectDeserializedHandler = new EventHandler<ItemSerializationEventArgs>(OnObjectDeserialized);
         _layoutSerializer.CanLoadToolWindowTitles = true;

         _layoutSerializer.LoadFromString(layout.InnerXml, _dockSite);

      }

      private void OnObjectSerialized(object sender, ItemSerializationEventArgs e)
      {
         if (e.Node is XmlDockSiteLayout)
         {
            
         }
         else if (e.Node is XmlToolWindow)
         {
            GroupPanel panel = e.Item as GroupPanel;
            PanelLayout layout = new PanelLayout();
            layout.Layout = panel.GetLayout();
            e.Node.Tag = layout;                        
         }
      }

      private void OnObjectDeserialized(object sender, ItemSerializationEventArgs e)
      {
         if (e.Node is XmlDockSiteLayout)
         {

         }
         else if (e.Node is XmlToolWindow)
         {
            <b>=> This code is never called!!!</b>            
            GroupPanel panel = new GroupPanel(this, _dockSite);
            PanelLayout layout = e.Node.Tag as PanelLayout;
            panel.RestoreLayout(layout.Layout);
         }
      }

}
Does anyone have an idea??

Thaks Andreas

Comments (4)

Posted 9 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
Hi Andreas,

We still have a TODO item to make it easier to reload tool windows that aren't "known" to the DockSite at the time you reload a layout. I'll mark your post down with that TODO item.

However in the meantime, what I'd recommend is that you scan the layout XML before you load it. Look at all the ToolWindow tags and if there are some listed for tool windows that haven't been registered yet with the DockSite, create them. Then load the layout and they will be found.

In the future we hope to add some sort of callback event, etc. that will let you handle this easier but that should get you going for now.


Actipro Software Support

Posted 9 years ago by Andreas Boerzel - Software Architect, REALTECH Software Products GmbH
Avatar
Thank you for your answer. Can you tell me until when the TODO item is planned to be released??

Andreas
Posted 9 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
Sorry we don't have a target date for this at this time since we have some higher priority items to work on first. You can either use the workaround we mentioned or if you need this feature implemented right now, you can hire us to implement it immediately:
http://www.actiprosoftware.com/Purchase/ConsultingServices.aspx


Actipro Software Support

Posted 8 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
Hi Andreas,

Just fyi, we added support for lazy loading of layout data or automatically creating ToolWindows that are in the layout data, but not currently registered with the DockSite. You can see this feature in action in the current WPF Studio version available.


Actipro Software Support

The latest build of this product (v2018.1 build 0675) was released 1 month ago, which was after the last post in this thread.

Add Comment

Please log in to a validated account to post comments.