/// <summary> /// Prepares a panel for the UI. Override for hooking custom events. /// </summary> /// <param name="panel">The panel to prepare.</param> protected virtual void PreparePanel(DragDockPanel panel) { // Hook up panel events panel.DragStarted += new DragEventHander(this.DragDockPanel_DragStarted); panel.DragFinished += new DragEventHander(this.DragDockPanel_DragFinished); panel.DragMoved += new DragEventHander(this.DragDockPanel_DragMoved); panel.Maximized += new EventHandler(this.DragDockPanel_Maximized); panel.Restored += new EventHandler(this.DragDockPanel_Restored); if (panel.PanelState == PanelState.Maximized) { this.maximizedPanel = panel; foreach (DragDockPanel dragDockPanel in this.panels) { if (panel != dragDockPanel) { dragDockPanel.Minimize(); } } } }
/// <summary> /// Maximises a panel. /// </summary> /// <param name="sender">the panel to maximise.</param> /// <param name="e">Event args.</param> private void DragDockPanel_Maximized(object sender, EventArgs e) { DragDockPanel maximizedPanel = sender as DragDockPanel; // Store max'ed panel this.maximizedPanel = maximizedPanel; // Loop through children to disable dragging foreach (UIElement child in this.panels) { DragDockPanel panel = child as DragDockPanel; panel.DraggingEnabled = false; if (panel != this.maximizedPanel) { panel.Minimize(); } } // Update sizes and layout this.AnimatePanelSizes(); this.AnimatePanelLayout(); }
/// <summary> /// Keeps a reference to the dragging panel. /// </summary> /// <param name="sender">The dragging panel.</param> /// <param name="args">Drag event args.</param> private void DragDockPanel_DragStarted(object sender, DragEventArgs args) { DragDockPanel panel = sender as DragDockPanel; // Keep reference to dragging panel this.draggingPanel = panel; }
void tt_MouseLeave(object sender, MouseEventArgs e) { TextBox tb2 = sender as TextBox; if (tb2 != null) { TextBlock tb = new TextBlock() { Text = tb2.Text, FontFamily = new FontFamily("Verdana"), FontSize = 14, VerticalAlignment = VerticalAlignment.Center, HorizontalAlignment = HorizontalAlignment.Center, TextWrapping = System.Windows.TextWrapping.Wrap, Foreground = new SolidColorBrush(Color.FromArgb(0x44, 255, 0, 255)) }; tb.MouseLeftButtonDown += new MouseButtonEventHandler(DragSample_MouseLeftButtonDown); DragDockPanel ddp = tb2.Parent as DragDockPanel; if (ddp != null) { ddp.Content = tb; } } }
/// <summary> /// Drops the dragging panel. /// </summary> /// <param name="sender">The dragging panel.</param> /// <param name="args">Drag event args.</param> private void DragDockPanel_DragFinished(object sender, DragEventArgs args) { // Set dragging panel back to null this.draggingPanel = null; // Update the layout (to reset all panel positions) this.UpdatePanelLayout(); }
/// <summary> /// Unprepares a drag dock panel. /// </summary> /// <param name="element">The source drag dock panel.</param> /// <param name="item">The source item.</param> protected override void ClearContainerForItemOverride(DependencyObject element, object item) { base.ClearContainerForItemOverride(element, item); DragDockPanel panel = element as DragDockPanel; this.UnpreparePanel(panel); this.panels.Remove(panel); this.SetRowsAndColumns(this.GetOrderedPanels()); this.AnimatePanelSizes(); this.AnimatePanelLayout(); }
/// <summary> /// Shuffles the panels around. /// </summary> /// <param name="sender">The dragging panel.</param> /// <param name="args">Drag event args.</param> private void DragDockPanel_DragMoved(object sender, DragEventArgs args) { Point mousePosInHost = args.MouseEventArgs.GetPosition(this); int currentRow = (int)Math.Floor(mousePosInHost.Y / (this.ActualHeight / (double)this.rows)); int currentColumn = (int)Math.Floor(mousePosInHost.X / (this.ActualWidth / (double)this.columns)); // Stores the panel we will swap with DragDockPanel swapPanel = null; // Loop through children to see if there is a panel to swap with foreach (UIElement child in this.panels) { DragDockPanel panel = child as DragDockPanel; // If the panel is not the dragging panel and is in the current row // or current column... mark it as the panel to swap with if (panel != this.draggingPanel && Grid.GetColumn(panel) == currentColumn && Grid.GetRow(panel) == currentRow) { swapPanel = panel; break; } } // If there is a panel to swap with if (swapPanel != null) { // Store the new row and column int draggingPanelNewColumn = Grid.GetColumn(swapPanel); int draggingPanelNewRow = Grid.GetRow(swapPanel); // Update the swapping panel row and column Grid.SetColumn(swapPanel, Grid.GetColumn(this.draggingPanel)); Grid.SetRow(swapPanel, Grid.GetRow(this.draggingPanel)); // Update the dragging panel row and column Grid.SetColumn(this.draggingPanel, draggingPanelNewColumn); Grid.SetRow(this.draggingPanel, draggingPanelNewRow); // Animate the layout to the new positions this.AnimatePanelLayout(); } }
/// <summary> /// Puts all of the panel back to a grid view. /// </summary> /// <param name="sender">The minimising panel.</param> /// <param name="e">Event args.</param> private void DragDockPanel_Restored(object sender, EventArgs e) { // Set max'ed panel to null this.maximizedPanel = null; // Loop through children to disable dragging foreach (UIElement child in this.panels) { DragDockPanel panel = child as DragDockPanel; panel.Restore(); panel.DraggingEnabled = true; } // Update sizes and layout this.AnimatePanelSizes(); this.AnimatePanelLayout(); }
/// <summary> /// Updates the layout when in design mode. /// </summary> /// <param name="sender">The drag dock panel host.</param> /// <param name="e">Event Args.</param> private void DragDockPanelHost_LayoutUpdated(object sender, EventArgs e) { if (System.ComponentModel.DesignerProperties.GetIsInDesignMode(this)) { Dictionary <int, DragDockPanel> orderedPanels = new Dictionary <int, DragDockPanel>(); for (int i = 0; i < this.panels.Count; i++) { if (this.panels[i].GetType() == typeof(DragDockPanel)) { DragDockPanel panel = (DragDockPanel)this.panels[i]; orderedPanels.Add(i, panel); } } this.SetRowsAndColumns(orderedPanels); this.UpdatePanelLayout(); } }
/// <summary> /// Unprepares a panel for the UI. Override for hooking custom events. /// </summary> /// <param name="panel">The panel to prepare.</param> protected virtual void UnpreparePanel(DragDockPanel panel) { if (panel.PanelState == PanelState.Maximized) { this.DragDockPanel_Restored(null, null); } // Hook up panel events panel.DragStarted -= new DragEventHander(this.DragDockPanel_DragStarted); panel.DragFinished -= new DragEventHander(this.DragDockPanel_DragFinished); panel.DragMoved -= new DragEventHander(this.DragDockPanel_DragMoved); panel.Maximized -= new EventHandler(this.DragDockPanel_Maximized); panel.Restored -= new EventHandler(this.DragDockPanel_Restored); }
/// <summary> /// Pepares a drag dock panel. /// </summary> /// <param name="element">The drag dock panel.</param> /// <param name="item">The source item.</param> protected override void PrepareContainerForItemOverride(DependencyObject element, object item) { base.PrepareContainerForItemOverride(element, item); DragDockPanel panel = element as DragDockPanel; if (panel.Style == null && this.DefaultPanelStyle != null) { panel.Style = this.DefaultPanelStyle; } Dictionary <int, DragDockPanel> orderedPanels = this.GetOrderedPanels(); orderedPanels.Add(this.panels.Count, panel); this.panels.Add(panel); this.PreparePanel(panel); this.SetRowsAndColumns(orderedPanels); this.AnimatePanelSizes(); this.AnimatePanelLayout(); }
void DragSample_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { TextBlock tb = sender as TextBlock; if (tb != null) { tb.Text = "Whoa! - you clicked on me..."; DragDockPanel ddp = tb.Parent as DragDockPanel; if (ddp != null) { TextBox tt = new TextBox(); tt.Text = tb.Text; tt.TextWrapping = TextWrapping.Wrap; tt.MouseLeave += new MouseEventHandler(tt_MouseLeave); ddp.Content = tt; } } }
/// <summary> /// Gets the panels in order. /// </summary> /// <returns>The ordered panels.</returns> private Dictionary <int, DragDockPanel> GetOrderedPanels() { Dictionary <int, DragDockPanel> orderedPanels = new Dictionary <int, DragDockPanel>(); List <DragDockPanel> addedPanels = new List <DragDockPanel>(); for (int i = 0; i < this.panels.Count; i++) { DragDockPanel lowestPanel = null; foreach (DragDockPanel panel in this.panels) { if (!addedPanels.Contains(panel) && (lowestPanel == null || ((Grid.GetRow(panel) * this.columns) + Grid.GetColumn(panel) < (Grid.GetRow(lowestPanel) * this.columns) + Grid.GetColumn(lowestPanel)))) { lowestPanel = panel; } } addedPanels.Add(lowestPanel); orderedPanels.Add(i, lowestPanel); } return(orderedPanels); }
/// <summary> /// Animate the panel positions /// </summary> private void AnimatePanelLayout() { if (double.IsInfinity(this.ActualWidth) || double.IsNaN(this.ActualWidth) || this.ActualWidth == 0) { return; } // If we are not in max'ed panel mode... if (this.maximizedPanel == null) { // Loop through children and size to row and columns foreach (UIElement child in this.panels) { DragDockPanel panel = (DragDockPanel)child; if (panel != this.draggingPanel) { panel.AnimatePosition( (Grid.GetColumn(panel) * (this.ActualWidth / (double)this.columns)), (Grid.GetRow(panel) * (this.ActualHeight / (double)this.rows))); } } } else { Dictionary <int, DragDockPanel> orderedPanels = new Dictionary <int, DragDockPanel>(); // Loop through children to order them according to their // current row and column... foreach (UIElement child in this.panels) { DragDockPanel panel = (DragDockPanel)child; orderedPanels.Add( (Grid.GetRow(panel) * this.columns) + Grid.GetColumn(panel), panel); } // Set initial top of minimized panels to 0 double currentOffset = 0.0; // For each of the panels (as ordered in the grid) for (int i = 0; i < orderedPanels.Count; i++) { // If the current panel is not the maximized panel if (orderedPanels[i] != this.maximizedPanel) { double newX = 0; double newY = currentOffset; #region determin new docking coordinates if (this.minimizedPosition.Equals(MinimizedPositions.Right)) { newX = this.ActualWidth - this.minimizedColumnWidth; newY = currentOffset; } else if (this.minimizedPosition.Equals(MinimizedPositions.Left)) { newX = 0; newY = currentOffset; } else if (this.minimizedPosition.Equals(MinimizedPositions.Bottom)) { newX = currentOffset; newY = this.ActualHeight - this.minimizedRowHeight; } else if (this.minimizedPosition.Equals(MinimizedPositions.Top)) { newX = currentOffset; newY = 0; } #endregion // Animate the position orderedPanels[i].AnimatePosition( newX, newY); if (this.minimizedPosition.Equals(MinimizedPositions.Left) || this.minimizedPosition.Equals(MinimizedPositions.Right)) { // Increment current top currentOffset += this.ActualHeight / (double)(this.panels.Count - 1); } else { // Increment current left currentOffset += this.ActualWidth / (double)(this.panels.Count - 1); } } else { #region determine new docking position double newX = 0; double newY = 0; if (this.minimizedPosition.Equals(MinimizedPositions.Right)) { newX = 0; newY = 0; } else if (this.minimizedPosition.Equals(MinimizedPositions.Left)) { newX = this.minimizedColumnWidth; newY = 0; } else if (this.minimizedPosition.Equals(MinimizedPositions.Bottom)) { newX = 0; newY = 0; } else if (this.minimizedPosition.Equals(MinimizedPositions.Top)) { newX = 0; newY = this.minimizedRowHeight; } #endregion // Animate maximized panel orderedPanels[i].AnimatePosition(newX, newY); } } } }
/// <summary> /// Animates the panel sizes /// </summary> private void AnimatePanelSizes() { if (double.IsInfinity(this.ActualWidth) || double.IsNaN(this.ActualWidth) || this.ActualWidth == 0) { return; } // If there is not a maxmized panel... if (this.maximizedPanel == null) { // Animate the panel sizes to row / column sizes foreach (UIElement child in this.panels) { DragDockPanel panel = (DragDockPanel)child; double width = (this.ActualWidth / (double)this.columns) - panel.Margin.Left - panel.Margin.Right; double height = (this.ActualHeight / (double)this.rows) - panel.Margin.Top - panel.Margin.Bottom; if (width < 0) { width = 0; } if (height < 0) { height = 0; } panel.AnimateSize( width, height); } } else { // Loop through the children foreach (UIElement child in this.panels) { DragDockPanel panel = (DragDockPanel)child; // Set the size of the non // maximized children if (panel != this.maximizedPanel) { #region determine new width & height depending on docking axis double newWidth = this.minimizedColumnWidth - panel.Margin.Left - panel.Margin.Right; double newHeight = (this.ActualHeight / (double)(this.panels.Count - 1)) - panel.Margin.Top - panel.Margin.Bottom; if (this.minimizedPosition.Equals(MinimizedPositions.Bottom) || this.minimizedPosition.Equals(MinimizedPositions.Top)) { newWidth = (this.ActualWidth / (double)(this.panels.Count - 1)) - panel.Margin.Left - panel.Margin.Right; newHeight = this.minimizedRowHeight - panel.Margin.Top - panel.Margin.Bottom; } #endregion if (newHeight < 0) { newHeight = 0; } if (newWidth < 0) { newWidth = 0; } panel.AnimateSize( newWidth, newHeight); } else { #region determine new width & height depending on docking axis double newWidth = this.ActualWidth - this.minimizedColumnWidth - panel.Margin.Left - panel.Margin.Right; double newHeight = this.ActualHeight - panel.Margin.Top - panel.Margin.Bottom; if (this.minimizedPosition.Equals(MinimizedPositions.Bottom) || this.minimizedPosition.Equals(MinimizedPositions.Top)) { newWidth = this.ActualWidth - panel.Margin.Left - panel.Margin.Right; newHeight = this.ActualHeight - this.minimizedRowHeight - panel.Margin.Top - panel.Margin.Bottom; } #endregion if (newHeight < 0) { newHeight = 0; } if (newWidth < 0) { newWidth = 0; } panel.AnimateSize( newWidth, newHeight); } } } }
/// <summary> /// Updates the panel layout without animation /// This does size and position without animation /// </summary> private void UpdatePanelLayout() { if (double.IsInfinity(this.ActualWidth) || double.IsNaN(this.ActualWidth) || this.ActualWidth == 0) { return; } // If we are not in max'ed panel mode... if (this.maximizedPanel == null) { // Layout children as per rows and columns foreach (UIElement child in this.panels) { DragDockPanel panel = (DragDockPanel)child; Canvas.SetLeft( panel, (Grid.GetColumn(panel) * (this.ActualWidth / (double)this.columns))); Canvas.SetTop( panel, (Grid.GetRow(panel) * (this.ActualHeight / (double)this.rows))); double width = (this.ActualWidth / (double)this.columns) - panel.Margin.Left - panel.Margin.Right; double height = (this.ActualHeight / (double)this.rows) - panel.Margin.Top - panel.Margin.Bottom; if (width < 0) { width = 0; } if (height < 0) { height = 0; } panel.Width = width; panel.Height = height; } } else { Dictionary <int, DragDockPanel> orderedPanels = new Dictionary <int, DragDockPanel>(); // Loop through children to order them according to their // current row and column... foreach (UIElement child in this.panels) { DragDockPanel panel = (DragDockPanel)child; orderedPanels.Add( (Grid.GetRow(panel) * this.columns) + Grid.GetColumn(panel), panel); } // Set initial top of minimized panels to 0 double currentOffset = 0.0; // For each of the panels (as ordered in the grid) for (int i = 0; i < orderedPanels.Count; i++) { // If the current panel is not the maximized panel if (orderedPanels[i] != this.maximizedPanel) { #region determine new width & height depending on docking axis double newWidth = this.minimizedColumnWidth - orderedPanels[i].Margin.Left - orderedPanels[i].Margin.Right; double newHeight = (this.ActualHeight / (double)(this.panels.Count - 1)) - orderedPanels[i].Margin.Top - orderedPanels[i].Margin.Bottom; if (this.minimizedPosition.Equals(MinimizedPositions.Bottom) || this.minimizedPosition.Equals(MinimizedPositions.Top)) { newWidth = (this.ActualWidth / (double)(this.panels.Count - 1)) - orderedPanels[i].Margin.Left - orderedPanels[i].Margin.Right; newHeight = this.minimizedRowHeight - orderedPanels[i].Margin.Top - orderedPanels[i].Margin.Bottom; } #endregion if (newHeight < 0) { newHeight = 0; } if (newWidth < 0) { newWidth = 0; } // Set the size of the panel orderedPanels[i].Width = newWidth; orderedPanels[i].Height = newHeight; double newX = 0; double newY = currentOffset; #region determin new docking coordinates if (this.minimizedPosition.Equals(MinimizedPositions.Right)) { newX = this.ActualWidth - this.minimizedColumnWidth; newY = currentOffset; } else if (this.minimizedPosition.Equals(MinimizedPositions.Left)) { newX = 0; newY = currentOffset; } else if (this.minimizedPosition.Equals(MinimizedPositions.Bottom)) { newX = currentOffset; newY = this.ActualHeight - this.minimizedRowHeight; } else if (this.minimizedPosition.Equals(MinimizedPositions.Top)) { newX = currentOffset; newY = 0; } #endregion // Set the position of the panel Canvas.SetLeft(orderedPanels[i], newX); Canvas.SetTop(orderedPanels[i], newY); if (this.minimizedPosition.Equals(MinimizedPositions.Left) || this.minimizedPosition.Equals(MinimizedPositions.Right)) { // Increment current top currentOffset += this.ActualHeight / (double)(this.panels.Count - 1); } else { // Increment current left currentOffset += this.ActualWidth / (double)(this.panels.Count - 1); } } else { #region determine new width & height depending on docking axis double newWidth = this.ActualWidth - this.minimizedColumnWidth - orderedPanels[i].Margin.Left - orderedPanels[i].Margin.Right; double newHeight = this.ActualHeight - orderedPanels[i].Margin.Top - orderedPanels[i].Margin.Bottom; if (this.minimizedPosition.Equals(MinimizedPositions.Bottom) || this.minimizedPosition.Equals(MinimizedPositions.Top)) { newWidth = this.ActualWidth - orderedPanels[i].Margin.Left - orderedPanels[i].Margin.Right; newHeight = this.ActualHeight - this.minimizedRowHeight - orderedPanels[i].Margin.Top - orderedPanels[i].Margin.Bottom; } #endregion if (newHeight < 0) { newHeight = 0; } if (newWidth < 0) { newWidth = 0; } // Set the size of the panel orderedPanels[i].Width = newWidth; orderedPanels[i].Height = newHeight; #region determine new docking position double newX = 0; double newY = 0; if (this.minimizedPosition.Equals(MinimizedPositions.Right)) { newX = 0; newY = 0; } else if (this.minimizedPosition.Equals(MinimizedPositions.Left)) { newX = this.minimizedColumnWidth; newY = 0; } else if (this.minimizedPosition.Equals(MinimizedPositions.Bottom)) { newX = 0; newY = 0; } else if (this.minimizedPosition.Equals(MinimizedPositions.Top)) { newX = 0; newY = this.minimizedRowHeight; } #endregion // Set the position of the panel Canvas.SetLeft(orderedPanels[i], newX); Canvas.SetTop(orderedPanels[i], newY); } } } }