DockPanel.DockDragHandler.cs
上传用户:szlfmled
上传日期:2020-11-22
资源大小:978k
文件大小:33k
源码类别:

C#编程

开发平台:

C#

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Windows.Forms;
  5. using System.Drawing;
  6. using System.Drawing.Drawing2D;
  7. using System.ComponentModel;
  8. namespace WeifenLuo.WinFormsUI.Docking
  9. {
  10.     partial class DockPanel
  11.     {
  12.         private sealed class DockDragHandler : DragHandler
  13.         {
  14.             private class DockIndicator : DragForm
  15.             {
  16.                 #region IHitTest
  17.                 private interface IHitTest
  18.                 {
  19.                     DockStyle HitTest(Point pt);
  20.                     DockStyle Status { get; set; }
  21.                 }
  22.                 #endregion
  23.                 #region PanelIndicator
  24.                 private class PanelIndicator : PictureBox, IHitTest
  25.                 {
  26.                     private static Image _imagePanelLeft = Resources.DockIndicator_PanelLeft;
  27.                     private static Image _imagePanelRight = Resources.DockIndicator_PanelRight;
  28.                     private static Image _imagePanelTop = Resources.DockIndicator_PanelTop;
  29.                     private static Image _imagePanelBottom = Resources.DockIndicator_PanelBottom;
  30.                     private static Image _imagePanelFill = Resources.DockIndicator_PanelFill;
  31.                     private static Image _imagePanelLeftActive = Resources.DockIndicator_PanelLeft_Active;
  32.                     private static Image _imagePanelRightActive = Resources.DockIndicator_PanelRight_Active;
  33.                     private static Image _imagePanelTopActive = Resources.DockIndicator_PanelTop_Active;
  34.                     private static Image _imagePanelBottomActive = Resources.DockIndicator_PanelBottom_Active;
  35.                     private static Image _imagePanelFillActive = Resources.DockIndicator_PanelFill_Active;
  36.                     public PanelIndicator(DockStyle dockStyle)
  37.                     {
  38.                         m_dockStyle = dockStyle;
  39.                         SizeMode = PictureBoxSizeMode.AutoSize;
  40.                         Image = ImageInactive;
  41.                     }
  42.                     private DockStyle m_dockStyle;
  43.                     private DockStyle DockStyle
  44.                     {
  45.                         get { return m_dockStyle; }
  46.                     }
  47.                     private DockStyle m_status;
  48.                     public DockStyle Status
  49.                     {
  50.                         get { return m_status; }
  51.                         set
  52.                         {
  53.                             if (value != DockStyle && value != DockStyle.None)
  54.                                 throw new InvalidEnumArgumentException();
  55.                             if (m_status == value)
  56.                                 return;
  57.                             m_status = value;
  58.                             IsActivated = (m_status != DockStyle.None);
  59.                         }
  60.                     }
  61.                     private Image ImageInactive
  62.                     {
  63.                         get
  64.                         {
  65.                             if (DockStyle == DockStyle.Left)
  66.                                 return _imagePanelLeft;
  67.                             else if (DockStyle == DockStyle.Right)
  68.                                 return _imagePanelRight;
  69.                             else if (DockStyle == DockStyle.Top)
  70.                                 return _imagePanelTop;
  71.                             else if (DockStyle == DockStyle.Bottom)
  72.                                 return _imagePanelBottom;
  73.                             else if (DockStyle == DockStyle.Fill)
  74.                                 return _imagePanelFill;
  75.                             else
  76.                                 return null;
  77.                         }
  78.                     }
  79.                     private Image ImageActive
  80.                     {
  81.                         get
  82.                         {
  83.                             if (DockStyle == DockStyle.Left)
  84.                                 return _imagePanelLeftActive;
  85.                             else if (DockStyle == DockStyle.Right)
  86.                                 return _imagePanelRightActive;
  87.                             else if (DockStyle == DockStyle.Top)
  88.                                 return _imagePanelTopActive;
  89.                             else if (DockStyle == DockStyle.Bottom)
  90.                                 return _imagePanelBottomActive;
  91.                             else if (DockStyle == DockStyle.Fill)
  92.                                 return _imagePanelFillActive;
  93.                             else
  94.                                 return null;
  95.                         }
  96.                     }
  97.                     private bool m_isActivated = false;
  98.                     private bool IsActivated
  99.                     {
  100.                         get { return m_isActivated; }
  101.                         set
  102.                         {
  103.                             m_isActivated = value;
  104.                             Image = IsActivated ? ImageActive : ImageInactive;
  105.                         }
  106.                     }
  107.                     public DockStyle HitTest(Point pt)
  108.                     {
  109.                         return this.Visible && ClientRectangle.Contains(PointToClient(pt)) ? DockStyle : DockStyle.None;
  110.                     }
  111.                 }
  112.                 #endregion PanelIndicator
  113.                 #region PaneIndicator
  114.                 private class PaneIndicator : PictureBox, IHitTest
  115.                 {
  116.                     private struct HotSpotIndex
  117.                     {
  118.                         public HotSpotIndex(int x, int y, DockStyle dockStyle)
  119.                         {
  120.                             m_x = x;
  121.                             m_y = y;
  122.                             m_dockStyle = dockStyle;
  123.                         }
  124.                         private int m_x;
  125.                         public int X
  126.                         {
  127.                             get { return m_x; }
  128.                         }
  129.                         private int m_y;
  130.                         public int Y
  131.                         {
  132.                             get { return m_y; }
  133.                         }
  134.                         private DockStyle m_dockStyle;
  135.                         public DockStyle DockStyle
  136.                         {
  137.                             get { return m_dockStyle; }
  138.                         }
  139.                     }
  140.                     private static Bitmap _bitmapPaneDiamond = Resources.DockIndicator_PaneDiamond;
  141.                     private static Bitmap _bitmapPaneDiamondLeft = Resources.DockIndicator_PaneDiamond_Left;
  142.                     private static Bitmap _bitmapPaneDiamondRight = Resources.DockIndicator_PaneDiamond_Right;
  143.                     private static Bitmap _bitmapPaneDiamondTop = Resources.DockIndicator_PaneDiamond_Top;
  144.                     private static Bitmap _bitmapPaneDiamondBottom = Resources.DockIndicator_PaneDiamond_Bottom;
  145.                     private static Bitmap _bitmapPaneDiamondFill = Resources.DockIndicator_PaneDiamond_Fill;
  146.                     private static Bitmap _bitmapPaneDiamondHotSpot = Resources.DockIndicator_PaneDiamond_HotSpot;
  147.                     private static Bitmap _bitmapPaneDiamondHotSpotIndex = Resources.DockIndicator_PaneDiamond_HotSpotIndex;
  148.                     private static HotSpotIndex[] _hotSpots = new HotSpotIndex[]
  149. {
  150. new HotSpotIndex(1, 0, DockStyle.Top),
  151. new HotSpotIndex(0, 1, DockStyle.Left),
  152. new HotSpotIndex(1, 1, DockStyle.Fill),
  153. new HotSpotIndex(2, 1, DockStyle.Right),
  154. new HotSpotIndex(1, 2, DockStyle.Bottom)
  155. };
  156.                     private static GraphicsPath _displayingGraphicsPath = DrawHelper.CalculateGraphicsPathFromBitmap(_bitmapPaneDiamond);
  157.                     public PaneIndicator()
  158.                     {
  159.                         SizeMode = PictureBoxSizeMode.AutoSize;
  160.                         Image = _bitmapPaneDiamond;
  161.                         Region = new Region(DisplayingGraphicsPath);
  162.                     }
  163.                     public static GraphicsPath DisplayingGraphicsPath
  164.                     {
  165.                         get { return _displayingGraphicsPath; }
  166.                     }
  167.                     public DockStyle HitTest(Point pt)
  168.                     {
  169.                         if (!Visible)
  170.                             return DockStyle.None;
  171.                         pt = PointToClient(pt);
  172.                         if (!ClientRectangle.Contains(pt))
  173.                             return DockStyle.None;
  174.                         for (int i = _hotSpots.GetLowerBound(0); i <= _hotSpots.GetUpperBound(0); i++)
  175.                         {
  176.                             if (_bitmapPaneDiamondHotSpot.GetPixel(pt.X, pt.Y) == _bitmapPaneDiamondHotSpotIndex.GetPixel(_hotSpots[i].X, _hotSpots[i].Y))
  177.                                 return _hotSpots[i].DockStyle;
  178.                         }
  179.                         return DockStyle.None;
  180.                     }
  181.                     private DockStyle m_status = DockStyle.None;
  182.                     public DockStyle Status
  183.                     {
  184.                         get { return m_status; }
  185.                         set
  186.                         {
  187.                             m_status = value;
  188.                             if (m_status == DockStyle.None)
  189.                                 Image = _bitmapPaneDiamond;
  190.                             else if (m_status == DockStyle.Left)
  191.                                 Image = _bitmapPaneDiamondLeft;
  192.                             else if (m_status == DockStyle.Right)
  193.                                 Image = _bitmapPaneDiamondRight;
  194.                             else if (m_status == DockStyle.Top)
  195.                                 Image = _bitmapPaneDiamondTop;
  196.                             else if (m_status == DockStyle.Bottom)
  197.                                 Image = _bitmapPaneDiamondBottom;
  198.                             else if (m_status == DockStyle.Fill)
  199.                                 Image = _bitmapPaneDiamondFill;
  200.                         }
  201.                     }
  202.                 }
  203.                 #endregion PaneIndicator
  204.                 #region consts
  205.                 private int _PanelIndicatorMargin = 10;
  206.                 #endregion
  207.                 private DockDragHandler m_dragHandler;
  208.                 public DockIndicator(DockDragHandler dragHandler)
  209.                 {
  210.                     m_dragHandler = dragHandler;
  211.                     Controls.AddRange(new Control[] {
  212.             PaneDiamond,
  213.             PanelLeft,
  214.             PanelRight,
  215.             PanelTop,
  216.             PanelBottom,
  217.             PanelFill
  218.             });
  219.                     Region = new Region(Rectangle.Empty);
  220.                 }
  221.                 private PaneIndicator m_paneDiamond = null;
  222.                 private PaneIndicator PaneDiamond
  223.                 {
  224.                     get
  225.                     {
  226.                         if (m_paneDiamond == null)
  227.                             m_paneDiamond = new PaneIndicator();
  228.                         return m_paneDiamond;
  229.                     }
  230.                 }
  231.                 private PanelIndicator m_panelLeft = null;
  232.                 private PanelIndicator PanelLeft
  233.                 {
  234.                     get
  235.                     {
  236.                         if (m_panelLeft == null)
  237.                             m_panelLeft = new PanelIndicator(DockStyle.Left);
  238.                         return m_panelLeft;
  239.                     }
  240.                 }
  241.                 private PanelIndicator m_panelRight = null;
  242.                 private PanelIndicator PanelRight
  243.                 {
  244.                     get
  245.                     {
  246.                         if (m_panelRight == null)
  247.                             m_panelRight = new PanelIndicator(DockStyle.Right);
  248.                         return m_panelRight;
  249.                     }
  250.                 }
  251.                 private PanelIndicator m_panelTop = null;
  252.                 private PanelIndicator PanelTop
  253.                 {
  254.                     get
  255.                     {
  256.                         if (m_panelTop == null)
  257.                             m_panelTop = new PanelIndicator(DockStyle.Top);
  258.                         return m_panelTop;
  259.                     }
  260.                 }
  261.                 private PanelIndicator m_panelBottom = null;
  262.                 private PanelIndicator PanelBottom
  263.                 {
  264.                     get
  265.                     {
  266.                         if (m_panelBottom == null)
  267.                             m_panelBottom = new PanelIndicator(DockStyle.Bottom);
  268.                         return m_panelBottom;
  269.                     }
  270.                 }
  271.                 private PanelIndicator m_panelFill = null;
  272.                 private PanelIndicator PanelFill
  273.                 {
  274.                     get
  275.                     {
  276.                         if (m_panelFill == null)
  277.                             m_panelFill = new PanelIndicator(DockStyle.Fill);
  278.                         return m_panelFill;
  279.                     }
  280.                 }
  281.                 private bool m_fullPanelEdge = false;
  282.                 public bool FullPanelEdge
  283.                 {
  284.                     get { return m_fullPanelEdge; }
  285.                     set
  286.                     {
  287.                         if (m_fullPanelEdge == value)
  288.                             return;
  289.                         m_fullPanelEdge = value;
  290.                         RefreshChanges();
  291.                     }
  292.                 }
  293.                 public DockDragHandler DragHandler
  294.                 {
  295.                     get { return m_dragHandler; }
  296.                 }
  297.                 public DockPanel DockPanel
  298.                 {
  299.                     get { return DragHandler.DockPanel; }
  300.                 }
  301.                 private DockPane m_dockPane = null;
  302.                 public DockPane DockPane
  303.                 {
  304.                     get { return m_dockPane; }
  305.                     internal set
  306.                     {
  307.                         if (m_dockPane == value)
  308.                             return;
  309.                         DockPane oldDisplayingPane = DisplayingPane;
  310.                         m_dockPane = value;
  311.                         if (oldDisplayingPane != DisplayingPane)
  312.                             RefreshChanges();
  313.                     }
  314.                 }
  315.                 private IHitTest m_hitTest = null;
  316.                 private IHitTest HitTestResult
  317.                 {
  318.                     get { return m_hitTest; }
  319.                     set
  320.                     {
  321.                         if (m_hitTest == value)
  322.                             return;
  323.                         if (m_hitTest != null)
  324.                             m_hitTest.Status = DockStyle.None;
  325.                         m_hitTest = value;
  326.                     }
  327.                 }
  328.                 private DockPane DisplayingPane
  329.                 {
  330.                     get { return ShouldPaneDiamondVisible() ? DockPane : null; }
  331.                 }
  332.                 private void RefreshChanges()
  333.                 {
  334.                     Region region = new Region(Rectangle.Empty);
  335.                     Rectangle rectDockArea = FullPanelEdge ? DockPanel.DockArea : DockPanel.DocumentWindowBounds;
  336.                     rectDockArea = RectangleToClient(DockPanel.RectangleToScreen(rectDockArea));
  337.                     if (ShouldPanelIndicatorVisible(DockState.DockLeft))
  338.                     {
  339.                         PanelLeft.Location = new Point(rectDockArea.X + _PanelIndicatorMargin, rectDockArea.Y + (rectDockArea.Height - PanelRight.Height) / 2);
  340.                         PanelLeft.Visible = true;
  341.                         region.Union(PanelLeft.Bounds);
  342.                     }
  343.                     else
  344.                         PanelLeft.Visible = false;
  345.                     if (ShouldPanelIndicatorVisible(DockState.DockRight))
  346.                     {
  347.                         PanelRight.Location = new Point(rectDockArea.X + rectDockArea.Width - PanelRight.Width - _PanelIndicatorMargin, rectDockArea.Y + (rectDockArea.Height - PanelRight.Height) / 2);
  348.                         PanelRight.Visible = true;
  349.                         region.Union(PanelRight.Bounds);
  350.                     }
  351.                     else
  352.                         PanelRight.Visible = false;
  353.                     if (ShouldPanelIndicatorVisible(DockState.DockTop))
  354.                     {
  355.                         PanelTop.Location = new Point(rectDockArea.X + (rectDockArea.Width - PanelTop.Width) / 2, rectDockArea.Y + _PanelIndicatorMargin);
  356.                         PanelTop.Visible = true;
  357.                         region.Union(PanelTop.Bounds);
  358.                     }
  359.                     else
  360.                         PanelTop.Visible = false;
  361.                     if (ShouldPanelIndicatorVisible(DockState.DockBottom))
  362.                     {
  363.                         PanelBottom.Location = new Point(rectDockArea.X + (rectDockArea.Width - PanelBottom.Width) / 2, rectDockArea.Y + rectDockArea.Height - PanelBottom.Height - _PanelIndicatorMargin);
  364.                         PanelBottom.Visible = true;
  365.                         region.Union(PanelBottom.Bounds);
  366.                     }
  367.                     else
  368.                         PanelBottom.Visible = false;
  369.                     if (ShouldPanelIndicatorVisible(DockState.Document))
  370.                     {
  371.                         Rectangle rectDocumentWindow = RectangleToClient(DockPanel.RectangleToScreen(DockPanel.DocumentWindowBounds));
  372.                         PanelFill.Location = new Point(rectDocumentWindow.X + (rectDocumentWindow.Width - PanelFill.Width) / 2, rectDocumentWindow.Y + (rectDocumentWindow.Height - PanelFill.Height) / 2);
  373.                         PanelFill.Visible = true;
  374.                         region.Union(PanelFill.Bounds);
  375.                     }
  376.                     else
  377.                         PanelFill.Visible = false;
  378.                     if (ShouldPaneDiamondVisible())
  379.                     {
  380.                         Rectangle rect = RectangleToClient(DockPane.RectangleToScreen(DockPane.ClientRectangle));
  381.                         PaneDiamond.Location = new Point(rect.Left + (rect.Width - PaneDiamond.Width) / 2, rect.Top + (rect.Height - PaneDiamond.Height) / 2);
  382.                         PaneDiamond.Visible = true;
  383.                         using (GraphicsPath graphicsPath = PaneIndicator.DisplayingGraphicsPath.Clone() as GraphicsPath)
  384.                         {
  385.                             Point[] pts = new Point[]
  386. {
  387. new Point(PaneDiamond.Left, PaneDiamond.Top),
  388. new Point(PaneDiamond.Right, PaneDiamond.Top),
  389. new Point(PaneDiamond.Left, PaneDiamond.Bottom)
  390. };
  391.                             using (Matrix matrix = new Matrix(PaneDiamond.ClientRectangle, pts))
  392.                             {
  393.                                 graphicsPath.Transform(matrix);
  394.                             }
  395.                             region.Union(graphicsPath);
  396.                         }
  397.                     }
  398.                     else
  399.                         PaneDiamond.Visible = false;
  400.                     Region = region;
  401.                 }
  402.                 private bool ShouldPanelIndicatorVisible(DockState dockState)
  403.                 {
  404.                     if (!Visible)
  405.                         return false;
  406.                     if (DockPanel.DockWindows[dockState].Visible)
  407.                         return false;
  408.                     return DragHandler.DragSource.IsDockStateValid(dockState);
  409.                 }
  410.                 private bool ShouldPaneDiamondVisible()
  411.                 {
  412.                     if (DockPane == null)
  413.                         return false;
  414.                     if (!DockPanel.AllowEndUserNestedDocking)
  415.                         return false;
  416.                     return DragHandler.DragSource.CanDockTo(DockPane);
  417.                 }
  418.                 public override void Show(bool bActivate)
  419.                 {
  420.                     base.Show(bActivate);
  421.                     Bounds = SystemInformation.VirtualScreen;
  422.                     RefreshChanges();
  423.                 }
  424.                 public void TestDrop()
  425.                 {
  426.                     Point pt = Control.MousePosition;
  427.                     DockPane = DockHelper.PaneAtPoint(pt, DockPanel);
  428.                     if (TestDrop(PanelLeft, pt) != DockStyle.None)
  429.                         HitTestResult = PanelLeft;
  430.                     else if (TestDrop(PanelRight, pt) != DockStyle.None)
  431.                         HitTestResult = PanelRight;
  432.                     else if (TestDrop(PanelTop, pt) != DockStyle.None)
  433.                         HitTestResult = PanelTop;
  434.                     else if (TestDrop(PanelBottom, pt) != DockStyle.None)
  435.                         HitTestResult = PanelBottom;
  436.                     else if (TestDrop(PanelFill, pt) != DockStyle.None)
  437.                         HitTestResult = PanelFill;
  438.                     else if (TestDrop(PaneDiamond, pt) != DockStyle.None)
  439.                         HitTestResult = PaneDiamond;
  440.                     else
  441.                         HitTestResult = null;
  442.                     if (HitTestResult != null)
  443.                     {
  444.                         if (HitTestResult is PaneIndicator)
  445.                             DragHandler.Outline.Show(DockPane, HitTestResult.Status);
  446.                         else
  447.                             DragHandler.Outline.Show(DockPanel, HitTestResult.Status, FullPanelEdge);
  448.                     }
  449.                 }
  450.                 private static DockStyle TestDrop(IHitTest hitTest, Point pt)
  451.                 {
  452.                     return hitTest.Status = hitTest.HitTest(pt);
  453.                 }
  454.             }
  455.             private class DockOutline : DockOutlineBase
  456.             {
  457.                 public DockOutline()
  458.                 {
  459.                     m_dragForm = new DragForm();
  460.                     SetDragForm(Rectangle.Empty);
  461.                     DragForm.BackColor = SystemColors.ActiveCaption;
  462.                     DragForm.Opacity = 0.5;
  463.                     DragForm.Show(false);
  464.                 }
  465.                 DragForm m_dragForm;
  466.                 private DragForm DragForm
  467.                 {
  468.                     get { return m_dragForm; }
  469.                 }
  470.                 protected override void OnShow()
  471.                 {
  472.                     CalculateRegion();
  473.                 }
  474.                 protected override void OnClose()
  475.                 {
  476.                     DragForm.Close();
  477.                 }
  478.                 private void CalculateRegion()
  479.                 {
  480.                     if (SameAsOldValue)
  481.                         return;
  482.                     if (!FloatWindowBounds.IsEmpty)
  483.                         SetOutline(FloatWindowBounds);
  484.                     else if (DockTo is DockPanel)
  485.                         SetOutline(DockTo as DockPanel, Dock, (ContentIndex != 0));
  486.                     else if (DockTo is DockPane)
  487.                         SetOutline(DockTo as DockPane, Dock, ContentIndex);
  488.                     else
  489.                         SetOutline();
  490.                 }
  491.                 private void SetOutline()
  492.                 {
  493.                     SetDragForm(Rectangle.Empty);
  494.                 }
  495.                 private void SetOutline(Rectangle floatWindowBounds)
  496.                 {
  497.                     SetDragForm(floatWindowBounds);
  498.                 }
  499.                 private void SetOutline(DockPanel dockPanel, DockStyle dock, bool fullPanelEdge)
  500.                 {
  501.                     Rectangle rect = fullPanelEdge ? dockPanel.DockArea : dockPanel.DocumentWindowBounds;
  502.                     rect.Location = dockPanel.PointToScreen(rect.Location);
  503.                     if (dock == DockStyle.Top)
  504.                     {
  505.                         int height = dockPanel.GetDockWindowSize(DockState.DockTop);
  506.                         rect = new Rectangle(rect.X, rect.Y, rect.Width, height);
  507.                     }
  508.                     else if (dock == DockStyle.Bottom)
  509.                     {
  510.                         int height = dockPanel.GetDockWindowSize(DockState.DockBottom);
  511.                         rect = new Rectangle(rect.X, rect.Bottom - height, rect.Width, height);
  512.                     }
  513.                     else if (dock == DockStyle.Left)
  514.                     {
  515.                         int width = dockPanel.GetDockWindowSize(DockState.DockLeft);
  516.                         rect = new Rectangle(rect.X, rect.Y, width, rect.Height);
  517.                     }
  518.                     else if (dock == DockStyle.Right)
  519.                     {
  520.                         int width = dockPanel.GetDockWindowSize(DockState.DockRight);
  521.                         rect = new Rectangle(rect.Right - width, rect.Y, width, rect.Height);
  522.                     }
  523.                     else if (dock == DockStyle.Fill)
  524.                     {
  525.                         rect = dockPanel.DocumentWindowBounds;
  526.                         rect.Location = dockPanel.PointToScreen(rect.Location);
  527.                     }
  528.                     SetDragForm(rect);
  529.                 }
  530.                 private void SetOutline(DockPane pane, DockStyle dock, int contentIndex)
  531.                 {
  532.                     if (dock != DockStyle.Fill)
  533.                     {
  534.                         Rectangle rect = pane.DisplayingRectangle;
  535.                         if (dock == DockStyle.Right)
  536.                             rect.X += rect.Width / 2;
  537.                         if (dock == DockStyle.Bottom)
  538.                             rect.Y += rect.Height / 2;
  539.                         if (dock == DockStyle.Left || dock == DockStyle.Right)
  540.                             rect.Width -= rect.Width / 2;
  541.                         if (dock == DockStyle.Top || dock == DockStyle.Bottom)
  542.                             rect.Height -= rect.Height / 2;
  543.                         rect.Location = pane.PointToScreen(rect.Location);
  544.                         SetDragForm(rect);
  545.                     }
  546.                     else if (contentIndex == -1)
  547.                     {
  548.                         Rectangle rect = pane.DisplayingRectangle;
  549.                         rect.Location = pane.PointToScreen(rect.Location);
  550.                         SetDragForm(rect);
  551.                     }
  552.                     else
  553.                     {
  554.                         using (GraphicsPath path = pane.TabStripControl.GetOutline(contentIndex))
  555.                         {
  556.                             RectangleF rectF = path.GetBounds();
  557.                             Rectangle rect = new Rectangle((int)rectF.X, (int)rectF.Y, (int)rectF.Width, (int)rectF.Height);
  558.                             using (Matrix matrix = new Matrix(rect, new Point[] { new Point(0, 0), new Point(rect.Width, 0), new Point(0, rect.Height) }))
  559.                             {
  560.                                 path.Transform(matrix);
  561.                             }
  562.                             Region region = new Region(path);
  563.                             SetDragForm(rect, region);
  564.                         }
  565.                     }
  566.                 }
  567.                 private void SetDragForm(Rectangle rect)
  568.                 {
  569.                     DragForm.Bounds = rect;
  570.                     if (rect == Rectangle.Empty)
  571.                         DragForm.Region = new Region(Rectangle.Empty);
  572.                     else if (DragForm.Region != null)
  573.                         DragForm.Region = null;
  574.                 }
  575.                 private void SetDragForm(Rectangle rect, Region region)
  576.                 {
  577.                     DragForm.Bounds = rect;
  578.                     DragForm.Region = region;
  579.                 }
  580.             }
  581.             public DockDragHandler(DockPanel panel)
  582.                 : base(panel)
  583.             {
  584.             }
  585.             public new IDockDragSource DragSource
  586.             {
  587.                 get { return base.DragSource as IDockDragSource; }
  588.                 set { base.DragSource = value; }
  589.             }
  590.             private DockOutlineBase m_outline;
  591.             public DockOutlineBase Outline
  592.             {
  593.                 get { return m_outline; }
  594.                 private set { m_outline = value; }
  595.             }
  596.             private DockIndicator m_indicator;
  597.             private DockIndicator Indicator
  598.             {
  599.                 get { return m_indicator; }
  600.                 set { m_indicator = value; }
  601.             }
  602.             private Rectangle m_floatOutlineBounds;
  603.             private Rectangle FloatOutlineBounds
  604.             {
  605.                 get { return m_floatOutlineBounds; }
  606.                 set { m_floatOutlineBounds = value; }
  607.             }
  608.             public void BeginDrag(IDockDragSource dragSource)
  609.             {
  610.                 DragSource = dragSource;
  611.                 if (!BeginDrag())
  612.                 {
  613.                     DragSource = null;
  614.                     return;
  615.                 }
  616.                 Outline = new DockOutline();
  617.                 Indicator = new DockIndicator(this);
  618.                 Indicator.Show(false);
  619.                 FloatOutlineBounds = DragSource.BeginDrag(StartMousePosition);
  620.             }
  621.             protected override void OnDragging()
  622.             {
  623.                 TestDrop();
  624.             }
  625.             protected override void OnEndDrag(bool abort)
  626.             {
  627.                 DockPanel.SuspendLayout(true);
  628.                 Outline.Close();
  629.                 Indicator.Close();
  630.                 EndDrag(abort);
  631.                 // Queue a request to layout all children controls
  632.                 DockPanel.PerformMdiClientLayout();
  633.                 DockPanel.ResumeLayout(true, true);
  634.                 DragSource = null;
  635.             }
  636.             private void TestDrop()
  637.             {
  638.                 Outline.FlagTestDrop = false;
  639.                 Indicator.FullPanelEdge = ((Control.ModifierKeys & Keys.Shift) != 0);
  640.                 if ((Control.ModifierKeys & Keys.Control) == 0)
  641.                 {
  642.                     Indicator.TestDrop();
  643.                     if (!Outline.FlagTestDrop)
  644.                     {
  645.                         DockPane pane = DockHelper.PaneAtPoint(Control.MousePosition, DockPanel);
  646.                         if (pane != null && DragSource.IsDockStateValid(pane.DockState))
  647.                             pane.TestDrop(DragSource, Outline);
  648.                     }
  649.                     if (!Outline.FlagTestDrop && DragSource.IsDockStateValid(DockState.Float))
  650.                     {
  651.                         FloatWindow floatWindow = DockHelper.FloatWindowAtPoint(Control.MousePosition, DockPanel);
  652.                         if (floatWindow != null)
  653.                             floatWindow.TestDrop(DragSource, Outline);
  654.                     }
  655.                 }
  656.                 else
  657.                     Indicator.DockPane = DockHelper.PaneAtPoint(Control.MousePosition, DockPanel);
  658.                 if (!Outline.FlagTestDrop)
  659.                 {
  660.                     if (DragSource.IsDockStateValid(DockState.Float))
  661.                     {
  662.                         Rectangle rect = FloatOutlineBounds;
  663.                         rect.Offset(Control.MousePosition.X - StartMousePosition.X, Control.MousePosition.Y - StartMousePosition.Y);
  664.                         Outline.Show(rect);
  665.                     }
  666.                 }
  667.                 if (!Outline.FlagTestDrop)
  668.                 {
  669.                     Cursor.Current = Cursors.No;
  670.                     Outline.Show();
  671.                 }
  672.                 else
  673.                     Cursor.Current = DragControl.Cursor;
  674.             }
  675.             private void EndDrag(bool abort)
  676.             {
  677.                 if (abort)
  678.                     return;
  679.                 if (!Outline.FloatWindowBounds.IsEmpty)
  680.                     DragSource.FloatAt(Outline.FloatWindowBounds);
  681.                 else if (Outline.DockTo is DockPane)
  682.                 {
  683.                     DockPane pane = Outline.DockTo as DockPane;
  684.                     DragSource.DockTo(pane, Outline.Dock, Outline.ContentIndex);
  685.                 }
  686.                 else if (Outline.DockTo is DockPanel)
  687.                 {
  688.                     DockPanel panel = Outline.DockTo as DockPanel;
  689.                     panel.UpdateDockWindowZOrder(Outline.Dock, Outline.FlagFullEdge);
  690.                     DragSource.DockTo(panel, Outline.Dock);
  691.                 }
  692.             }
  693.         }
  694.         private DockDragHandler m_dockDragHandler = null;
  695.         private DockDragHandler GetDockDragHandler()
  696.         {
  697.             if (m_dockDragHandler == null)
  698.                 m_dockDragHandler = new DockDragHandler(this);
  699.             return m_dockDragHandler;
  700.         }
  701.         internal void BeginDrag(IDockDragSource dragSource)
  702.         {
  703.             GetDockDragHandler().BeginDrag(dragSource);
  704.         }
  705.     }
  706. }