Click here to Skip to main content
15,879,348 members
Articles / Desktop Programming / WPF

WPF Docking Library

Rate me:
Please Sign up or sign in to vote.
4.78/5 (85 votes)
17 Jul 2007CPOL3 min read 1M   24.4K   317  
A WPF library to easily integrate Windows docking features in applications like VS
using System;
using System.Collections.Generic;
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 System.Xml;

namespace DockingLibrary
{
    /// <summary>
    /// States that a dockable pane can assume
    /// </summary>
    public enum PaneState
    { 
        Hidden,

        AutoHide,

        Docked,

        TabbedDocument,

        FloatingWindow,

        DockableWindow
    }


    /// <summary>
    /// A dockable pane is a resizable and movable window region which can host one or more dockable content
    /// </summary>
    /// <remarks>A dockable pane occupies a window region. It can be in two different states: docked to a border or hosted in a floating window.
    /// When is docked it can be resizes only in a direction. User can switch between pane states using mouse or context menus.
    /// Contents whitin a dockable pane are arranged through a tabcontrol.</remarks>
    partial class DockablePane : Pane
    {
 
        /// <summary>
        /// When created pane is hidden
        /// </summary>
        protected PaneState _state = PaneState.Hidden;

        /// <summary>
        /// Get pane state
        /// </summary>
        public PaneState State
        {
            get
            {
                return _state;
            }
        }

        /// <summary>
        /// Show/hide pane header (title, buttons etc...)
        /// </summary>
        public bool ShowHeader
        {
            get 
            {
                return PaneHeader.Visibility == Visibility.Visible;
            }
            set 
            {
                if (value)
                    PaneHeader.Visibility = Visibility.Visible;
                else
                    PaneHeader.Visibility = Visibility.Collapsed;
            }
        }

        /// <summary>
        /// Current docking border
        /// </summary>
        Dock _dock = Dock.Right;

        /// <summary>
        /// Current docking border
        /// </summary>
        public Dock Dock
        {
            get
            {
                return _dock;
            }
        }


        public DockablePane(DockManager dockManager) : this(dockManager, Dock.Right) { }
        public DockablePane(DockManager dockManager, Dock initialDock) : base(dockManager)
        {
            _dock = initialDock;
            InitializeComponent();

            //this.GotFocus += new RoutedEventHandler(item_GotFocus);

        }

        /// <summary>
        /// Active visible content
        /// </summary>
        public override DockableContent ActiveContent
        {
            get 
            {
                if (VisibleContents.Count == 1)
                    return VisibleContents[0];
                else if (VisibleContents.Count > 1)
                    return VisibleContents[tbcContents.SelectedIndex];

                return null;
            }
            set
            {
                if (VisibleContents.Count > 1)
                {
                    tbcContents.SelectedIndex = VisibleContents.IndexOf(value);
                }
            }
        }
        /// <summary>
        /// Event raised when title is changed
        /// </summary>
        public event EventHandler OnTitleChanged;

        /// <summary>
        /// Change pane's title and fires OnTitleChanged event
        /// </summary>
        public override void RefreshTitle()
        {
            if (ActiveContent != null)
            {
                tbTitle.Text = Title;

                if (tbcContents.Items.Count > 0)
                {
                    SetTabItemHeader(
                        tbcContents.Items[VisibleContents.IndexOf(ActiveContent)] as TabItem,
                        ActiveContent);
                }
                if (OnTitleChanged != null)
                    OnTitleChanged(this, new EventArgs());
            }
        }


        /// <summary>
        /// Get pane title
        /// </summary>
        public virtual string Title
        {
            get 
            {
                if (ActiveContent != null)
                    return ActiveContent.Title;

                return null;
            }
        }
        /// <summary>
        /// Get visible contents
        /// </summary>
        public readonly List<DockableContent> VisibleContents = new List<DockableContent>();

        /// <summary>
        /// Add a dockable content to Contents list
        /// </summary>
        /// <param name="content">Content to add</param>
        /// <remarks>Content is automatically shown.</remarks>
        public override void Add(DockableContent content)
        {
            if (Contents.Count == 0)
            {
                SaveFloatingWindowSizeAndPosition(content);
            }


            base.Add(content);
        }

        /// <summary>
        /// Remove a content from pane Contents list
        /// </summary>
        /// <param name="content">Content to remove</param>
        /// <remarks>Notice that when no more contents are present in a pane, it is automatically removed</remarks>
        public override void Remove(DockableContent content)
        {
            Hide(content);

            base.Remove(content);

            if (Contents.Count == 0)
                DockManager.Remove(this);
        }

        /// <summary>
        /// Show a content previuosly added
        /// </summary>
        /// <param name="content">DockableContent object to show</param>
        public override void Show(DockableContent content)
        {
            AddVisibleContent(content);

            if (VisibleContents.Count == 1 && State == PaneState.Hidden)
            {
                ChangeState(PaneState.Docked);
                DockManager.DragPaneServices.Register(this);
            }


            base.Show(content);
        }

        /// <summary>
        /// Hide a contained dockable content
        /// </summary>
        /// <param name="content">DockableContent object to hide</param>
        /// <remarks>Pane is automatically hidden if no more visible contents are shown</remarks>
        public override void Hide(DockableContent content)
        {
            RemoveVisibleContent(content);

            if (VisibleContents.Count == 0 && State==PaneState.Docked)
                Hide();

            base.Hide(content);
        }

        /// <summary>
        /// Add a visible content
        /// </summary>
        /// <param name="content">DockableContent object to add</param>
        /// <remarks>If more then one contents are visible, this method dinamically creates a tab control and
        /// adds new content to it.</remarks>
        void AddVisibleContent(DockableContent content)
        {
            if (VisibleContents.Contains(content))
                return;

            if (VisibleContents.Count == 0)
            {
                VisibleContents.Add(content);
                ShowSingleContent(content);
            }
            else if (VisibleContents.Count == 1)
            {
                HideSingleContent(VisibleContents[0]);
                AddItem(VisibleContents[0]);
                VisibleContents.Add(content);
                AddItem(content);
                ShowTabs();
            }
            else
            {
                VisibleContents.Add(content);
                AddItem(content);
            }
        }

        /// <summary>
        /// Remove a visible content from pane
        /// </summary>
        /// <param name="content">DockableContent object to remove</param>
        /// <remarks>Remove related tab item from contents tab control. if only one content is visible than hide tab control.</remarks>
        void RemoveVisibleContent(DockableContent content)
        {
            if (!VisibleContents.Contains(content))
                return;

            if (VisibleContents.Count == 1)
            {
                VisibleContents.Remove(content);
                HideSingleContent(content);
                HideTabs();
            }
            else if (VisibleContents.Count == 2)
            {
                RemoveItem(VisibleContents[0]);
                RemoveItem(VisibleContents[1]);
                VisibleContents.Remove(content);
                ShowSingleContent(VisibleContents[0]);
                HideTabs();
            }
            else
            {
                VisibleContents.Remove(content);
                RemoveItem(content);
            }
        }

        /// <summary>
        /// Close a dockable content
        /// </summary>
        /// <param name="content">DockableContent object to close</param>
        /// <remarks>In this library version this method simply hide the content</remarks>
        public override void Close(DockableContent content)
        {
            Hide(content);
        }

        #region Contents management
        private bool IsSingleContentVisible
        {
            get { return cpClientWindowContent.Visibility == Visibility.Visible; }
        }

        void ShowSingleContent(DockableContent content)
        {
            cpClientWindowContent.Content = content.Content;
            cpClientWindowContent.Visibility = Visibility.Visible;
            RefreshTitle();
        }

        void HideSingleContent(DockableContent content)
        {
            cpClientWindowContent.Content = null; 
            cpClientWindowContent.Visibility = Visibility.Collapsed;
        }


        private bool IsContentsTbcVisible
        {
            get { return tbcContents.Visibility == Visibility.Visible; }
        }

        protected void ShowTabs()
        {
            tbcContents.SelectionChanged += new SelectionChangedEventHandler(_tabs_SelectionChanged);
            tbcContents.Visibility = Visibility.Visible;
        }

        protected void HideTabs()
        {
            tbcContents.SelectionChanged -= new SelectionChangedEventHandler(_tabs_SelectionChanged);
            tbcContents.Visibility = Visibility.Collapsed;
        }

        void SetTabItemHeader(TabItem item, DockableContent content)
        {
            StackPanel spHeader = new StackPanel();
            spHeader.Orientation = Orientation.Horizontal;
            Image iconContent = new Image();
            iconContent.Source = content.Icon;
            spHeader.Children.Add(iconContent);
            TextBlock titleContent = new TextBlock();
            titleContent.Text = content.Title;
            titleContent.Margin = new Thickness(2, 0, 0, 0);
            spHeader.Children.Add(titleContent);
            item.Header = spHeader;
        }

        protected virtual void AddItem(DockableContent content)
        {
            TabItem item = new TabItem();
            DockPanel tabPanel = new DockPanel();

            //SetTabItemHeader(item, content);

            item.Style = FindResource("DockablePaneTabItemStyle") as Style;
            item.Content = new ContentPresenter();
            (item.Content as ContentPresenter).Content = content.Content;

            //item.PreviewMouseDown += new MouseButtonEventHandler(OnTabItemMouseDown);
            //item.MouseMove += new MouseEventHandler(OnTabItemMouseMove);
            //item.MouseUp += new MouseButtonEventHandler(OnTabItemMouseUp);
            //item.Focusable = true;
            //item.GotFocus += new RoutedEventHandler(item_GotFocus);
            tbcContents.Items.Add(item);
            tbcContents.SelectedItem = item;

            RefreshTitle();
        }

        void item_GotFocus(object sender, RoutedEventArgs e)
        {
            Console.WriteLine("GotFocus");
        }

        protected virtual void RemoveItem(DockableContent content)
        {
            foreach (TabItem item in tbcContents.Items)
                if ((item.Content as ContentPresenter).Content == content.Content)
                {
                    //item.PreviewMouseDown -= new MouseButtonEventHandler(OnTabItemMouseDown);
                    //item.MouseMove -= new MouseEventHandler(OnTabItemMouseMove);
                    //item.MouseUp -= new MouseButtonEventHandler(OnTabItemMouseUp);

                    item.Content = null;
                    tbcContents.Items.Remove(item);
                    //ChangeTitle();
                    break;
                }
        }


        void _tabs_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (tbcContents.SelectedIndex >= 0)
                RefreshTitle();
        }

        #endregion

        //List<EventHandler> _list = new List<EventHandler>();
        
        ///// <summary>
        ///// Event fired when pane internal state is changed
        ///// </summary>
        //public event EventHandler OnStateChanged
        //{
        //    add { _list.Add(value); }
        //    remove { _list.Remove(value); }
        //}

        public EventHandler OnStateChanged;

        /// <summary>
        /// Fires OnStateChanged event
        /// </summary>
        private void FireOnOnStateChanged()
        {
            if (OnStateChanged != null)
                OnStateChanged(this, EventArgs.Empty);
            //foreach (EventHandler eh in _list)
            //    eh(this, EventArgs.Empty);
            
        }
        
        /// <summary>
        /// Change pane internal state
        /// </summary>
        /// <param name="newState">New pane state</param>
        /// <remarks>OnStateChanged event is raised only if newState is different from State.</remarks>
        internal void ChangeState(PaneState newState)
        {
            if (State != newState)
            {
                SaveSize();

                _lastState = _state;
                _state = newState;

                FireOnOnStateChanged();
            }
        }


        /// <summary>
        /// Return true if pane is hidden, ie State is different from PaneState.Docked
        /// </summary>
        public override bool IsHidden
        {
            get
            {
                return State != PaneState.Docked;
            }
        }

        /// <summary>
        /// Internal last pane state
        /// </summary>
        PaneState _lastState = PaneState.Docked;

        /// <summary>
        /// Show this pane and all contained contents
        /// </summary>
        public override void Show()
        {
            foreach (DockableContent content in Contents)
                Show(content);

            if (State == PaneState.AutoHide || State == PaneState.Hidden)
                ChangeState(PaneState.Docked);

            base.Show();
        }

        /// <summary>
        /// Hide this pane and all contained contents
        /// </summary>
        public override void Hide()
        {
            foreach (DockableContent content in Contents)
                RemoveVisibleContent(content);

            ChangeState(PaneState.Hidden);
            base.Hide();
        }

        /// <summary>
        /// Close this pane
        /// </summary>
        /// <remarks>Consider that in this version library this method simply hides the pane.</remarks>
        public override  void Close()
        {
            Hide();

            base.Close();
        }

        /// <summary>
        /// Create and show a floating window hosting this pane
        /// </summary>
        public virtual void FloatingWindow()
        {
            ChangeState(PaneState.FloatingWindow); 
            

            FloatingWindow wnd = new FloatingWindow(this);
            SetFloatingWindowSizeAndPosition(wnd);

            wnd.Owner = DockManager.ParentWindow;
            wnd.Show();
        }

        /// <summary>
        /// Create and show a dockable window hosting this pane
        /// </summary>
        public virtual void DockableWindow()
        {
            FloatingWindow wnd = new FloatingWindow(this);
            SetFloatingWindowSizeAndPosition(wnd);

            ChangeState(PaneState.DockableWindow);

            wnd.Owner = DockManager.ParentWindow;
            wnd.Show();
        }

        /// <summary>
        /// Show contained contents as documents and close this pane
        /// </summary>
        public virtual void TabbedDocument()
        {
            while (Contents.Count > 0)
            {
                DockableContent contentToRemove = Contents[0];
                Remove(contentToRemove);
                DockManager.AddDocument(contentToRemove);
            }

            ChangeState(PaneState.TabbedDocument);
        }

        /// <summary>
        /// Dock this pane to a destination pane border
        /// </summary>
        /// <param name="destinationPane"></param>
        /// <param name="relativeDock"></param>
        internal void MoveTo(Pane destinationPane, Dock relativeDock)
        {
            DockablePane dockableDestPane = destinationPane as DockablePane;
            if (dockableDestPane != null)
                ChangeDock(dockableDestPane.Dock);
            else
                ChangeDock(relativeDock);
            
            
            DockManager.MoveTo(this, destinationPane, relativeDock);
            ChangeState(PaneState.Docked);
            //Show();
            //ChangeState(PaneState.Docked);
        }

        /// <summary>
        /// Move contained contents into a destination pane and close this one
        /// </summary>
        /// <param name="destinationPane"></param>
        internal void MoveInto(Pane destinationPane)
        {
            //DockablePane dockableDestPane = destinationPane as DockablePane;
            //if (dockableDestPane != null)
            //    ChangeDock(dockableDestPane.Dock);

            DockManager.MoveInto(this, destinationPane);

            //if (destinationPane is DocumentsPane)
            //    ChangeState(PaneState.TabbedDocument);
            //else
            //    ChangeState(PaneState.Docked);
        }

        /// <summary>
        /// Event raised when Dock property is changed
        /// </summary>
        public event EventHandler OnDockChanged;

        /// <summary>
        /// Fires OnDockChanged
        /// </summary>
        private void FireOnOnDockChanged()
        {
            if (OnDockChanged != null)
                OnDockChanged(this, EventArgs.Empty);
        }
        
        /// <summary>
        /// Change dock border
        /// </summary>
        /// <param name="dock">New dock border</param>
        public void ChangeDock(Dock dock)
        {
            //if (dock != _dock)
            {
                //SaveSize();

                _dock = dock;

                FireOnOnDockChanged();

                ChangeState(PaneState.Docked);
                //Show();
            }
            
        }

        /// <summary>
        /// Auto-hide this pane 
        /// </summary>
        public void AutoHide()
        {
            foreach (DockableContent content in Contents)
                RemoveVisibleContent(content);

            ChangeState(PaneState.AutoHide);

            DockManager.DragPaneServices.Unregister(this);
        }

        /// <summary>
        /// Handles effective pane resizing 
        /// </summary>
        /// <param name="sizeInfo"></param>
        protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo)
        {
            //SaveSize();
            base.OnRenderSizeChanged(sizeInfo);
        }


        /// <summary>
        /// Save current pane size
        /// </summary>
        public override void SaveSize()
        {
            if (IsHidden)
                return;

            if (Dock == Dock.Left || Dock == Dock.Right)
                PaneWidth = ActualWidth > 150 ? ActualWidth : 150;
            else
                PaneHeight = ActualHeight > 150 ? ActualHeight : 150;

            base.SaveSize();
        }


        Point ptFloatingWindow = new Point(0,0);
        Size sizeFloatingWindow = new Size(300, 300);

        internal void SaveFloatingWindowSizeAndPosition(Window fw)
        {
            if (!double.IsNaN(fw.Left) && !double.IsNaN(fw.Top))
                ptFloatingWindow = new Point(fw.Left, fw.Top);
            
            if (!double.IsNaN(fw.Width) && !double.IsNaN(fw.Height))
                sizeFloatingWindow = new Size(fw.Width, fw.Height);
        }

        internal void SetFloatingWindowSizeAndPosition(FloatingWindow fw)
        {
            fw.Left = ptFloatingWindow.X;
            fw.Top = ptFloatingWindow.Y;
            fw.Width = sizeFloatingWindow.Width;
            fw.Height = sizeFloatingWindow.Height;
        }

        /// <summary>
        /// Get swith options context menu
        /// </summary>
        internal ContextMenu OptionsMenu
        {
            get 
            {
                return btnMenu.ContextMenu;
            }
        }

        /// <summary>
        /// Handles user click on OptionsMenu
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        /// <remarks></remarks>
        protected virtual void OnDockingMenu(object sender, EventArgs e)
        {
            if (sender == menuTabbedDocument)
                TabbedDocument();
            if (sender == menuFloatingWindow)
                FloatingWindow();
            if (sender == menuDockedWindow)
                DockableWindow();


            if (sender == menuAutoHide)
            {
                if (menuAutoHide.IsChecked)
                    ChangeState(PaneState.Docked);
                else
                    AutoHide();
            }
            if (sender == menuClose)
            {
                Close(ActiveContent);
            }
        }
        /// <summary>
        /// Show switch options menu
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void OnBtnMenuMouseDown(object sender, RoutedEventArgs e)
        {
            btnMenu.ContextMenu.IsOpen = true;
            e.Handled = true;
        }

        /// <summary>
        /// Handles user click event on auto-hide button
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void OnBtnAutoHideMouseDown(object sender, RoutedEventArgs e)
        {
            if (State == PaneState.AutoHide)
                ChangeState(PaneState.Docked);
            else
                AutoHide();

            e.Handled = true;
        }

        /// <summary>
        /// Handles user click event on close button
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void OnBtnCloseMouseDown(object sender, RoutedEventArgs e)
        {
            Close(ActiveContent);
            e.Handled = true;
        }
 
        /// <summary>
        /// Enable/disable switch options menu items
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void OnBtnMenuPopup(object sender, DependencyPropertyChangedEventArgs e)
        {
            if (btnMenu.ContextMenu.IsOpen)
            {
                menuFloatingWindow.IsEnabled = _state != PaneState.AutoHide && _state != PaneState.Hidden;
                menuFloatingWindow.IsChecked = _state == PaneState.FloatingWindow;
                menuDockedWindow.IsEnabled = _state != PaneState.AutoHide && _state != PaneState.Hidden;
                menuDockedWindow.IsChecked = _state == PaneState.Docked || _state == PaneState.DockableWindow;
                menuTabbedDocument.IsEnabled = _state != PaneState.AutoHide && _state != PaneState.Hidden;
                menuAutoHide.IsChecked = _state == PaneState.AutoHide;
            }
        }

        /// <summary>
        /// Drag starting point
        /// </summary>
        Point ptStartDrag;

        /// <summary>
        /// Handles mouse douwn event on pane header
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        /// <remarks>Save current mouse position in ptStartDrag and capture mouse event on PaneHeader object.</remarks>
        void OnHeaderMouseDown(object sender, MouseEventArgs e)
        {
            if (DockManager == null)
                return;

            if (!PaneHeader.IsMouseCaptured)
            {
                ptStartDrag = e.GetPosition(this);
                PaneHeader.CaptureMouse();
            }
        }
        /// <summary>
        /// Handles mouse up event on pane header
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        /// <remarks>Release any mouse capture</remarks>
        void OnHeaderMouseUp(object sender, MouseEventArgs e)
        {
            PaneHeader.ReleaseMouseCapture();
        }

        /// <summary>
        /// Handles mouse move event and eventually starts draging this pane
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void OnHeaderMouseMove(object sender, MouseEventArgs e)
        {
            if (PaneHeader.IsMouseCaptured && Math.Abs(ptStartDrag.X - e.GetPosition(this).X) > 4)
            {
                PaneHeader.ReleaseMouseCapture();
                DragPane(DockManager.PointToScreen(e.GetPosition(DockManager)), e.GetPosition(PaneHeader));
            }
        }

        /// <summary>
        /// Initiate a dragging operation of this pane, relative DockManager is also involved
        /// </summary>
        /// <param name="startDragPoint"></param>
        /// <param name="offset"></param>
        protected virtual void DragPane(Point startDragPoint, Point offset)
        {
            FloatingWindow wnd = new FloatingWindow(this);
            SetFloatingWindowSizeAndPosition(wnd);

            ChangeState(PaneState.DockableWindow);
            
            DockManager.Drag(wnd, startDragPoint, offset);        
        }


        /// <summary>
        /// Mouse down event on a content tab item
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void OnTabItemMouseDown(object sender, MouseButtonEventArgs e)
        {
            //TabItem item = sender as TabItem;
            FrameworkElement senderElement = sender as FrameworkElement;
            TabItem item = senderElement.TemplatedParent as TabItem;

            if (!senderElement.IsMouseCaptured)
            {
                ptStartDrag = e.GetPosition(this);
                senderElement.CaptureMouse();
            }

        }

        /// <summary>
        /// Mouse move event on a content tab item
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        /// <remarks>If mouse is moved when left button is pressed than this method starts a dragging content operations. Also in this case relative DockManager is involved.</remarks>
        void OnTabItemMouseMove(object sender, MouseEventArgs e)
        {
            //TabItem item = sender as TabItem;
            FrameworkElement senderElement = sender as FrameworkElement;
            TabItem item = senderElement.TemplatedParent as TabItem;

            if (senderElement.IsMouseCaptured && Math.Abs(ptStartDrag.X - e.GetPosition(this).X) > 4)
            {
                senderElement.ReleaseMouseCapture();
                DockableContent contentToDrag = Contents[tbcContents.Items.IndexOf(item)] as DockableContent;
                if (contentToDrag != null)
                    DragContent(contentToDrag, e.GetPosition(DockManager), e.GetPosition(item));
            }
        }

        /// <summary>
        /// Handles MouseUp event fired from a content tab item and eventually release mouse event capture 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void OnTabItemMouseUp(object sender, MouseButtonEventArgs e)
        {
            //TabItem item = sender as TabItem;
            FrameworkElement senderElement = sender as FrameworkElement;
            TabItem item = senderElement.TemplatedParent as TabItem;

            senderElement.ReleaseMouseCapture();
        }


        #region persistence

        public override void Serialize(XmlDocument doc, XmlNode parentNode)
        {
            SaveSize();

            parentNode.Attributes.Append(doc.CreateAttribute("Dock"));
            parentNode.Attributes["Dock"].Value = _dock.ToString();
            parentNode.Attributes.Append(doc.CreateAttribute("State"));
            parentNode.Attributes["State"].Value = _state.ToString();
            parentNode.Attributes.Append(doc.CreateAttribute("LastState"));
            parentNode.Attributes["LastState"].Value = _lastState.ToString();

            
            parentNode.Attributes.Append(doc.CreateAttribute("ptFloatingWindow"));
            parentNode.Attributes["ptFloatingWindow"].Value = System.ComponentModel.TypeDescriptor.GetConverter(typeof(Point)).ConvertToInvariantString(ptFloatingWindow);
            parentNode.Attributes.Append(doc.CreateAttribute("sizeFloatingWindow"));
            parentNode.Attributes["sizeFloatingWindow"].Value = System.ComponentModel.TypeDescriptor.GetConverter(typeof(Size)).ConvertToInvariantString(sizeFloatingWindow);

            base.Serialize(doc, parentNode);
        }

        public override void Deserialize(DockManager managerToAttach, XmlNode node, GetContentFromTypeString getObjectHandler)
        {
            base.Deserialize(managerToAttach, node, getObjectHandler);

            _dock = (Dock)Enum.Parse(typeof(Dock), node.Attributes["Dock"].Value);
            _state = (PaneState)Enum.Parse(typeof(PaneState), node.Attributes["State"].Value);
            _lastState = (PaneState)Enum.Parse(typeof(PaneState), node.Attributes["LastState"].Value);

            ptFloatingWindow = (Point)System.ComponentModel.TypeDescriptor.GetConverter(typeof(Point)).ConvertFromInvariantString(node.Attributes["ptFloatingWindow"].Value);
            sizeFloatingWindow = (Size)System.ComponentModel.TypeDescriptor.GetConverter(typeof(Size)).ConvertFromInvariantString(node.Attributes["sizeFloatingWindow"].Value);

            

            if (State == PaneState.FloatingWindow)
                FloatingWindow();
            else if (State == PaneState.DockableWindow)
                DockableWindow();

            DockManager.AttachPaneEvents(this);
        }

        #endregion
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Systems Engineer
Italy Italy
I bought my first computer in Nov 1991, 21st and I started programming with QBasic under MSDOS.
Today my main interest is developping applications with .NET and HTML5 stack.

Comments and Discussions