/// <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;
        }
Beispiel #4
0
        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();
        }
Beispiel #12
0
        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);
                    }
                }
            }
        }