/// <summary> /// Show a dockable content in its container with a desidered state /// </summary> /// <param name="content">Content to show</param> /// <param name="desideredState">State desidered</param> /// <param name="desideredAnchor">Border to which anchor the newly created container pane</param> /// <remarks></remarks> internal void Show(DockableContent content, DockableContentState desideredState, AnchorStyle desideredAnchor) { Debug.WriteLine(string.Format("Show Content={0}, desideredState={1}, desideredAnchor={2}", content.Name, desideredState, desideredAnchor)); #region Dockable content if (desideredState == DockableContentState.Hidden)//??!!show hidden? Hide(content); if (content.State == DockableContentState.AutoHide) { //first redock the content (content.ContainerPane as DockablePane).ToggleAutoHide(); //then show it as desidered Show(content, desideredState, desideredAnchor); } else if (content.State == DockableContentState.Docked || content.State == DockableContentState.Document || content.State == DockableContentState.None) { if (content.ContainerPane == null || content.State == DockableContentState.None) { //Problem!? try to rescue if (content.State == DockableContentState.Docked || content.State == DockableContentState.None) { //find the the pane which the desidered anchor style //DockablePane foundPane = this.FindChildDockablePane(desideredAnchor != AnchorStyle.None ? desideredAnchor : AnchorStyle.Right); //first search for a pane with other contents (avoiding empty panes which are containers for hidden contents) ILinqToTree<DependencyObject> itemFound = new LogicalTreeAdapter(this).Descendants().FirstOrDefault(el => el.Item is DockablePane && (el.Item as DockablePane).Anchor == desideredAnchor && (el.Item as DockablePane).IsDocked); if (itemFound == null)//search for all panes (even empty) itemFound = new LogicalTreeAdapter(this).Descendants().FirstOrDefault(el => el.Item is DockablePane && (el.Item as DockablePane).Anchor == desideredAnchor && (el.Item as DockablePane).Items.Count == 0); DockablePane foundPane = itemFound != null ? itemFound.Item as DockablePane : null; if (foundPane != null) { content.SetStateToDock(); foundPane.Items.Add(content); var containerPanel = foundPane.Parent as ResizingPanel; if (containerPanel != null) containerPanel.InvalidateMeasure(); } else { //if no suitable pane was found create e new one on the fly if (content.ContainerPane != null) { content.ContainerPane.RemoveContent(content); } DockablePane pane = new DockablePane(); pane.Items.Add(content); Anchor(pane, desideredAnchor); } } else { //add to main document pane MainDocumentPane.Items.Add(content); } } if (content.ContainerPane.GetManager() == null) { //disconnect the parent pane from previous panel //((Panel)content.ContainerPane.Parent).Children.Remove(content.ContainerPane); if (content.ContainerPane.Parent != null) { ((Panel)content.ContainerPane.Parent).Children.Remove(content.ContainerPane); } Anchor(content.ContainerPane as DockablePane, desideredAnchor); } if (desideredState == DockableContentState.DockableWindow || desideredState == DockableContentState.FloatingWindow) { var floatingWindow = new DockableFloatingWindow(this); floatingWindow.Content = content; var mainWindow = Window.GetWindow(this); if (mainWindow.IsVisible) floatingWindow.Owner = mainWindow; //floatingWindow.WindowStartupLocation = WindowStartupLocation.CenterOwner; //if (content.Content != null) //{ // floatingWindow.Width = Math.Min(((FrameworkElement)content.Content).ActualWidth, ResizingPanel.GetResizeWidth(content.ContainerPane)); // floatingWindow.Height = Math.Min(((FrameworkElement)content.Content).ActualHeight, ResizingPanel.GetResizeHeight(content.ContainerPane)); //} //else ////{ // floatingWindow.Width = 400; // floatingWindow.Height = 400; //} floatingWindow.Show(); } else if (desideredState == DockableContentState.AutoHide) { var paneContainer = content.ContainerPane as DockablePane; Debug.Assert(paneContainer != null); if (paneContainer != null) paneContainer.ToggleAutoHide(); content.Activate(); } else if (desideredState == DockableContentState.Document) { DocumentPane docPane = MainDocumentPane; if (docPane != null) { docPane.Items.Add(content.DetachFromContainerPane()); docPane.SelectedItem = content; content.SetStateToDocument(); } } else { content.ContainerPane.SelectedItem = content; content.Activate(); DockablePane dockParent = content.ContainerPane as DockablePane; if (content.ActualWidth == 0.0 && ( dockParent.Anchor == AnchorStyle.Left || dockParent.Anchor == AnchorStyle.Right)) { ResizingPanel.SetResizeWidth(dockParent, new GridLength(200)); ResizingPanel.SetEffectiveSize(dockParent, new Size(200, 0.0)); } else if (content.ActualWidth == 0.0 && ( dockParent.Anchor == AnchorStyle.Top || dockParent.Anchor == AnchorStyle.Bottom)) { ResizingPanel.SetResizeHeight(dockParent, new GridLength(200)); ResizingPanel.SetEffectiveSize(dockParent, new Size(200, 0.0)); } } } else if (content.State == DockableContentState.Document) { if (content.ContainerPane != null) content.ContainerPane.SelectedItem = this; content.Activate(); } else if (content.State == DockableContentState.Hidden || content.State == DockableContentState.DockableWindow || content.State == DockableContentState.FloatingWindow) { if (content.State == DockableContentState.Hidden) { //Debug.Assert(HiddenContents.Contains(content)); //HiddenContents.Remove(content); } else { FloatingWindow floatingWindow = null; floatingWindow = (content.ContainerPane as FloatingDockablePane).FloatingWindow; content.DetachFromContainerPane(); if (floatingWindow.HostedPane.Items.Count == 0) floatingWindow.Close(); } if (desideredState == DockableContentState.Docked || desideredState == DockableContentState.AutoHide) { if (content.SavedStateAndPosition != null && content.SavedStateAndPosition.ContainerPane != null && content.SavedStateAndPosition.ChildIndex >= 0 && content.SavedStateAndPosition.ContainerPane.GetManager() == this && desideredState == DockableContentState.Docked) { //ok previous container pane is here.. Pane prevPane = content.SavedStateAndPosition.ContainerPane; if (content.SavedStateAndPosition.ChildIndex < prevPane.Items.Count) { prevPane.Items.Insert(content.SavedStateAndPosition.ChildIndex, content); } else { prevPane.Items.Add(content); } if (prevPane.Items.Count == 1) { if (!double.IsNaN(content.SavedStateAndPosition.Width) || !double.IsInfinity(content.SavedStateAndPosition.Width)) { ResizingPanel.SetResizeWidth(content, new GridLength(content.SavedStateAndPosition.Width)); } } DockablePane prevDockablePane = prevPane as DockablePane; if (prevDockablePane != null && prevDockablePane.IsAutoHidden) { prevDockablePane.ToggleAutoHide(); } content.SetStateToDock(); content.Activate(); (prevPane.Parent as UIElement).InvalidateMeasure(); } else { if (desideredAnchor == AnchorStyle.None && content.SavedStateAndPosition != null && content.SavedStateAndPosition.Anchor != AnchorStyle.None) desideredAnchor = content.SavedStateAndPosition.Anchor; if (desideredAnchor == AnchorStyle.None) desideredAnchor = AnchorStyle.Right; DockablePane foundPane = null; if (desideredState == DockableContentState.Docked) { //first not empty panes ILinqToTree<DependencyObject> itemFound = new LogicalTreeAdapter(this).Descendants().FirstOrDefault(el => el.Item is DockablePane && (el.Item as DockablePane).Anchor == desideredAnchor && (el.Item as DockablePane).IsDocked); if (itemFound == null)//look for all panes even empty itemFound = new LogicalTreeAdapter(this).Descendants().FirstOrDefault(el => el.Item is DockablePane && (el.Item as DockablePane).Anchor == desideredAnchor && (el.Item as DockablePane).Items.Count == 0); foundPane = itemFound != null ? itemFound.Item as DockablePane : null; } if (foundPane != null) { content.SetStateToDock(); foundPane.Items.Add(content); if ((foundPane.IsAutoHidden && desideredState == DockableContentState.Docked) || (!foundPane.IsAutoHidden && desideredState == DockableContentState.AutoHide)) foundPane.ToggleAutoHide(); } else { DockablePane newHostpane = new DockablePane(); newHostpane.Items.Add(content); if (desideredAnchor == AnchorStyle.Left || desideredAnchor == AnchorStyle.Right) { double w = 200; if (content.SavedStateAndPosition != null && !double.IsInfinity(content.SavedStateAndPosition.Width) && !double.IsNaN(content.SavedStateAndPosition.Width)) w = content.SavedStateAndPosition.Width; ResizingPanel.SetResizeWidth(newHostpane, new GridLength(w)); ResizingPanel.SetEffectiveSize(newHostpane, new Size(w, 0.0)); } else { double h = 200; if (content.SavedStateAndPosition != null && !double.IsInfinity(content.SavedStateAndPosition.Height) && !double.IsNaN(content.SavedStateAndPosition.Height)) h = content.SavedStateAndPosition.Height; ResizingPanel.SetResizeHeight(newHostpane, new GridLength(h)); ResizingPanel.SetEffectiveSize(newHostpane, new Size(0.0, h)); } Anchor(newHostpane, desideredAnchor); if (desideredState == DockableContentState.AutoHide) { ToggleAutoHide(newHostpane); } } } ActiveContent = content; } else if (desideredState == DockableContentState.DockableWindow || desideredState == DockableContentState.FloatingWindow) { DockablePane newHostpane = null; FloatingDockablePane prevHostpane = null; if (content.SavedStateAndPosition != null && content.SavedStateAndPosition.ContainerPane != null && content.SavedStateAndPosition.ContainerPane is FloatingDockablePane) { prevHostpane = content.SavedStateAndPosition.ContainerPane as FloatingDockablePane; if (!prevHostpane.Items.Contains(content)) prevHostpane.Items.Add(content); } else { newHostpane = new DockablePane(); newHostpane.Items.Add(content); } if (desideredState == DockableContentState.DockableWindow) content.SetStateToDockableWindow(); else if (desideredState == DockableContentState.FloatingWindow) content.SetStateToFloatingWindow(); if (prevHostpane != null) { //check to see if floating window that host prevHostPane is already loaded (hosting other contents) var floatingWindow = prevHostpane.Parent as DockableFloatingWindow; if (floatingWindow != null && floatingWindow.IsLoaded) { floatingWindow.Activate(); } else { floatingWindow = new DockableFloatingWindow(this); floatingWindow.Content = content; floatingWindow.WindowStartupLocation = WindowStartupLocation.Manual; floatingWindow.Top = prevHostpane.FloatingWindow.Top; floatingWindow.Left = prevHostpane.FloatingWindow.Left; floatingWindow.Width = prevHostpane.FloatingWindow.Width; floatingWindow.Height = prevHostpane.FloatingWindow.Height; //floatingWindow.Owner = Window.GetWindow(this); var mainWindow = Window.GetWindow(this); if (mainWindow.IsVisible) floatingWindow.Owner = mainWindow; //now I've created a new pane to host the hidden content //if a an hidden content is shown that has prevHostpane as saved pane //I want that it is relocated in this new pane that I've created right now var hiddenContents = DockableContents.Where(c => c.State == DockableContentState.Hidden).ToArray(); foreach (var hiddenContent in hiddenContents) { if (hiddenContent.SavedStateAndPosition.ContainerPane == prevHostpane) { hiddenContent.SavedStateAndPosition = new DockableContentStateAndPosition( (floatingWindow.Content as Pane), hiddenContent.SavedStateAndPosition.ChildIndex, hiddenContent.SavedStateAndPosition.Width, hiddenContent.SavedStateAndPosition.Height, hiddenContent.SavedStateAndPosition.Anchor, hiddenContent.SavedStateAndPosition.State); } } floatingWindow.Show(); } } else if (newHostpane != null) { var floatingWindow = new DockableFloatingWindow(this); floatingWindow.Content = newHostpane; floatingWindow.WindowStartupLocation = WindowStartupLocation.CenterScreen; floatingWindow.Width = 200; floatingWindow.Height = 500; //floatingWindow.Owner = Window.GetWindow(this); var mainWindow = Window.GetWindow(this); if (mainWindow.IsVisible) floatingWindow.Owner = mainWindow; floatingWindow.Show(); } } else if (desideredState == DockableContentState.Document) { DocumentPane docPane = MainDocumentPane; if (docPane != null) { docPane.Items.Add(content); docPane.SelectedItem = content; content.SetStateToDocument(); } } } #endregion }
void DetachContentFromDockingManager(DockableContent content) { if (content.State == DockableContentState.AutoHide) { DockablePane parentContainer = content.Parent as DockablePane; if (parentContainer != null && parentContainer.Items.Count == 1) parentContainer.ToggleAutoHide(); } if (content.State == DockableContentState.DockableWindow || content.State == DockableContentState.FloatingWindow) { DockablePane parentContainer = content.Parent as DockablePane; if (parentContainer != null && parentContainer.Items.Count == 1) { FloatingWindow floatingWindow = Window.GetWindow(content) as FloatingWindow; floatingWindow.Close(true); } } //this content can be hidden also if was contained in closed floating window if (content.State == DockableContentState.Hidden) Show(content, DockableContentState.Docked); content.DetachFromContainerPane(); }
/// <summary> /// Hide a dockable content removing it from its container <see cref="Pane"/> /// </summary> /// <param name="content">Content to hide</param> /// <remarks>Note that if you simply remove a content from its container without calling this method, the /// layout serializer component can't managed correctly the removed content.</remarks> internal void Hide(DockableContent content) { if (content.State == DockableContentState.Hidden) { DockableContents.Add(content); return; } if (!content.IsCloseable) return; if (content.State != DockableContentState.FloatingWindow && content.State != DockableContentState.DockableWindow) { //save position only if hiding from a docked or autohidden pane content.SaveCurrentStateAndPosition(); } if (content.State == DockableContentState.AutoHide) { HideFlyoutWindow(); RemoveContentFromTabGroup(content); } if (content.State == DockableContentState.FloatingWindow || content.State == DockableContentState.DockableWindow) { DockableFloatingWindow floatingWindow = Window.GetWindow(content) as DockableFloatingWindow; if (floatingWindow != null && (floatingWindow.Content as Pane).HasSingleItem && !floatingWindow.IsClosing) { floatingWindow.Close(); } } if (content.State != DockableContentState.Hidden) { DockableContents.Add(content); content.SetStateToHidden(); content.DetachFromContainerPane(); } if (ActiveDocument == content) ActiveDocument = null; if (ActiveContent == content) ActiveContent = null; }