| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642 |
- /*************************************************************************************
- Extended WPF Toolkit
- Copyright (C) 2007-2013 Xceed Software Inc.
- This program is provided to you under the terms of the Microsoft Public
- License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license
- For more features, controls, and fast professional support,
- pick up the Plus Edition at http://xceed.com/wpf_toolkit
- Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids
- ***********************************************************************************/
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Windows;
- using System.Xml.Serialization;
- using System.Windows.Controls;
- using System.Globalization;
- using System.ComponentModel;
- namespace Xceed.Wpf.AvalonDock.Layout
- {
- [Serializable]
- public class LayoutAnchorable : LayoutContent
- {
- #region IsVisible
- [XmlIgnore]
- public bool IsVisible
- {
- get
- {
- return Parent != null && !(Parent is LayoutRoot);
- }
- set
- {
- if (value)
- {
- Show();
- }
- else
- {
- Hide();
- }
- }
- }
- public event EventHandler IsVisibleChanged;
- void NotifyIsVisibleChanged()
- {
- if (IsVisibleChanged != null)
- IsVisibleChanged(this, EventArgs.Empty);
- }
- [XmlIgnore]
- public bool IsHidden
- {
- get
- {
- return (Parent is LayoutRoot);
- }
- }
- protected override void OnParentChanged(ILayoutContainer oldValue, ILayoutContainer newValue)
- {
- UpdateParentVisibility();
- RaisePropertyChanged("IsVisible");
- NotifyIsVisibleChanged();
- RaisePropertyChanged("IsHidden");
- RaisePropertyChanged("IsAutoHidden");
- base.OnParentChanged(oldValue, newValue);
- }
- void UpdateParentVisibility()
- {
- var parentPane = Parent as ILayoutElementWithVisibility;
- if (parentPane != null)
- parentPane.ComputeVisibility();
- }
- #endregion
- #region AutoHideWidth
- private double _autohideWidth = 0.0;
- public double AutoHideWidth
- {
- get { return _autohideWidth; }
- set
- {
- if (_autohideWidth != value)
- {
- RaisePropertyChanging("AutoHideWidth");
- value = Math.Max(value, _autohideMinWidth);
- _autohideWidth = value;
- RaisePropertyChanged("AutoHideWidth");
- }
- }
- }
- #endregion
- #region AutoHideMinWidth
- private double _autohideMinWidth = 100.0;
- public double AutoHideMinWidth
- {
- get { return _autohideMinWidth; }
- set
- {
- if (_autohideMinWidth != value)
- {
- RaisePropertyChanging("AutoHideMinWidth");
- if (value < 0)
- throw new ArgumentException("value");
- _autohideMinWidth = value;
- RaisePropertyChanged("AutoHideMinWidth");
- }
- }
- }
- #endregion
- #region AutoHideHeight
- private double _autohideHeight = 0.0;
- public double AutoHideHeight
- {
- get { return _autohideHeight; }
- set
- {
- if (_autohideHeight != value)
- {
- RaisePropertyChanging("AutoHideHeight");
- value = Math.Max(value, _autohideMinHeight);
- _autohideHeight = value;
- RaisePropertyChanged("AutoHideHeight");
- }
- }
- }
- #endregion
- #region AutoHideMinHeight
- private double _autohideMinHeight = 100.0;
- public double AutoHideMinHeight
- {
- get { return _autohideMinHeight; }
- set
- {
- if (_autohideMinHeight != value)
- {
- RaisePropertyChanging("AutoHideMinHeight");
- if (value < 0)
- throw new ArgumentException("value");
- _autohideMinHeight = value;
- RaisePropertyChanged("AutoHideMinHeight");
- }
- }
- }
- #endregion
- /// <summary>
- /// Hide this contents
- /// </summary>
- /// <remarks>Add this content to <see cref="ILayoutRoot.Hidden"/> collection of parent root.</remarks>
- public void Hide(bool cancelable = true)
- {
- if (!IsVisible)
- {
- IsSelected = true;
- IsActive = true;
- return;
- }
- if (cancelable)
- {
- CancelEventArgs args = new CancelEventArgs();
- OnHiding(args);
- if (args.Cancel)
- return;
- }
- RaisePropertyChanging("IsHidden");
- RaisePropertyChanging("IsVisible");
- //if (Parent is ILayoutPane)
- {
- var parentAsGroup = Parent as ILayoutGroup;
- PreviousContainer = parentAsGroup;
- PreviousContainerIndex = parentAsGroup.IndexOfChild(this);
- }
- Root.Hidden.Add(this);
- RaisePropertyChanged("IsVisible");
- RaisePropertyChanged("IsHidden");
- NotifyIsVisibleChanged();
- }
- public event EventHandler<CancelEventArgs> Hiding;
- protected virtual void OnHiding(CancelEventArgs args)
- {
- if (Hiding != null)
- Hiding(this, args);
- }
- /// <summary>
- /// Show the content
- /// </summary>
- /// <remarks>Try to show the content where it was previously hidden.</remarks>
- public void Show()
- {
- if (IsVisible)
- return;
- if (!IsHidden)
- throw new InvalidOperationException();
- RaisePropertyChanging("IsHidden");
- RaisePropertyChanging("IsVisible");
- bool added = false;
- var root = Root;
- if (root != null && root.Manager != null)
- {
- if (root.Manager.LayoutUpdateStrategy != null)
- added = root.Manager.LayoutUpdateStrategy.BeforeInsertAnchorable(root as LayoutRoot, this, PreviousContainer);
- }
- if (!added && PreviousContainer != null)
- {
- var previousContainerAsLayoutGroup = PreviousContainer as ILayoutGroup;
- if (PreviousContainerIndex < previousContainerAsLayoutGroup.ChildrenCount)
- previousContainerAsLayoutGroup.InsertChildAt(PreviousContainerIndex, this);
- else
- previousContainerAsLayoutGroup.InsertChildAt(previousContainerAsLayoutGroup.ChildrenCount, this);
- IsSelected = true;
- IsActive = true;
- }
- if (root != null && root.Manager != null)
- {
- if (root.Manager.LayoutUpdateStrategy != null)
- {
- root.Manager.LayoutUpdateStrategy.AfterInsertAnchorable(root as LayoutRoot, this);
- }
- }
- PreviousContainer = null;
- PreviousContainerIndex = -1;
- RaisePropertyChanged("IsVisible");
- RaisePropertyChanged("IsHidden");
- NotifyIsVisibleChanged();
- }
- protected override void InternalDock()
- {
- var root = Root as LayoutRoot;
- LayoutAnchorablePane anchorablePane = null;
- if (root.ActiveContent != null &&
- root.ActiveContent != this)
- {
- //look for active content parent pane
- anchorablePane = root.ActiveContent.Parent as LayoutAnchorablePane;
- }
- if (anchorablePane == null)
- {
- //look for a pane on the right side
- anchorablePane = root.Descendents().OfType<LayoutAnchorablePane>().Where(pane => !pane.IsHostedInFloatingWindow && pane.GetSide() == AnchorSide.Right).FirstOrDefault();
- }
- if (anchorablePane == null)
- {
- //look for an available pane
- anchorablePane = root.Descendents().OfType<LayoutAnchorablePane>().FirstOrDefault();
- }
- bool added = false;
- if (root.Manager.LayoutUpdateStrategy != null)
- {
- added = root.Manager.LayoutUpdateStrategy.BeforeInsertAnchorable(root, this, anchorablePane);
- }
- if (!added)
- {
- if (anchorablePane == null)
- {
- var mainLayoutPanel = new LayoutPanel() { Orientation = Orientation.Horizontal };
- if (root.RootPanel != null)
- {
- mainLayoutPanel.Children.Add(root.RootPanel);
- }
- root.RootPanel = mainLayoutPanel;
- anchorablePane = new LayoutAnchorablePane() { DockWidth = new GridLength(200.0, GridUnitType.Pixel) };
- mainLayoutPanel.Children.Add(anchorablePane);
- }
- anchorablePane.Children.Add(this);
- added = true;
- }
- if (root.Manager.LayoutUpdateStrategy != null)
- {
- root.Manager.LayoutUpdateStrategy.AfterInsertAnchorable(root, this);
- }
- base.InternalDock();
- }
- /// <summary>
- /// Add the anchorable to a DockingManager layout
- /// </summary>
- /// <param name="manager"></param>
- /// <param name="strategy"></param>
- public void AddToLayout(DockingManager manager, AnchorableShowStrategy strategy)
- {
- if (IsVisible ||
- IsHidden)
- throw new InvalidOperationException();
- bool most = (strategy & AnchorableShowStrategy.Most) == AnchorableShowStrategy.Most;
- bool left = (strategy & AnchorableShowStrategy.Left) == AnchorableShowStrategy.Left;
- bool right = (strategy & AnchorableShowStrategy.Right) == AnchorableShowStrategy.Right;
- bool top = (strategy & AnchorableShowStrategy.Top) == AnchorableShowStrategy.Top;
- bool bottom = (strategy & AnchorableShowStrategy.Bottom) == AnchorableShowStrategy.Bottom;
- if (!most)
- {
- var side = AnchorSide.Left;
- if (left)
- side = AnchorSide.Left;
- if (right)
- side = AnchorSide.Right;
- if (top)
- side = AnchorSide.Top;
- if (bottom)
- side = AnchorSide.Bottom;
- var anchorablePane = manager.Layout.Descendents().OfType<LayoutAnchorablePane>().FirstOrDefault(p => p.GetSide() == side);
- if (anchorablePane != null)
- anchorablePane.Children.Add(this);
- else
- most = true;
- }
- if (most)
- {
- if (manager.Layout.RootPanel == null)
- manager.Layout.RootPanel = new LayoutPanel() { Orientation = (left || right ? Orientation.Horizontal : Orientation.Vertical) };
- if (left || right)
- {
- if (manager.Layout.RootPanel.Orientation == Orientation.Vertical &&
- manager.Layout.RootPanel.ChildrenCount > 1)
- {
- manager.Layout.RootPanel = new LayoutPanel(manager.Layout.RootPanel);
- }
- manager.Layout.RootPanel.Orientation = Orientation.Horizontal;
- if (left)
- manager.Layout.RootPanel.Children.Insert(0, new LayoutAnchorablePane(this));
- else
- manager.Layout.RootPanel.Children.Add(new LayoutAnchorablePane(this));
- }
- else
- {
- if (manager.Layout.RootPanel.Orientation == Orientation.Horizontal &&
- manager.Layout.RootPanel.ChildrenCount > 1)
- {
- manager.Layout.RootPanel = new LayoutPanel(manager.Layout.RootPanel);
- }
- manager.Layout.RootPanel.Orientation = Orientation.Vertical;
- if (top)
- manager.Layout.RootPanel.Children.Insert(0, new LayoutAnchorablePane(this));
- else
- manager.Layout.RootPanel.Children.Add(new LayoutAnchorablePane(this));
- }
- }
- }
- /// <summary>
- /// Get a value indicating if the anchorable is anchored to a border in an autohide status
- /// </summary>
- public bool IsAutoHidden
- {
- get { return Parent != null && Parent is LayoutAnchorGroup; }
- }
- #region AutoHide
- public void ToggleAutoHide()
- {
- #region Anchorable is already auto hidden
- if (IsAutoHidden)
- {
- var parentGroup = Parent as LayoutAnchorGroup;
- var parentSide = parentGroup.Parent as LayoutAnchorSide;
- var previousContainer = ((ILayoutPreviousContainer)parentGroup).PreviousContainer as LayoutAnchorablePane;
- if (previousContainer == null)
- {
- AnchorSide side = (parentGroup.Parent as LayoutAnchorSide).Side;
- switch (side)
- {
- case AnchorSide.Right:
- if (parentGroup.Root.RootPanel.Orientation == Orientation.Horizontal)
- {
- previousContainer = new LayoutAnchorablePane();
- parentGroup.Root.RootPanel.Children.Add(previousContainer);
- }
- else
- {
- previousContainer = new LayoutAnchorablePane();
- LayoutPanel panel = new LayoutPanel() { Orientation = Orientation.Horizontal };
- LayoutRoot root = parentGroup.Root as LayoutRoot;
- LayoutPanel oldRootPanel = parentGroup.Root.RootPanel as LayoutPanel;
- root.RootPanel = panel;
- panel.Children.Add(oldRootPanel);
- panel.Children.Add(previousContainer);
- }
- break;
- case AnchorSide.Left:
- if (parentGroup.Root.RootPanel.Orientation == Orientation.Horizontal)
- {
- previousContainer = new LayoutAnchorablePane();
- parentGroup.Root.RootPanel.Children.Insert(0, previousContainer);
- }
- else
- {
- previousContainer = new LayoutAnchorablePane();
- LayoutPanel panel = new LayoutPanel() { Orientation = Orientation.Horizontal };
- LayoutRoot root = parentGroup.Root as LayoutRoot;
- LayoutPanel oldRootPanel = parentGroup.Root.RootPanel as LayoutPanel;
- root.RootPanel = panel;
- panel.Children.Add(previousContainer);
- panel.Children.Add(oldRootPanel);
- }
- break;
- case AnchorSide.Top:
- if (parentGroup.Root.RootPanel.Orientation == Orientation.Vertical)
- {
- previousContainer = new LayoutAnchorablePane();
- parentGroup.Root.RootPanel.Children.Insert(0, previousContainer);
- }
- else
- {
- previousContainer = new LayoutAnchorablePane();
- LayoutPanel panel = new LayoutPanel() { Orientation = Orientation.Vertical };
- LayoutRoot root = parentGroup.Root as LayoutRoot;
- LayoutPanel oldRootPanel = parentGroup.Root.RootPanel as LayoutPanel;
- root.RootPanel = panel;
- panel.Children.Add(previousContainer);
- panel.Children.Add(oldRootPanel);
- }
- break;
- case AnchorSide.Bottom:
- if (parentGroup.Root.RootPanel.Orientation == Orientation.Vertical)
- {
- previousContainer = new LayoutAnchorablePane();
- parentGroup.Root.RootPanel.Children.Add(previousContainer);
- }
- else
- {
- previousContainer = new LayoutAnchorablePane();
- LayoutPanel panel = new LayoutPanel() { Orientation = Orientation.Vertical };
- LayoutRoot root = parentGroup.Root as LayoutRoot;
- LayoutPanel oldRootPanel = parentGroup.Root.RootPanel as LayoutPanel;
- root.RootPanel = panel;
- panel.Children.Add(oldRootPanel);
- panel.Children.Add(previousContainer);
- }
- break;
- }
- }
- else
- {
- //I'm about to remove parentGroup, redirect any content (ie hidden contents) that point to it
- //to previousContainer
- LayoutRoot root = parentGroup.Root as LayoutRoot;
- foreach (var cnt in root.Descendents().OfType<ILayoutPreviousContainer>().Where(c => c.PreviousContainer == parentGroup))
- {
- cnt.PreviousContainer = previousContainer;
- }
- }
- foreach (var anchorableToToggle in parentGroup.Children.ToArray())
- {
- previousContainer.Children.Add(anchorableToToggle);
- }
- parentSide.Children.Remove(parentGroup);
- }
- #endregion
- #region Anchorable is docked
- else if (Parent is LayoutAnchorablePane)
- {
- var root = Root;
- var parentPane = Parent as LayoutAnchorablePane;
- var newAnchorGroup = new LayoutAnchorGroup();
- ((ILayoutPreviousContainer)newAnchorGroup).PreviousContainer = parentPane;
- foreach (var anchorableToImport in parentPane.Children.ToArray())
- newAnchorGroup.Children.Add(anchorableToImport);
- //detect anchor side for the pane
- var anchorSide = parentPane.GetSide();
- switch (anchorSide)
- {
- case AnchorSide.Right:
- root.RightSide.Children.Add(newAnchorGroup);
- break;
- case AnchorSide.Left:
- root.LeftSide.Children.Add(newAnchorGroup);
- break;
- case AnchorSide.Top:
- root.TopSide.Children.Add(newAnchorGroup);
- break;
- case AnchorSide.Bottom:
- root.BottomSide.Children.Add(newAnchorGroup);
- break;
- }
- }
- #endregion
- }
- #endregion
- #region CanHide
- private bool _canHide = true;
- public bool CanHide
- {
- get { return _canHide; }
- set
- {
- if (_canHide != value)
- {
- _canHide = value;
- RaisePropertyChanged("CanHide");
- }
- }
- }
- #endregion
- #region CanAutoHide
- private bool _canAutoHide = true;
- public bool CanAutoHide
- {
- get { return _canAutoHide; }
- set
- {
- if (_canAutoHide != value)
- {
- _canAutoHide = value;
- RaisePropertyChanged("CanAutoHide");
- }
- }
- }
- #endregion
- public override void ReadXml(System.Xml.XmlReader reader)
- {
- if (reader.MoveToAttribute("CanHide"))
- CanHide = bool.Parse(reader.Value);
- if (reader.MoveToAttribute("CanAutoHide"))
- CanAutoHide = bool.Parse(reader.Value);
- if (reader.MoveToAttribute("AutoHideWidth"))
- AutoHideWidth = double.Parse(reader.Value, CultureInfo.InvariantCulture);
- if (reader.MoveToAttribute("AutoHideHeight"))
- AutoHideHeight = double.Parse(reader.Value, CultureInfo.InvariantCulture);
- if (reader.MoveToAttribute("AutoHideMinWidth"))
- AutoHideMinWidth = double.Parse(reader.Value, CultureInfo.InvariantCulture);
- if (reader.MoveToAttribute("AutoHideMinHeight"))
- AutoHideMinHeight = double.Parse(reader.Value, CultureInfo.InvariantCulture);
- base.ReadXml(reader);
- }
- public override void WriteXml(System.Xml.XmlWriter writer)
- {
- if (!CanHide)
- writer.WriteAttributeString("CanHide", CanHide.ToString());
- if (!CanAutoHide)
- writer.WriteAttributeString("CanAutoHide", CanAutoHide.ToString(CultureInfo.InvariantCulture));
- if (AutoHideWidth > 0)
- writer.WriteAttributeString("AutoHideWidth", AutoHideWidth.ToString(CultureInfo.InvariantCulture));
- if (AutoHideHeight > 0)
- writer.WriteAttributeString("AutoHideHeight", AutoHideHeight.ToString(CultureInfo.InvariantCulture));
- if (AutoHideMinWidth != 25.0)
- writer.WriteAttributeString("AutoHideMinWidth", AutoHideMinWidth.ToString(CultureInfo.InvariantCulture));
- if (AutoHideMinHeight != 25.0)
- writer.WriteAttributeString("AutoHideMinHeight", AutoHideMinHeight.ToString(CultureInfo.InvariantCulture));
- base.WriteXml(writer);
- }
- public override void Close()
- {
- var dockingManager = this.Root.Manager;
- if( ( this.Root != null ) && ( this.Root.Manager != null ) )
- dockingManager._ExecuteCloseCommand( this );
- }
- #if TRACE
- public override void ConsoleDump(int tab)
- {
- System.Diagnostics.Trace.Write( new string( ' ', tab * 4 ) );
- System.Diagnostics.Trace.WriteLine( "Anchorable()" );
- }
- #endif
- }
- }
|