/*************************************************************************************
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;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Markup;
using System.Windows.Threading;
using Xceed.Wpf.AvalonDock.Controls;
using Xceed.Wpf.AvalonDock.Layout;
using Xceed.Wpf.AvalonDock.Themes;
namespace Xceed.Wpf.AvalonDock
{
[ContentProperty("Layout")]
[TemplatePart(Name = "PART_AutoHideArea")]
public class DockingManager : Control, IOverlayWindowHost//, ILogicalChildrenContainer
{
private ResourceDictionary currentThemeResourceDictionary; // = null
static DockingManager()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(DockingManager), new FrameworkPropertyMetadata(typeof(DockingManager)));
FocusableProperty.OverrideMetadata(typeof(DockingManager), new FrameworkPropertyMetadata(false));
HwndSource.DefaultAcquireHwndFocusInMenuMode = false;
}
public DockingManager()
{
Layout = new LayoutRoot() { RootPanel = new LayoutPanel(new LayoutDocumentPaneGroup(new LayoutDocumentPane())) };
this.Loaded += new RoutedEventHandler(DockingManager_Loaded);
this.Unloaded += new RoutedEventHandler(DockingManager_Unloaded);
}
#region Layout
///
/// Layout Dependency Property
///
public static readonly DependencyProperty LayoutProperty =
DependencyProperty.Register("Layout", typeof(LayoutRoot), typeof(DockingManager),
new FrameworkPropertyMetadata(null,
new PropertyChangedCallback(OnLayoutChanged),
new CoerceValueCallback(CoerceLayoutValue)));
///
/// Gets or sets the Layout property. This dependency property
/// indicates layout tree.
///
public LayoutRoot Layout
{
get { return (LayoutRoot)GetValue(LayoutProperty); }
set { SetValue(LayoutProperty, value); }
}
///
/// Handles changes to the Layout property.
///
private static void OnLayoutChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((DockingManager)d).OnLayoutChanged(e.OldValue as LayoutRoot, e.NewValue as LayoutRoot);
}
///
/// Provides derived classes an opportunity to handle changes to the property.
///
protected virtual void OnLayoutChanged(LayoutRoot oldLayout, LayoutRoot newLayout)
{
if (oldLayout != null)
{
oldLayout.PropertyChanged -= new PropertyChangedEventHandler(OnLayoutRootPropertyChanged);
oldLayout.Updated -= new EventHandler(OnLayoutRootUpdated);
}
foreach (var fwc in _fwList.ToArray())
{
fwc.KeepContentVisibleOnClose = true;
fwc.InternalClose();
}
_fwList.Clear();
DetachDocumentsSource(oldLayout, DocumentsSource);
DetachAnchorablesSource(oldLayout, AnchorablesSource);
if (oldLayout != null &&
oldLayout.Manager == this)
oldLayout.Manager = null;
ClearLogicalChildrenList();
DetachLayoutItems();
Layout.Manager = this;
AttachLayoutItems();
AttachDocumentsSource(newLayout, DocumentsSource);
AttachAnchorablesSource(newLayout, AnchorablesSource);
if (IsLoaded)
{
LayoutRootPanel = CreateUIElementForModel(Layout.RootPanel) as LayoutPanelControl;
LeftSidePanel = CreateUIElementForModel(Layout.LeftSide) as LayoutAnchorSideControl;
TopSidePanel = CreateUIElementForModel(Layout.TopSide) as LayoutAnchorSideControl;
RightSidePanel = CreateUIElementForModel(Layout.RightSide) as LayoutAnchorSideControl;
BottomSidePanel = CreateUIElementForModel(Layout.BottomSide) as LayoutAnchorSideControl;
foreach (var fw in Layout.FloatingWindows.ToArray())
{
if (fw.IsValid)
_fwList.Add(CreateUIElementForModel(fw) as LayoutFloatingWindowControl);
}
foreach (var fw in _fwList)
{
//fw.Owner = Window.GetWindow(this);
//fw.SetParentToMainWindowOf(this);
}
}
if (newLayout != null)
{
newLayout.PropertyChanged += new PropertyChangedEventHandler(OnLayoutRootPropertyChanged);
newLayout.Updated += new EventHandler(OnLayoutRootUpdated);
}
if (LayoutChanged != null)
LayoutChanged(this, EventArgs.Empty);
//if (Layout != null)
// Layout.CollectGarbage();
CommandManager.InvalidateRequerySuggested();
}
DispatcherOperation _setFocusAsyncOperation = null;
void OnLayoutRootPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "RootPanel")
{
if (IsInitialized)
{
var layoutRootPanel = CreateUIElementForModel(Layout.RootPanel) as LayoutPanelControl;
LayoutRootPanel = layoutRootPanel;
}
}
else if (e.PropertyName == "ActiveContent")
{
if (Layout.ActiveContent != null)
{
//Debug.WriteLine(new StackTrace().ToString());
//set focus on active element only after a layout pass is completed
//it's possible that it is not yet visible in the visual tree
if (_setFocusAsyncOperation == null)
{
_setFocusAsyncOperation = Dispatcher.BeginInvoke(new Action(() =>
{
if (Layout.ActiveContent != null)
FocusElementManager.SetFocusOnLastElement(Layout.ActiveContent);
_setFocusAsyncOperation = null;
}), DispatcherPriority.Background);
}
}
if (!_insideInternalSetActiveContent)
ActiveContent = Layout.ActiveContent != null ?
Layout.ActiveContent.Content : null;
}
}
void OnLayoutRootUpdated(object sender, EventArgs e)
{
CommandManager.InvalidateRequerySuggested();
}
///
/// Event fired when property changes
///
public event EventHandler LayoutChanged;
///
/// Coerces the value.
///
private static object CoerceLayoutValue(DependencyObject d, object value)
{
if (value == null)
return new LayoutRoot() { RootPanel = new LayoutPanel(new LayoutDocumentPaneGroup(new LayoutDocumentPane())) };
((DockingManager)d).OnLayoutChanging(value as LayoutRoot);
return value;
}
///
/// Event fired when property is about to be changed
///
public event EventHandler LayoutChanging;
void OnLayoutChanging(LayoutRoot newLayout)
{
if (LayoutChanging != null)
LayoutChanging(this, EventArgs.Empty);
}
#region LayoutUpdateStrategy
///
/// LayoutUpdateStrategy Dependency Property
///
public static readonly DependencyProperty LayoutUpdateStrategyProperty =
DependencyProperty.Register("LayoutUpdateStrategy", typeof(ILayoutUpdateStrategy), typeof(DockingManager),
new FrameworkPropertyMetadata((ILayoutUpdateStrategy)null));
///
/// Gets or sets the LayoutUpdateStrategy property. This dependency property
/// indicates the strategy class to call when AvalonDock needs to positionate a LayoutAnchorable inside an existing layout.
///
/// Sometimes it's impossible to automatically insert an anchorable in the layout without specifing the target parent pane.
/// Set this property to an object that will be asked to insert the anchorable to the desidered position.
public ILayoutUpdateStrategy LayoutUpdateStrategy
{
get { return (ILayoutUpdateStrategy)GetValue(LayoutUpdateStrategyProperty); }
set { SetValue(LayoutUpdateStrategyProperty, value); }
}
#endregion
#endregion
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
SetupAutoHideWindow();
}
protected override void OnInitialized(EventArgs e)
{
base.OnInitialized(e);
}
void DockingManager_Loaded(object sender, RoutedEventArgs e)
{
if (!DesignerProperties.GetIsInDesignMode(this))
{
if (Layout.Manager == this)
{
LayoutRootPanel = CreateUIElementForModel(Layout.RootPanel) as LayoutPanelControl;
LeftSidePanel = CreateUIElementForModel(Layout.LeftSide) as LayoutAnchorSideControl;
TopSidePanel = CreateUIElementForModel(Layout.TopSide) as LayoutAnchorSideControl;
RightSidePanel = CreateUIElementForModel(Layout.RightSide) as LayoutAnchorSideControl;
BottomSidePanel = CreateUIElementForModel(Layout.BottomSide) as LayoutAnchorSideControl;
}
//load windows not already loaded!
foreach (var fw in Layout.FloatingWindows.Where(fw => !_fwList.Any(fwc => fwc.Model == fw)))
_fwList.Add(CreateUIElementForModel(fw) as LayoutFloatingWindowControl);
//create the overlaywindow if it's possible
if (IsVisible)
CreateOverlayWindow();
FocusElementManager.SetupFocusManagement(this);
}
}
void DockingManager_Unloaded(object sender, RoutedEventArgs e)
{
if (!DesignerProperties.GetIsInDesignMode(this))
{
if (_autoHideWindowManager != null)
{
_autoHideWindowManager.HideAutoWindow();
}
foreach (var fw in _fwList.ToArray())
{
//fw.Owner = null;
fw.SetParentWindowToNull();
fw.KeepContentVisibleOnClose = true;
fw.Close();
}
DestroyOverlayWindow();
FocusElementManager.FinalizeFocusManagement(this);
}
}
internal UIElement CreateUIElementForModel(ILayoutElement model)
{
if (model is LayoutPanel)
return new LayoutPanelControl(model as LayoutPanel);
if (model is LayoutAnchorablePaneGroup)
return new LayoutAnchorablePaneGroupControl(model as LayoutAnchorablePaneGroup);
if (model is LayoutDocumentPaneGroup)
return new LayoutDocumentPaneGroupControl(model as LayoutDocumentPaneGroup);
if (model is LayoutAnchorSide)
{
var templateModelView = new LayoutAnchorSideControl(model as LayoutAnchorSide);
templateModelView.SetBinding(LayoutAnchorSideControl.TemplateProperty, new Binding("AnchorSideTemplate") { Source = this });
return templateModelView;
}
if (model is LayoutAnchorGroup)
{
var templateModelView = new LayoutAnchorGroupControl(model as LayoutAnchorGroup);
templateModelView.SetBinding(LayoutAnchorGroupControl.TemplateProperty, new Binding("AnchorGroupTemplate") { Source = this });
return templateModelView;
}
if (model is LayoutDocumentPane)
{
var templateModelView = new LayoutDocumentPaneControl(model as LayoutDocumentPane);
templateModelView.SetBinding(LayoutDocumentPaneControl.StyleProperty, new Binding("DocumentPaneControlStyle") { Source = this });
return templateModelView;
}
if (model is LayoutAnchorablePane)
{
var templateModelView = new LayoutAnchorablePaneControl(model as LayoutAnchorablePane);
templateModelView.SetBinding(LayoutAnchorablePaneControl.StyleProperty, new Binding("AnchorablePaneControlStyle") { Source = this });
return templateModelView;
}
if (model is LayoutAnchorableFloatingWindow)
{
if (DesignerProperties.GetIsInDesignMode(this))
return null;
var modelFW = model as LayoutAnchorableFloatingWindow;
var newFW = new LayoutAnchorableFloatingWindowControl(modelFW)
{
//Owner = Window.GetWindow(this)
};
newFW.SetParentToMainWindowOf(this);
var paneForExtensions = modelFW.RootPanel.Children.OfType().FirstOrDefault();
if (paneForExtensions != null)
{
//ensure that floating window position is inside current (or nearest) monitor
paneForExtensions.KeepInsideNearestMonitor();
newFW.Left = paneForExtensions.FloatingLeft;
newFW.Top = paneForExtensions.FloatingTop;
newFW.Width = paneForExtensions.FloatingWidth;
newFW.Height = paneForExtensions.FloatingHeight;
}
newFW.ShowInTaskbar = false;
newFW.Show();
// Do not set the WindowState before showing or it will be lost
if (paneForExtensions != null && paneForExtensions.IsMaximized)
{
newFW.WindowState = WindowState.Maximized;
}
return newFW;
}
if (model is LayoutDocumentFloatingWindow)
{
if (DesignerProperties.GetIsInDesignMode(this))
return null;
var modelFW = model as LayoutDocumentFloatingWindow;
var newFW = new LayoutDocumentFloatingWindowControl(modelFW)
{
//Owner = Window.GetWindow(this)
};
newFW.SetParentToMainWindowOf(this);
var paneForExtensions = modelFW.RootDocument;
if (paneForExtensions != null)
{
//ensure that floating window position is inside current (or nearest) monitor
paneForExtensions.KeepInsideNearestMonitor();
newFW.Left = paneForExtensions.FloatingLeft;
newFW.Top = paneForExtensions.FloatingTop;
newFW.Width = paneForExtensions.FloatingWidth;
newFW.Height = paneForExtensions.FloatingHeight;
}
newFW.ShowInTaskbar = false;
newFW.Show();
// Do not set the WindowState before showing or it will be lost
if (paneForExtensions != null && paneForExtensions.IsMaximized)
{
newFW.WindowState = WindowState.Maximized;
}
return newFW;
}
if (model is LayoutDocument)
{
var templateModelView = new LayoutDocumentControl() { Model = model as LayoutDocument };
return templateModelView;
}
return null;
}
#region DocumentPaneTemplate
///
/// DocumentPaneTemplate Dependency Property
///
public static readonly DependencyProperty DocumentPaneTemplateProperty =
DependencyProperty.Register("DocumentPaneTemplate", typeof(ControlTemplate), typeof(DockingManager),
new FrameworkPropertyMetadata((ControlTemplate)null,
new PropertyChangedCallback(OnDocumentPaneTemplateChanged)));
///
/// Gets or sets the DocumentPaneDataTemplate property. This dependency property
/// indicates .
///
public ControlTemplate DocumentPaneTemplate
{
get { return (ControlTemplate)GetValue(DocumentPaneTemplateProperty); }
set { SetValue(DocumentPaneTemplateProperty, value); }
}
///
/// Handles changes to the DocumentPaneTemplate property.
///
private static void OnDocumentPaneTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((DockingManager)d).OnDocumentPaneTemplateChanged(e);
}
///
/// Provides derived classes an opportunity to handle changes to the DocumentPaneTemplate property.
///
protected virtual void OnDocumentPaneTemplateChanged(DependencyPropertyChangedEventArgs e)
{
}
#endregion
#region AnchorablePaneTemplate
///
/// AnchorablePaneTemplate Dependency Property
///
public static readonly DependencyProperty AnchorablePaneTemplateProperty =
DependencyProperty.Register("AnchorablePaneTemplate", typeof(ControlTemplate), typeof(DockingManager),
new FrameworkPropertyMetadata((ControlTemplate)null,
new PropertyChangedCallback(OnAnchorablePaneTemplateChanged)));
///
/// Gets or sets the AnchorablePaneTemplate property. This dependency property
/// indicates ....
///
public ControlTemplate AnchorablePaneTemplate
{
get { return (ControlTemplate)GetValue(AnchorablePaneTemplateProperty); }
set { SetValue(AnchorablePaneTemplateProperty, value); }
}
///
/// Handles changes to the AnchorablePaneDataTemplate property.
///
private static void OnAnchorablePaneTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((DockingManager)d).OnAnchorablePaneTemplateChanged(e);
}
///
/// Provides derived classes an opportunity to handle changes to the AnchorablePaneDataTemplate property.
///
protected virtual void OnAnchorablePaneTemplateChanged(DependencyPropertyChangedEventArgs e)
{
}
#endregion
#region AnchorSideTemplate
///
/// AnchorSideTemplate Dependency Property
///
public static readonly DependencyProperty AnchorSideTemplateProperty =
DependencyProperty.Register("AnchorSideTemplate", typeof(ControlTemplate), typeof(DockingManager),
new FrameworkPropertyMetadata((ControlTemplate)null));
///
/// Gets or sets the AnchorSideTemplate property. This dependency property
/// indicates ....
///
public ControlTemplate AnchorSideTemplate
{
get { return (ControlTemplate)GetValue(AnchorSideTemplateProperty); }
set { SetValue(AnchorSideTemplateProperty, value); }
}
#endregion
#region AnchorGroupTemplate
///
/// AnchorGroupTemplate Dependency Property
///
public static readonly DependencyProperty AnchorGroupTemplateProperty =
DependencyProperty.Register("AnchorGroupTemplate", typeof(ControlTemplate), typeof(DockingManager),
new FrameworkPropertyMetadata((ControlTemplate)null));
///
/// Gets or sets the AnchorGroupTemplate property. This dependency property
/// indicates the template used to render the AnchorGroup control.
///
public ControlTemplate AnchorGroupTemplate
{
get { return (ControlTemplate)GetValue(AnchorGroupTemplateProperty); }
set { SetValue(AnchorGroupTemplateProperty, value); }
}
#endregion
#region AnchorTemplate
///
/// AnchorTemplate Dependency Property
///
public static readonly DependencyProperty AnchorTemplateProperty =
DependencyProperty.Register("AnchorTemplate", typeof(ControlTemplate), typeof(DockingManager),
new FrameworkPropertyMetadata((ControlTemplate)null));
///
/// Gets or sets the AnchorTemplate property. This dependency property
/// indicates ....
///
public ControlTemplate AnchorTemplate
{
get { return (ControlTemplate)GetValue(AnchorTemplateProperty); }
set { SetValue(AnchorTemplateProperty, value); }
}
#endregion
#region DocumentPaneControlStyle
///
/// DocumentPaneControlStyle Dependency Property
///
public static readonly DependencyProperty DocumentPaneControlStyleProperty =
DependencyProperty.Register("DocumentPaneControlStyle", typeof(Style), typeof(DockingManager),
new FrameworkPropertyMetadata((Style)null,
new PropertyChangedCallback(OnDocumentPaneControlStyleChanged)));
///
/// Gets or sets the DocumentPaneControlStyle property. This dependency property
/// indicates ....
///
public Style DocumentPaneControlStyle
{
get { return (Style)GetValue(DocumentPaneControlStyleProperty); }
set { SetValue(DocumentPaneControlStyleProperty, value); }
}
///
/// Handles changes to the DocumentPaneControlStyle property.
///
private static void OnDocumentPaneControlStyleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((DockingManager)d).OnDocumentPaneControlStyleChanged(e);
}
///
/// Provides derived classes an opportunity to handle changes to the DocumentPaneControlStyle property.
///
protected virtual void OnDocumentPaneControlStyleChanged(DependencyPropertyChangedEventArgs e)
{
}
#endregion
#region AnchorablePaneControlStyle
///
/// AnchorablePaneControlStyle Dependency Property
///
public static readonly DependencyProperty AnchorablePaneControlStyleProperty =
DependencyProperty.Register("AnchorablePaneControlStyle", typeof(Style), typeof(DockingManager),
new FrameworkPropertyMetadata((Style)null,
new PropertyChangedCallback(OnAnchorablePaneControlStyleChanged)));
///
/// Gets or sets the AnchorablePaneControlStyle property. This dependency property
/// indicates the style to apply to AnchorablePaneControl.
///
public Style AnchorablePaneControlStyle
{
get { return (Style)GetValue(AnchorablePaneControlStyleProperty); }
set { SetValue(AnchorablePaneControlStyleProperty, value); }
}
///
/// Handles changes to the AnchorablePaneControlStyle property.
///
private static void OnAnchorablePaneControlStyleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((DockingManager)d).OnAnchorablePaneControlStyleChanged(e);
}
///
/// Provides derived classes an opportunity to handle changes to the AnchorablePaneControlStyle property.
///
protected virtual void OnAnchorablePaneControlStyleChanged(DependencyPropertyChangedEventArgs e)
{
}
#endregion
#region DocumentHeaderTemplate
///
/// DocumentHeaderTemplate Dependency Property
///
public static readonly DependencyProperty DocumentHeaderTemplateProperty =
DependencyProperty.Register("DocumentHeaderTemplate", typeof(DataTemplate), typeof(DockingManager),
new FrameworkPropertyMetadata((DataTemplate)null,
new PropertyChangedCallback(OnDocumentHeaderTemplateChanged),
new CoerceValueCallback(CoerceDocumentHeaderTemplateValue)));
///
/// Gets or sets the DocumentHeaderTemplate property. This dependency property
/// indicates data template to use for document header.
///
public DataTemplate DocumentHeaderTemplate
{
get { return (DataTemplate)GetValue(DocumentHeaderTemplateProperty); }
set { SetValue(DocumentHeaderTemplateProperty, value); }
}
///
/// Handles changes to the DocumentHeaderTemplate property.
///
private static void OnDocumentHeaderTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((DockingManager)d).OnDocumentHeaderTemplateChanged(e);
}
///
/// Provides derived classes an opportunity to handle changes to the DocumentHeaderTemplate property.
///
protected virtual void OnDocumentHeaderTemplateChanged(DependencyPropertyChangedEventArgs e)
{
}
///
/// Coerces the DocumentHeaderTemplate value.
///
private static object CoerceDocumentHeaderTemplateValue(DependencyObject d, object value)
{
if (value != null &&
d.GetValue(DocumentHeaderTemplateSelectorProperty) != null)
return null;
return value;
}
#endregion
#region DocumentHeaderTemplateSelector
///
/// DocumentHeaderTemplateSelector Dependency Property
///
public static readonly DependencyProperty DocumentHeaderTemplateSelectorProperty =
DependencyProperty.Register("DocumentHeaderTemplateSelector", typeof(DataTemplateSelector), typeof(DockingManager),
new FrameworkPropertyMetadata((DataTemplateSelector)null,
new PropertyChangedCallback(OnDocumentHeaderTemplateSelectorChanged),
new CoerceValueCallback(CoerceDocumentHeaderTemplateSelectorValue)));
///
/// Gets or sets the DocumentHeaderTemplateSelector property. This dependency property
/// indicates the template selector that is used when selcting the data template for the header.
///
public DataTemplateSelector DocumentHeaderTemplateSelector
{
get { return (DataTemplateSelector)GetValue(DocumentHeaderTemplateSelectorProperty); }
set { SetValue(DocumentHeaderTemplateSelectorProperty, value); }
}
///
/// Handles changes to the DocumentHeaderTemplateSelector property.
///
private static void OnDocumentHeaderTemplateSelectorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((DockingManager)d).OnDocumentHeaderTemplateSelectorChanged(e);
}
///
/// Provides derived classes an opportunity to handle changes to the DocumentHeaderTemplateSelector property.
///
protected virtual void OnDocumentHeaderTemplateSelectorChanged(DependencyPropertyChangedEventArgs e)
{
if (e.NewValue != null &&
DocumentHeaderTemplate != null)
DocumentHeaderTemplate = null;
if (DocumentPaneMenuItemHeaderTemplateSelector == null)
DocumentPaneMenuItemHeaderTemplateSelector = DocumentHeaderTemplateSelector;
}
///
/// Coerces the DocumentHeaderTemplateSelector value.
///
private static object CoerceDocumentHeaderTemplateSelectorValue(DependencyObject d, object value)
{
return value;
}
#endregion
#region DocumentTitleTemplate
///
/// DocumentTitleTemplate Dependency Property
///
public static readonly DependencyProperty DocumentTitleTemplateProperty =
DependencyProperty.Register("DocumentTitleTemplate", typeof(DataTemplate), typeof(DockingManager),
new FrameworkPropertyMetadata((DataTemplate)null,
new PropertyChangedCallback(OnDocumentTitleTemplateChanged),
new CoerceValueCallback(CoerceDocumentTitleTemplateValue)));
///
/// Gets or sets the DocumentTitleTemplate property. This dependency property
/// indicates the datatemplate to use when creating the title for a document.
///
public DataTemplate DocumentTitleTemplate
{
get { return (DataTemplate)GetValue(DocumentTitleTemplateProperty); }
set { SetValue(DocumentTitleTemplateProperty, value); }
}
///
/// Handles changes to the DocumentTitleTemplate property.
///
private static void OnDocumentTitleTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((DockingManager)d).OnDocumentTitleTemplateChanged(e);
}
///
/// Provides derived classes an opportunity to handle changes to the DocumentTitleTemplate property.
///
protected virtual void OnDocumentTitleTemplateChanged(DependencyPropertyChangedEventArgs e)
{
}
///
/// Coerces the DocumentTitleTemplate value.
///
private static object CoerceDocumentTitleTemplateValue(DependencyObject d, object value)
{
if (value != null &&
d.GetValue(DocumentTitleTemplateSelectorProperty) != null)
return null;
return value;
}
#endregion
#region DocumentTitleTemplateSelector
///
/// DocumentTitleTemplateSelector Dependency Property
///
public static readonly DependencyProperty DocumentTitleTemplateSelectorProperty =
DependencyProperty.Register("DocumentTitleTemplateSelector", typeof(DataTemplateSelector), typeof(DockingManager),
new FrameworkPropertyMetadata((DataTemplateSelector)null,
new PropertyChangedCallback(OnDocumentTitleTemplateSelectorChanged),
new CoerceValueCallback(CoerceDocumentTitleTemplateSelectorValue)));
///
/// Gets or sets the DocumentTitleTemplateSelector property. This dependency property
/// indicates the data template selector to use when creating the data template for the title.
///
public DataTemplateSelector DocumentTitleTemplateSelector
{
get { return (DataTemplateSelector)GetValue(DocumentTitleTemplateSelectorProperty); }
set { SetValue(DocumentTitleTemplateSelectorProperty, value); }
}
///
/// Handles changes to the DocumentTitleTemplateSelector property.
///
private static void OnDocumentTitleTemplateSelectorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((DockingManager)d).OnDocumentTitleTemplateSelectorChanged(e);
}
///
/// Provides derived classes an opportunity to handle changes to the DocumentTitleTemplateSelector property.
///
protected virtual void OnDocumentTitleTemplateSelectorChanged(DependencyPropertyChangedEventArgs e)
{
if (e.NewValue != null)
DocumentTitleTemplate = null;
}
///
/// Coerces the DocumentTitleTemplateSelector value.
///
private static object CoerceDocumentTitleTemplateSelectorValue(DependencyObject d, object value)
{
return value;
}
#endregion
#region AnchorableTitleTemplate
///
/// AnchorableTitleTemplate Dependency Property
///
public static readonly DependencyProperty AnchorableTitleTemplateProperty =
DependencyProperty.Register("AnchorableTitleTemplate", typeof(DataTemplate), typeof(DockingManager),
new FrameworkPropertyMetadata((DataTemplate)null,
new PropertyChangedCallback(OnAnchorableTitleTemplateChanged),
new CoerceValueCallback(CoerceAnchorableTitleTemplateValue)));
///
/// Gets or sets the AnchorableTitleTemplate property. This dependency property
/// indicates the data template to use for anchorables title.
///
public DataTemplate AnchorableTitleTemplate
{
get { return (DataTemplate)GetValue(AnchorableTitleTemplateProperty); }
set { SetValue(AnchorableTitleTemplateProperty, value); }
}
///
/// Handles changes to the AnchorableTitleTemplate property.
///
private static void OnAnchorableTitleTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((DockingManager)d).OnAnchorableTitleTemplateChanged(e);
}
///
/// Provides derived classes an opportunity to handle changes to the AnchorableTitleTemplate property.
///
protected virtual void OnAnchorableTitleTemplateChanged(DependencyPropertyChangedEventArgs e)
{
}
///
/// Coerces the AnchorableTitleTemplate value.
///
private static object CoerceAnchorableTitleTemplateValue(DependencyObject d, object value)
{
if (value != null &&
d.GetValue(AnchorableTitleTemplateSelectorProperty) != null)
return null;
return value;
}
#endregion
#region AnchorableTitleTemplateSelector
///
/// AnchorableTitleTemplateSelector Dependency Property
///
public static readonly DependencyProperty AnchorableTitleTemplateSelectorProperty =
DependencyProperty.Register("AnchorableTitleTemplateSelector", typeof(DataTemplateSelector), typeof(DockingManager),
new FrameworkPropertyMetadata((DataTemplateSelector)null,
new PropertyChangedCallback(OnAnchorableTitleTemplateSelectorChanged)));
///
/// Gets or sets the AnchorableTitleTemplateSelector property. This dependency property
/// indicates selctor to use when selecting data template for the title of anchorables.
///
public DataTemplateSelector AnchorableTitleTemplateSelector
{
get { return (DataTemplateSelector)GetValue(AnchorableTitleTemplateSelectorProperty); }
set { SetValue(AnchorableTitleTemplateSelectorProperty, value); }
}
///
/// Handles changes to the AnchorableTitleTemplateSelector property.
///
private static void OnAnchorableTitleTemplateSelectorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((DockingManager)d).OnAnchorableTitleTemplateSelectorChanged(e);
}
///
/// Provides derived classes an opportunity to handle changes to the AnchorableTitleTemplateSelector property.
///
protected virtual void OnAnchorableTitleTemplateSelectorChanged(DependencyPropertyChangedEventArgs e)
{
if (e.NewValue != null &&
AnchorableTitleTemplate != null)
AnchorableTitleTemplate = null;
}
#endregion
#region AnchorableHeaderTemplate
///
/// AnchorableHeaderTemplate Dependency Property
///
public static readonly DependencyProperty AnchorableHeaderTemplateProperty =
DependencyProperty.Register("AnchorableHeaderTemplate", typeof(DataTemplate), typeof(DockingManager),
new FrameworkPropertyMetadata((DataTemplate)null,
new PropertyChangedCallback(OnAnchorableHeaderTemplateChanged),
new CoerceValueCallback(CoerceAnchorableHeaderTemplateValue)));
///
/// Gets or sets the AnchorableHeaderTemplate property. This dependency property
/// indicates the data template to use for anchorable templates.
///
public DataTemplate AnchorableHeaderTemplate
{
get { return (DataTemplate)GetValue(AnchorableHeaderTemplateProperty); }
set { SetValue(AnchorableHeaderTemplateProperty, value); }
}
///
/// Handles changes to the AnchorableHeaderTemplate property.
///
private static void OnAnchorableHeaderTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((DockingManager)d).OnAnchorableHeaderTemplateChanged(e);
}
///
/// Provides derived classes an opportunity to handle changes to the AnchorableHeaderTemplate property.
///
protected virtual void OnAnchorableHeaderTemplateChanged(DependencyPropertyChangedEventArgs e)
{
}
///
/// Coerces the AnchorableHeaderTemplate value.
///
private static object CoerceAnchorableHeaderTemplateValue(DependencyObject d, object value)
{
if (value != null &&
d.GetValue(AnchorableHeaderTemplateSelectorProperty) != null)
return null;
return value;
}
#endregion
#region AnchorableHeaderTemplateSelector
///
/// AnchorableHeaderTemplateSelector Dependency Property
///
public static readonly DependencyProperty AnchorableHeaderTemplateSelectorProperty =
DependencyProperty.Register("AnchorableHeaderTemplateSelector", typeof(DataTemplateSelector), typeof(DockingManager),
new FrameworkPropertyMetadata((DataTemplateSelector)null,
new PropertyChangedCallback(OnAnchorableHeaderTemplateSelectorChanged)));
///
/// Gets or sets the AnchorableHeaderTemplateSelector property. This dependency property
/// indicates the selector to use when selecting the data template for anchorable headers.
///
public DataTemplateSelector AnchorableHeaderTemplateSelector
{
get { return (DataTemplateSelector)GetValue(AnchorableHeaderTemplateSelectorProperty); }
set { SetValue(AnchorableHeaderTemplateSelectorProperty, value); }
}
///
/// Handles changes to the AnchorableHeaderTemplateSelector property.
///
private static void OnAnchorableHeaderTemplateSelectorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((DockingManager)d).OnAnchorableHeaderTemplateSelectorChanged(e);
}
///
/// Provides derived classes an opportunity to handle changes to the AnchorableHeaderTemplateSelector property.
///
protected virtual void OnAnchorableHeaderTemplateSelectorChanged(DependencyPropertyChangedEventArgs e)
{
if (e.NewValue != null)
AnchorableHeaderTemplate = null;
}
#endregion
protected override void OnGotKeyboardFocus(System.Windows.Input.KeyboardFocusChangedEventArgs e)
{
//if (e.NewFocus is Grid)
// Trace.WriteLine(string.Format("DockingManager.OnGotKeyboardFocus({0})", e.NewFocus));
base.OnGotKeyboardFocus(e);
}
protected override void OnPreviewGotKeyboardFocus(System.Windows.Input.KeyboardFocusChangedEventArgs e)
{
Trace.WriteLine(string.Format("DockingManager.OnPreviewGotKeyboardFocus({0})", e.NewFocus));
base.OnPreviewGotKeyboardFocus(e);
}
protected override void OnPreviewLostKeyboardFocus(KeyboardFocusChangedEventArgs e)
{
Trace.WriteLine(string.Format("DockingManager.OnPreviewLostKeyboardFocus({0})", e.OldFocus));
base.OnPreviewLostKeyboardFocus(e);
}
protected override void OnMouseLeftButtonDown(System.Windows.Input.MouseButtonEventArgs e)
{
Trace.WriteLine(string.Format("DockingManager.OnMouseLeftButtonDown([{0}])", e.GetPosition(this)));
base.OnMouseLeftButtonDown(e);
}
protected override void OnMouseMove(System.Windows.Input.MouseEventArgs e)
{
//Trace.WriteLine(string.Format("DockingManager.OnMouseMove([{0}])", e.GetPosition(this)));
base.OnMouseMove(e);
}
#region LayoutRootPanel
///
/// LayoutRootPanel Dependency Property
///
public static readonly DependencyProperty LayoutRootPanelProperty =
DependencyProperty.Register("LayoutRootPanel", typeof(LayoutPanelControl), typeof(DockingManager),
new FrameworkPropertyMetadata((LayoutPanelControl)null,
new PropertyChangedCallback(OnLayoutRootPanelChanged)));
///
/// Gets or sets the LayoutRootPanel property. This dependency property
/// indicates the layout panel control which is attached to the Layout.Root property.
///
public LayoutPanelControl LayoutRootPanel
{
get { return (LayoutPanelControl)GetValue(LayoutRootPanelProperty); }
set { SetValue(LayoutRootPanelProperty, value); }
}
///
/// Handles changes to the LayoutRootPanel property.
///
private static void OnLayoutRootPanelChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((DockingManager)d).OnLayoutRootPanelChanged(e);
}
///
/// Provides derived classes an opportunity to handle changes to the LayoutRootPanel property.
///
protected virtual void OnLayoutRootPanelChanged(DependencyPropertyChangedEventArgs e)
{
if (e.OldValue != null)
InternalRemoveLogicalChild(e.OldValue);
if (e.NewValue != null)
InternalAddLogicalChild(e.NewValue);
}
#endregion
#region RightSidePanel
///
/// RightSidePanel Dependency Property
///
public static readonly DependencyProperty RightSidePanelProperty =
DependencyProperty.Register("RightSidePanel", typeof(LayoutAnchorSideControl), typeof(DockingManager),
new FrameworkPropertyMetadata((LayoutAnchorSideControl)null,
new PropertyChangedCallback(OnRightSidePanelChanged)));
///
/// Gets or sets the RightSidePanel property. This dependency property
/// indicates right side anchor panel.
///
public LayoutAnchorSideControl RightSidePanel
{
get { return (LayoutAnchorSideControl)GetValue(RightSidePanelProperty); }
set { SetValue(RightSidePanelProperty, value); }
}
///
/// Handles changes to the RightSidePanel property.
///
private static void OnRightSidePanelChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((DockingManager)d).OnRightSidePanelChanged(e);
}
///
/// Provides derived classes an opportunity to handle changes to the RightSidePanel property.
///
protected virtual void OnRightSidePanelChanged(DependencyPropertyChangedEventArgs e)
{
if (e.OldValue != null)
InternalRemoveLogicalChild(e.OldValue);
if (e.NewValue != null)
InternalAddLogicalChild(e.NewValue);
}
#endregion
#region LeftSidePanel
///
/// LeftSidePanel Dependency Property
///
public static readonly DependencyProperty LeftSidePanelProperty =
DependencyProperty.Register("LeftSidePanel", typeof(LayoutAnchorSideControl), typeof(DockingManager),
new FrameworkPropertyMetadata((LayoutAnchorSideControl)null,
new PropertyChangedCallback(OnLeftSidePanelChanged)));
///
/// Gets or sets the LeftSidePanel property. This dependency property
/// indicates the left side panel control.
///
public LayoutAnchorSideControl LeftSidePanel
{
get { return (LayoutAnchorSideControl)GetValue(LeftSidePanelProperty); }
set { SetValue(LeftSidePanelProperty, value); }
}
///
/// Handles changes to the LeftSidePanel property.
///
private static void OnLeftSidePanelChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((DockingManager)d).OnLeftSidePanelChanged(e);
}
///
/// Provides derived classes an opportunity to handle changes to the LeftSidePanel property.
///
protected virtual void OnLeftSidePanelChanged(DependencyPropertyChangedEventArgs e)
{
if (e.OldValue != null)
InternalRemoveLogicalChild(e.OldValue);
if (e.NewValue != null)
InternalAddLogicalChild(e.NewValue);
}
#endregion
#region TopSidePanel
///
/// TopSidePanel Dependency Property
///
public static readonly DependencyProperty TopSidePanelProperty =
DependencyProperty.Register("TopSidePanel", typeof(LayoutAnchorSideControl), typeof(DockingManager),
new FrameworkPropertyMetadata((LayoutAnchorSideControl)null,
new PropertyChangedCallback(OnTopSidePanelChanged)));
///
/// Gets or sets the TopSidePanel property. This dependency property
/// indicates top side control panel.
///
public LayoutAnchorSideControl TopSidePanel
{
get { return (LayoutAnchorSideControl)GetValue(TopSidePanelProperty); }
set { SetValue(TopSidePanelProperty, value); }
}
///
/// Handles changes to the TopSidePanel property.
///
private static void OnTopSidePanelChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((DockingManager)d).OnTopSidePanelChanged(e);
}
///
/// Provides derived classes an opportunity to handle changes to the TopSidePanel property.
///
protected virtual void OnTopSidePanelChanged(DependencyPropertyChangedEventArgs e)
{
if (e.OldValue != null)
InternalRemoveLogicalChild(e.OldValue);
if (e.NewValue != null)
InternalAddLogicalChild(e.NewValue);
}
#endregion
#region BottomSidePanel
///
/// BottomSidePanel Dependency Property
///
public static readonly DependencyProperty BottomSidePanelProperty =
DependencyProperty.Register("BottomSidePanel", typeof(LayoutAnchorSideControl), typeof(DockingManager),
new FrameworkPropertyMetadata((LayoutAnchorSideControl)null,
new PropertyChangedCallback(OnBottomSidePanelChanged)));
///
/// Gets or sets the BottomSidePanel property. This dependency property
/// indicates bottom side panel control.
///
public LayoutAnchorSideControl BottomSidePanel
{
get { return (LayoutAnchorSideControl)GetValue(BottomSidePanelProperty); }
set { SetValue(BottomSidePanelProperty, value); }
}
///
/// Handles changes to the BottomSidePanel property.
///
private static void OnBottomSidePanelChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((DockingManager)d).OnBottomSidePanelChanged(e);
}
///
/// Provides derived classes an opportunity to handle changes to the BottomSidePanel property.
///
protected virtual void OnBottomSidePanelChanged(DependencyPropertyChangedEventArgs e)
{
if (e.OldValue != null)
InternalRemoveLogicalChild(e.OldValue);
if (e.NewValue != null)
InternalAddLogicalChild(e.NewValue);
}
#endregion
#region LogicalChildren
List _logicalChildren = new List();
protected override System.Collections.IEnumerator LogicalChildren
{
get
{
return _logicalChildren.Select(ch => ch.GetValueOrDefault