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

C#编程

开发平台:

C#

  1. using System;
  2. using System.ComponentModel;
  3. using System.Drawing;
  4. using System.Drawing.Drawing2D;
  5. using System.Windows.Forms;
  6. using System.Runtime.InteropServices;
  7. using System.Security.Permissions;
  8. using System.Diagnostics.CodeAnalysis;
  9. namespace WeifenLuo.WinFormsUI.Docking
  10. {
  11. [ToolboxItem(false)]
  12. public partial class DockPane : UserControl, IDockDragSource
  13. {
  14. public enum AppearanceStyle
  15. {
  16. ToolWindow,
  17. Document
  18. }
  19. private enum HitTestArea
  20. {
  21. Caption,
  22. TabStrip,
  23. Content,
  24. None
  25. }
  26. private struct HitTestResult
  27. {
  28. public HitTestArea HitArea;
  29. public int Index;
  30. public HitTestResult(HitTestArea hitTestArea, int index)
  31. {
  32. HitArea = hitTestArea;
  33. Index = index;
  34. }
  35. }
  36. private DockPaneCaptionBase m_captionControl;
  37. private DockPaneCaptionBase CaptionControl
  38. {
  39. get { return m_captionControl; }
  40. }
  41. private DockPaneStripBase m_tabStripControl;
  42. internal DockPaneStripBase TabStripControl
  43. {
  44. get { return m_tabStripControl; }
  45. }
  46. internal protected DockPane(IDockContent content, DockState visibleState, bool show)
  47. {
  48. InternalConstruct(content, visibleState, false, Rectangle.Empty, null, DockAlignment.Right, 0.5, show);
  49. }
  50.         [SuppressMessage("Microsoft.Naming", "CA1720:AvoidTypeNamesInParameters", MessageId = "1#")]
  51. internal protected DockPane(IDockContent content, FloatWindow floatWindow, bool show)
  52. {
  53.             if (floatWindow == null)
  54.                 throw new ArgumentNullException("floatWindow");
  55. InternalConstruct(content, DockState.Float, false, Rectangle.Empty, floatWindow.NestedPanes.GetDefaultPreviousPane(this), DockAlignment.Right, 0.5, show);
  56. }
  57. internal protected DockPane(IDockContent content, DockPane previousPane, DockAlignment alignment, double proportion, bool show)
  58. {
  59. if (previousPane == null)
  60. throw(new ArgumentNullException("previousPane"));
  61. InternalConstruct(content, previousPane.DockState, false, Rectangle.Empty, previousPane, alignment, proportion, show);
  62. }
  63.         [SuppressMessage("Microsoft.Naming", "CA1720:AvoidTypeNamesInParameters", MessageId = "1#")]
  64.         internal protected DockPane(IDockContent content, Rectangle floatWindowBounds, bool show)
  65. {
  66. InternalConstruct(content, DockState.Float, true, floatWindowBounds, null, DockAlignment.Right, 0.5, show);
  67. }
  68. private void InternalConstruct(IDockContent content, DockState dockState, bool flagBounds, Rectangle floatWindowBounds, DockPane prevPane, DockAlignment alignment, double proportion, bool show)
  69. {
  70. if (dockState == DockState.Hidden || dockState == DockState.Unknown)
  71. throw new ArgumentException(Strings.DockPane_SetDockState_InvalidState);
  72. if (content == null)
  73. throw new ArgumentNullException(Strings.DockPane_Constructor_NullContent);
  74. if (content.DockHandler.DockPanel == null)
  75. throw new ArgumentException(Strings.DockPane_Constructor_NullDockPanel);
  76. SuspendLayout();
  77. SetStyle(ControlStyles.Selectable, false);
  78. m_isFloat = (dockState == DockState.Float);
  79. m_contents = new DockContentCollection();
  80. m_displayingContents = new DockContentCollection(this);
  81. m_dockPanel = content.DockHandler.DockPanel;
  82. m_dockPanel.AddPane(this);
  83. m_splitter = new SplitterControl(this);
  84. m_nestedDockingStatus = new NestedDockingStatus(this);
  85. m_captionControl = DockPanel.DockPaneCaptionFactory.CreateDockPaneCaption(this);
  86. m_tabStripControl = DockPanel.DockPaneStripFactory.CreateDockPaneStrip(this);
  87. Controls.AddRange(new Control[] { m_captionControl, m_tabStripControl });
  88. DockPanel.SuspendLayout(true);
  89. if (flagBounds)
  90. FloatWindow = DockPanel.FloatWindowFactory.CreateFloatWindow(DockPanel, this, floatWindowBounds);
  91. else if (prevPane != null)
  92. DockTo(prevPane.NestedPanesContainer, prevPane, alignment, proportion);
  93. SetDockState(dockState);
  94. if (show)
  95. content.DockHandler.Pane = this;
  96. else if (this.IsFloat)
  97. content.DockHandler.FloatPane = this;
  98. else
  99. content.DockHandler.PanelPane = this;
  100. ResumeLayout();
  101. DockPanel.ResumeLayout(true, true);
  102. }
  103. protected override void Dispose(bool disposing)
  104. {
  105. if (disposing)
  106. {
  107. m_dockState = DockState.Unknown;
  108. if (NestedPanesContainer != null)
  109. NestedPanesContainer.NestedPanes.Remove(this);
  110. if (DockPanel != null)
  111. {
  112. DockPanel.RemovePane(this);
  113. m_dockPanel = null;
  114. }
  115. Splitter.Dispose();
  116.                 if (m_autoHidePane != null)
  117.     m_autoHidePane.Dispose();
  118. }
  119. base.Dispose(disposing);
  120. }
  121. private IDockContent m_activeContent = null;
  122. public virtual IDockContent ActiveContent
  123. {
  124. get { return m_activeContent; }
  125. set
  126. {
  127. if (ActiveContent == value)
  128. return;
  129. if (value != null)
  130. {
  131. if (!DisplayingContents.Contains(value))
  132. throw(new InvalidOperationException(Strings.DockPane_ActiveContent_InvalidValue));
  133. }
  134. else
  135. {
  136. if (DisplayingContents.Count != 0)
  137. throw(new InvalidOperationException(Strings.DockPane_ActiveContent_InvalidValue));
  138. }
  139. IDockContent oldValue = m_activeContent;
  140. if (DockPanel.ActiveAutoHideContent == oldValue)
  141. DockPanel.ActiveAutoHideContent = null;
  142. m_activeContent = value;
  143. if (DockPanel.DocumentStyle == DocumentStyle.DockingMdi && DockState == DockState.Document)
  144. {
  145. if (m_activeContent != null)
  146. m_activeContent.DockHandler.Form.BringToFront();
  147. }
  148. else
  149. {
  150. if (m_activeContent != null)
  151. m_activeContent.DockHandler.SetVisible();
  152. if (oldValue != null && DisplayingContents.Contains(oldValue))
  153. oldValue.DockHandler.SetVisible();
  154.                     if (IsActivated && m_activeContent != null)
  155.                         m_activeContent.DockHandler.Activate();
  156. }
  157. if (FloatWindow != null)
  158. FloatWindow.SetText();
  159.                 if (DockPanel.DocumentStyle == DocumentStyle.DockingMdi &&
  160.                     DockState == DockState.Document)
  161.                     RefreshChanges(false);  // delayed layout to reduce screen flicker
  162.                 else
  163.                     RefreshChanges();
  164. if (m_activeContent != null)
  165. TabStripControl.EnsureTabVisible(m_activeContent);
  166. }
  167. }
  168. private bool m_allowDockDragAndDrop = true;
  169. public virtual bool AllowDockDragAndDrop
  170. {
  171. get { return m_allowDockDragAndDrop; }
  172. set { m_allowDockDragAndDrop = value; }
  173. }
  174.         private IDisposable m_autoHidePane = null;
  175.         internal IDisposable AutoHidePane
  176.         {
  177.             get { return m_autoHidePane; }
  178.             set { m_autoHidePane = value; }
  179.         }
  180.         private object m_autoHideTabs = null;
  181.         internal object AutoHideTabs
  182.         {
  183.             get { return m_autoHideTabs; }
  184.             set { m_autoHideTabs = value; }
  185.         }
  186.         private object TabPageContextMenu
  187.         {
  188.             get
  189.             {
  190.                 IDockContent content = ActiveContent;
  191.                 if (content == null)
  192.                     return null;
  193.                 if (content.DockHandler.TabPageContextMenuStrip != null)
  194.                     return content.DockHandler.TabPageContextMenuStrip;
  195.                 else if (content.DockHandler.TabPageContextMenu != null)
  196.                     return content.DockHandler.TabPageContextMenu;
  197.                 else
  198.                     return null;
  199.             }
  200.         }
  201.         internal bool HasTabPageContextMenu
  202.         {
  203.             get { return TabPageContextMenu != null; }
  204.         }
  205.         internal void ShowTabPageContextMenu(Control control, Point position)
  206.         {
  207.             object menu = TabPageContextMenu;
  208.             if (menu == null)
  209.                 return;
  210.             ContextMenuStrip contextMenuStrip = menu as ContextMenuStrip;
  211.             if (contextMenuStrip != null)
  212.             {
  213.                 contextMenuStrip.Show(control, position);
  214.                 return;
  215.             }
  216.             ContextMenu contextMenu = menu as ContextMenu;
  217.             if (contextMenu != null)
  218.                 contextMenu.Show(this, position);
  219.         }
  220. private Rectangle CaptionRectangle
  221. {
  222. get
  223. {
  224. if (!HasCaption)
  225. return Rectangle.Empty;
  226. Rectangle rectWindow = DisplayingRectangle;
  227. int x, y, width;
  228. x = rectWindow.X;
  229. y = rectWindow.Y;
  230. width = rectWindow.Width;
  231. int height = CaptionControl.MeasureHeight();
  232. return new Rectangle(x, y, width, height);
  233. }
  234. }
  235. internal Rectangle ContentRectangle
  236. {
  237. get
  238. {
  239. Rectangle rectWindow = DisplayingRectangle;
  240. Rectangle rectCaption = CaptionRectangle;
  241. Rectangle rectTabStrip = TabStripRectangle;
  242. int x = rectWindow.X;
  243.                 int y = rectWindow.Y + (rectCaption.IsEmpty ? 0 : rectCaption.Height);
  244.                 if (DockState == DockState.Document && DockPanel.DocumentTabStripLocation == DocumentTabStripLocation.Top)
  245.                     y += rectTabStrip.Height;
  246.                 
  247. int width = rectWindow.Width;
  248. int height = rectWindow.Height - rectCaption.Height - rectTabStrip.Height;
  249. return new Rectangle(x, y, width, height);
  250. }
  251. }
  252. internal Rectangle TabStripRectangle
  253. {
  254. get
  255. {
  256. if (Appearance == AppearanceStyle.ToolWindow)
  257. return TabStripRectangle_ToolWindow;
  258. else
  259. return TabStripRectangle_Document;
  260. }
  261. }
  262. private Rectangle TabStripRectangle_ToolWindow
  263. {
  264. get
  265. {
  266. if (DisplayingContents.Count <= 1 || IsAutoHide)
  267. return Rectangle.Empty;
  268. Rectangle rectWindow = DisplayingRectangle;
  269. int width = rectWindow.Width;
  270. int height = TabStripControl.MeasureHeight();
  271. int x = rectWindow.X;
  272. int y = rectWindow.Bottom - height;
  273. Rectangle rectCaption = CaptionRectangle;
  274. if (rectCaption.Contains(x, y))
  275. y = rectCaption.Y + rectCaption.Height;
  276. return new Rectangle(x, y, width, height);
  277. }
  278. }
  279. private Rectangle TabStripRectangle_Document
  280. {
  281. get
  282. {
  283. if (DisplayingContents.Count == 0)
  284. return Rectangle.Empty;
  285. if (DisplayingContents.Count == 1 && DockPanel.DocumentStyle == DocumentStyle.DockingSdi)
  286. return Rectangle.Empty;
  287. Rectangle rectWindow = DisplayingRectangle;
  288. int x = rectWindow.X;
  289. int width = rectWindow.Width;
  290. int height = TabStripControl.MeasureHeight();
  291.                 int y = 0;
  292.                 if (DockPanel.DocumentTabStripLocation == DocumentTabStripLocation.Bottom)
  293.                     y = rectWindow.Height - height;
  294.                 else
  295.                     y = rectWindow.Y;
  296. return new Rectangle(x, y, width, height);
  297. }
  298. }
  299. public virtual string CaptionText
  300. {
  301. get { return ActiveContent == null ? string.Empty : ActiveContent.DockHandler.TabText; }
  302. }
  303. private DockContentCollection m_contents;
  304. public DockContentCollection Contents
  305. {
  306. get { return m_contents; }
  307. }
  308. private DockContentCollection m_displayingContents;
  309. public DockContentCollection DisplayingContents
  310. {
  311. get { return m_displayingContents; }
  312. }
  313. private DockPanel m_dockPanel;
  314. public DockPanel DockPanel
  315. {
  316. get { return m_dockPanel; }
  317. }
  318. private bool HasCaption
  319. {
  320. get
  321. {
  322. if (DockState == DockState.Document ||
  323. DockState == DockState.Hidden ||
  324. DockState == DockState.Unknown ||
  325. (DockState == DockState.Float && FloatWindow.VisibleNestedPanes.Count <= 1))
  326. return false;
  327. else
  328. return true;
  329. }
  330. }
  331. private bool m_isActivated = false;
  332. public bool IsActivated
  333. {
  334. get { return m_isActivated; }
  335. }
  336. internal void SetIsActivated(bool value)
  337. {
  338. if (m_isActivated == value)
  339. return;
  340. m_isActivated = value;
  341. if (DockState != DockState.Document)
  342. RefreshChanges(false);
  343. OnIsActivatedChanged(EventArgs.Empty);
  344. }
  345. private bool m_isActiveDocumentPane = false;
  346. public bool IsActiveDocumentPane
  347. {
  348. get { return m_isActiveDocumentPane; }
  349. }
  350. internal void SetIsActiveDocumentPane(bool value)
  351. {
  352. if (m_isActiveDocumentPane == value)
  353. return;
  354. m_isActiveDocumentPane = value;
  355. if (DockState == DockState.Document)
  356. RefreshChanges();
  357. OnIsActiveDocumentPaneChanged(EventArgs.Empty);
  358. }
  359. public bool IsDockStateValid(DockState dockState)
  360. {
  361. foreach (IDockContent content in Contents)
  362. if (!content.DockHandler.IsDockStateValid(dockState))
  363. return false;
  364. return true;
  365. }
  366. public bool IsAutoHide
  367. {
  368. get { return DockHelper.IsDockStateAutoHide(DockState); }
  369. }
  370. public AppearanceStyle Appearance
  371. {
  372. get { return (DockState == DockState.Document) ? AppearanceStyle.Document : AppearanceStyle.ToolWindow; }
  373. }
  374. internal Rectangle DisplayingRectangle
  375. {
  376. get { return ClientRectangle; }
  377. }
  378. public void Activate()
  379. {
  380. if (DockHelper.IsDockStateAutoHide(DockState) && DockPanel.ActiveAutoHideContent != ActiveContent)
  381. DockPanel.ActiveAutoHideContent = ActiveContent;
  382. else if (!IsActivated && ActiveContent != null)
  383. ActiveContent.DockHandler.Activate();
  384. }
  385. internal void AddContent(IDockContent content)
  386. {
  387. if (Contents.Contains(content))
  388. return;
  389. Contents.Add(content);
  390. }
  391. internal void Close()
  392. {
  393. Dispose();
  394. }
  395. public void CloseActiveContent()
  396. {
  397. CloseContent(ActiveContent);
  398. }
  399. internal void CloseContent(IDockContent content)
  400. {
  401.             DockPanel dockPanel = DockPanel;
  402.             dockPanel.SuspendLayout(true);
  403. if (content == null)
  404. return;
  405. if (!content.DockHandler.CloseButton)
  406. return;
  407. if (content.DockHandler.HideOnClose)
  408. content.DockHandler.Hide();
  409. else
  410. content.DockHandler.Close();
  411.             dockPanel.ResumeLayout(true, true);
  412.         }
  413. private HitTestResult GetHitTest(Point ptMouse)
  414. {
  415. Point ptMouseClient = PointToClient(ptMouse);
  416. Rectangle rectCaption = CaptionRectangle;
  417. if (rectCaption.Contains(ptMouseClient))
  418. return new HitTestResult(HitTestArea.Caption, -1);
  419. Rectangle rectContent = ContentRectangle;
  420. if (rectContent.Contains(ptMouseClient))
  421. return new HitTestResult(HitTestArea.Content, -1);
  422. Rectangle rectTabStrip = TabStripRectangle;
  423. if (rectTabStrip.Contains(ptMouseClient))
  424. return new HitTestResult(HitTestArea.TabStrip, TabStripControl.HitTest(TabStripControl.PointToClient(ptMouse)));
  425. return new HitTestResult(HitTestArea.None, -1);
  426. }
  427. private bool m_isHidden = true;
  428. public bool IsHidden
  429. {
  430. get { return m_isHidden; }
  431. }
  432. private void SetIsHidden(bool value)
  433. {
  434. if (m_isHidden == value)
  435. return;
  436. m_isHidden = value;
  437. if (DockHelper.IsDockStateAutoHide(DockState))
  438. {
  439. DockPanel.RefreshAutoHideStrip();
  440. DockPanel.PerformLayout();
  441. }
  442. else if (NestedPanesContainer != null)
  443. ((Control)NestedPanesContainer).PerformLayout();
  444. }
  445. protected override void OnLayout(LayoutEventArgs levent)
  446. {
  447. SetIsHidden(DisplayingContents.Count == 0);
  448. if (!IsHidden)
  449. {
  450. CaptionControl.Bounds = CaptionRectangle;
  451. TabStripControl.Bounds = TabStripRectangle;
  452. SetContentBounds();
  453. foreach (IDockContent content in Contents)
  454. {
  455. if (DisplayingContents.Contains(content))
  456. if (content.DockHandler.FlagClipWindow && content.DockHandler.Form.Visible)
  457. content.DockHandler.FlagClipWindow = false;
  458. }
  459. }
  460. base.OnLayout(levent);
  461. }
  462. internal void SetContentBounds()
  463. {
  464. Rectangle rectContent = ContentRectangle;
  465.             if (DockState == DockState.Document && DockPanel.DocumentStyle == DocumentStyle.DockingMdi)
  466.                 rectContent = DockPanel.RectangleToMdiClient(RectangleToScreen(rectContent));
  467.             Rectangle rectInactive = new Rectangle(-rectContent.Width, rectContent.Y, rectContent.Width, rectContent.Height);
  468. foreach (IDockContent content in Contents)
  469.                 if (content.DockHandler.Pane == this)
  470.                 {
  471.                     if (content == ActiveContent)
  472.                         content.DockHandler.Form.Bounds = rectContent;
  473.                     else
  474.                         content.DockHandler.Form.Bounds = rectInactive;
  475.                 }
  476. }
  477. internal void RefreshChanges()
  478. {
  479.             RefreshChanges(true);
  480. }
  481.         private void RefreshChanges(bool performLayout)
  482.         {
  483.             if (IsDisposed)
  484.                 return;
  485.             CaptionControl.RefreshChanges();
  486.             TabStripControl.RefreshChanges();
  487.             if (DockState == DockState.Float)
  488.                 FloatWindow.RefreshChanges();
  489.             if (DockHelper.IsDockStateAutoHide(DockState) && DockPanel != null)
  490.             {
  491.                 DockPanel.RefreshAutoHideStrip();
  492.                 DockPanel.PerformLayout();
  493.             }
  494.             if (performLayout)
  495.                 PerformLayout();
  496.         }
  497. internal void RemoveContent(IDockContent content)
  498. {
  499. if (!Contents.Contains(content))
  500. return;
  501. Contents.Remove(content);
  502. }
  503. public void SetContentIndex(IDockContent content, int index)
  504. {
  505. int oldIndex = Contents.IndexOf(content);
  506. if (oldIndex == -1)
  507. throw(new ArgumentException(Strings.DockPane_SetContentIndex_InvalidContent));
  508. if (index < 0 || index > Contents.Count - 1)
  509. if (index != -1)
  510. throw(new ArgumentOutOfRangeException(Strings.DockPane_SetContentIndex_InvalidIndex));
  511. if (oldIndex == index)
  512. return;
  513. if (oldIndex == Contents.Count - 1 && index == -1)
  514. return;
  515. Contents.Remove(content);
  516. if (index == -1)
  517. Contents.Add(content);
  518. else if (oldIndex < index)
  519. Contents.AddAt(content, index - 1);
  520. else
  521. Contents.AddAt(content, index);
  522. RefreshChanges();
  523. }
  524. private void SetParent()
  525. {
  526. if (DockState == DockState.Unknown || DockState == DockState.Hidden)
  527. {
  528. SetParent(null);
  529. Splitter.Parent = null;
  530. }
  531. else if (DockState == DockState.Float)
  532. {
  533. SetParent(FloatWindow);
  534. Splitter.Parent = FloatWindow;
  535. }
  536. else if (DockHelper.IsDockStateAutoHide(DockState))
  537. {
  538. SetParent(DockPanel.AutoHideControl);
  539. Splitter.Parent = null;
  540. }
  541. else
  542. {
  543. SetParent(DockPanel.DockWindows[DockState]);
  544. Splitter.Parent = Parent;
  545. }
  546. }
  547. private void SetParent(Control value)
  548. {
  549. if (Parent == value)
  550. return;
  551.             //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  552.             // Workaround of .Net Framework bug:
  553.             // Change the parent of a control with focus may result in the first
  554.             // MDI child form get activated. 
  555.             //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  556.             IDockContent contentFocused = GetFocusedContent();
  557.             if (contentFocused != null)
  558.                 DockPanel.SaveFocus();
  559.             //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  560.             Parent = value;
  561.             //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  562.             // Workaround of .Net Framework bug:
  563.             // Change the parent of a control with focus may result in the first
  564.             // MDI child form get activated. 
  565.             //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  566.             if (contentFocused != null)
  567.                 contentFocused.DockHandler.Activate();
  568.             //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  569.         }
  570. public new void Show()
  571. {
  572. Activate();
  573. }
  574.         internal void TestDrop(IDockDragSource dragSource, DockOutlineBase dockOutline)
  575.         {
  576.             if (!dragSource.CanDockTo(this))
  577.                 return;
  578.             Point ptMouse = Control.MousePosition;
  579.             HitTestResult hitTestResult = GetHitTest(ptMouse);
  580.             if (hitTestResult.HitArea == HitTestArea.Caption)
  581.                 dockOutline.Show(this, -1);
  582.             else if (hitTestResult.HitArea == HitTestArea.TabStrip && hitTestResult.Index != -1)
  583.                 dockOutline.Show(this, hitTestResult.Index);
  584.         }
  585. internal void ValidateActiveContent()
  586. {
  587. if (ActiveContent == null)
  588. {
  589. if (DisplayingContents.Count != 0)
  590. ActiveContent = DisplayingContents[0];
  591. return;
  592. }
  593. if (DisplayingContents.IndexOf(ActiveContent) >= 0)
  594. return;
  595. IDockContent prevVisible = null;
  596. for (int i=Contents.IndexOf(ActiveContent)-1; i>=0; i--)
  597. if (Contents[i].DockHandler.DockState == DockState)
  598. {
  599. prevVisible = Contents[i];
  600. break;
  601. }
  602. IDockContent nextVisible = null;
  603. for (int i=Contents.IndexOf(ActiveContent)+1; i<Contents.Count; i++)
  604. if (Contents[i].DockHandler.DockState == DockState)
  605. {
  606. nextVisible = Contents[i];
  607. break;
  608. }
  609. if (prevVisible != null)
  610. ActiveContent = prevVisible;
  611. else if (nextVisible != null)
  612. ActiveContent = nextVisible;
  613. else
  614. ActiveContent = null;
  615. }
  616. private static readonly object DockStateChangedEvent = new object();
  617. public event EventHandler DockStateChanged
  618. {
  619. add { Events.AddHandler(DockStateChangedEvent, value); }
  620. remove { Events.RemoveHandler(DockStateChangedEvent, value); }
  621. }
  622. protected virtual void OnDockStateChanged(EventArgs e)
  623. {
  624. EventHandler handler = (EventHandler)Events[DockStateChangedEvent];
  625. if (handler != null)
  626. handler(this, e);
  627. }
  628. private static readonly object IsActivatedChangedEvent = new object();
  629. public event EventHandler IsActivatedChanged
  630. {
  631. add { Events.AddHandler(IsActivatedChangedEvent, value); }
  632. remove { Events.RemoveHandler(IsActivatedChangedEvent, value); }
  633. }
  634. protected virtual void OnIsActivatedChanged(EventArgs e)
  635. {
  636. EventHandler handler = (EventHandler)Events[IsActivatedChangedEvent];
  637. if (handler != null)
  638. handler(this, e);
  639. }
  640. private static readonly object IsActiveDocumentPaneChangedEvent = new object();
  641. public event EventHandler IsActiveDocumentPaneChanged
  642. {
  643. add { Events.AddHandler(IsActiveDocumentPaneChangedEvent, value); }
  644. remove { Events.RemoveHandler(IsActiveDocumentPaneChangedEvent, value); }
  645. }
  646. protected virtual void OnIsActiveDocumentPaneChanged(EventArgs e)
  647. {
  648. EventHandler handler = (EventHandler)Events[IsActiveDocumentPaneChangedEvent];
  649. if (handler != null)
  650. handler(this, e);
  651. }
  652. public DockWindow DockWindow
  653. {
  654. get { return (m_nestedDockingStatus.NestedPanes == null) ? null : m_nestedDockingStatus.NestedPanes.Container as DockWindow; }
  655. set
  656. {
  657. DockWindow oldValue = DockWindow;
  658. if (oldValue == value)
  659. return;
  660. DockTo(value);
  661. }
  662. }
  663. public FloatWindow FloatWindow
  664. {
  665. get { return (m_nestedDockingStatus.NestedPanes == null) ? null : m_nestedDockingStatus.NestedPanes.Container as FloatWindow; }
  666. set
  667. {
  668. FloatWindow oldValue = FloatWindow;
  669. if (oldValue == value)
  670. return;
  671. DockTo(value);
  672. }
  673. }
  674. private NestedDockingStatus m_nestedDockingStatus;
  675. public NestedDockingStatus NestedDockingStatus
  676. {
  677. get { return m_nestedDockingStatus; }
  678. }
  679. private bool m_isFloat;
  680. public bool IsFloat
  681. {
  682. get { return m_isFloat; }
  683. }
  684. public INestedPanesContainer NestedPanesContainer
  685. {
  686. get
  687. {
  688. if (NestedDockingStatus.NestedPanes == null)
  689. return null;
  690. else
  691. return NestedDockingStatus.NestedPanes.Container;
  692. }
  693. }
  694. private DockState m_dockState = DockState.Unknown;
  695. public DockState DockState
  696. {
  697. get { return m_dockState; }
  698. set
  699. {
  700. SetDockState(value);
  701. }
  702. }
  703. public DockPane SetDockState(DockState value)
  704. {
  705. if (value == DockState.Unknown || value == DockState.Hidden)
  706. throw new InvalidOperationException(Strings.DockPane_SetDockState_InvalidState);
  707. if ((value == DockState.Float) == this.IsFloat)
  708. {
  709. InternalSetDockState(value);
  710. return this;
  711. }
  712. if (DisplayingContents.Count == 0)
  713. return null;
  714. IDockContent firstContent = null;
  715. for (int i=0; i<DisplayingContents.Count; i++)
  716. {
  717. IDockContent content = DisplayingContents[i];
  718. if (content.DockHandler.IsDockStateValid(value))
  719. {
  720. firstContent = content;
  721. break;
  722. }
  723. }
  724. if (firstContent == null)
  725. return null;
  726. firstContent.DockHandler.DockState = value;
  727. DockPane pane = firstContent.DockHandler.Pane;
  728. DockPanel.SuspendLayout(true);
  729. for (int i=0; i<DisplayingContents.Count; i++)
  730. {
  731. IDockContent content = DisplayingContents[i];
  732. if (content.DockHandler.IsDockStateValid(value))
  733. content.DockHandler.Pane = pane;
  734. }
  735. DockPanel.ResumeLayout(true, true);
  736. return pane;
  737. }
  738. private void InternalSetDockState(DockState value)
  739. {
  740. if (m_dockState == value)
  741. return;
  742. DockState oldDockState = m_dockState;
  743. INestedPanesContainer oldContainer = NestedPanesContainer;
  744. m_dockState = value;
  745. SuspendRefreshStateChange();
  746.             IDockContent contentFocused = GetFocusedContent();
  747.             if (contentFocused != null)
  748.                 DockPanel.SaveFocus();
  749.             if (!IsFloat)
  750.                 DockWindow = DockPanel.DockWindows[DockState];
  751.             else if (FloatWindow == null)
  752.                 FloatWindow = DockPanel.FloatWindowFactory.CreateFloatWindow(DockPanel, this);
  753.             if (contentFocused != null)
  754.                 DockPanel.ContentFocusManager.Activate(contentFocused);
  755. ResumeRefreshStateChange(oldContainer, oldDockState);
  756.         }
  757. private int m_countRefreshStateChange = 0;
  758. private void SuspendRefreshStateChange()
  759. {
  760. m_countRefreshStateChange ++;
  761. DockPanel.SuspendLayout(true);
  762. }
  763. private void ResumeRefreshStateChange()
  764. {
  765. m_countRefreshStateChange --;
  766. System.Diagnostics.Debug.Assert(m_countRefreshStateChange >= 0);
  767. DockPanel.ResumeLayout(true, true);
  768. }
  769. private bool IsRefreshStateChangeSuspended
  770. {
  771. get { return m_countRefreshStateChange != 0; }
  772. }
  773. private void ResumeRefreshStateChange(INestedPanesContainer oldContainer, DockState oldDockState)
  774. {
  775. ResumeRefreshStateChange();
  776. RefreshStateChange(oldContainer, oldDockState);
  777. }
  778. private void RefreshStateChange(INestedPanesContainer oldContainer, DockState oldDockState)
  779. {
  780. lock (this)
  781. {
  782. if (IsRefreshStateChangeSuspended)
  783. return;
  784. SuspendRefreshStateChange();
  785. }
  786.             DockPanel.SuspendLayout(true);
  787.             IDockContent contentFocused = GetFocusedContent();
  788.             if (contentFocused != null)
  789.                 DockPanel.SaveFocus();
  790. SetParent();
  791. if (ActiveContent != null)
  792. ActiveContent.DockHandler.SetDockState(ActiveContent.DockHandler.IsHidden, DockState, ActiveContent.DockHandler.Pane);
  793. foreach (IDockContent content in Contents)
  794. {
  795. if (content.DockHandler.Pane == this)
  796. content.DockHandler.SetDockState(content.DockHandler.IsHidden, DockState, content.DockHandler.Pane);
  797. }
  798. if (oldContainer != null)
  799. {
  800.                 Control oldContainerControl = (Control)oldContainer;
  801. if (oldContainer.DockState == oldDockState && !oldContainerControl.IsDisposed)
  802. oldContainerControl.PerformLayout();
  803. }
  804. if (DockHelper.IsDockStateAutoHide(oldDockState))
  805. DockPanel.RefreshActiveAutoHideContent();
  806. if (NestedPanesContainer.DockState == DockState)
  807. ((Control)NestedPanesContainer).PerformLayout();
  808. if (DockHelper.IsDockStateAutoHide(DockState))
  809. DockPanel.RefreshActiveAutoHideContent();
  810. if (DockHelper.IsDockStateAutoHide(oldDockState) ||
  811. DockHelper.IsDockStateAutoHide(DockState))
  812. {
  813. DockPanel.RefreshAutoHideStrip();
  814. DockPanel.PerformLayout();
  815. }
  816. ResumeRefreshStateChange();
  817.             if (contentFocused != null)
  818.                 contentFocused.DockHandler.Activate();
  819.             DockPanel.ResumeLayout(true, true);
  820.             if (oldDockState != DockState)
  821.                 OnDockStateChanged(EventArgs.Empty);
  822. }
  823.         private IDockContent GetFocusedContent()
  824.         {
  825.             IDockContent contentFocused = null;
  826.             foreach (IDockContent content in Contents)
  827.             {
  828.                 if (content.DockHandler.Form.ContainsFocus)
  829.                 {
  830.                     contentFocused = content;
  831.                     break;
  832.                 }
  833.             }
  834.             return contentFocused;
  835.         }
  836. public DockPane DockTo(INestedPanesContainer container)
  837. {
  838. if (container == null)
  839. throw new InvalidOperationException(Strings.DockPane_DockTo_NullContainer);
  840. DockAlignment alignment;
  841. if (container.DockState == DockState.DockLeft || container.DockState == DockState.DockRight)
  842. alignment = DockAlignment.Bottom;
  843. else
  844. alignment = DockAlignment.Right;
  845. return DockTo(container, container.NestedPanes.GetDefaultPreviousPane(this), alignment, 0.5);
  846. }
  847. public DockPane DockTo(INestedPanesContainer container, DockPane previousPane, DockAlignment alignment, double proportion)
  848. {
  849. if (container == null)
  850. throw new InvalidOperationException(Strings.DockPane_DockTo_NullContainer);
  851. if (container.IsFloat == this.IsFloat)
  852. {
  853. InternalAddToDockList(container, previousPane, alignment, proportion);
  854. return this;
  855. }
  856. IDockContent firstContent = GetFirstContent(container.DockState);
  857. if (firstContent == null)
  858. return null;
  859. DockPane pane;
  860. DockPanel.DummyContent.DockPanel = DockPanel;
  861. if (container.IsFloat)
  862. pane = DockPanel.DockPaneFactory.CreateDockPane(DockPanel.DummyContent, (FloatWindow)container, true);
  863. else
  864. pane = DockPanel.DockPaneFactory.CreateDockPane(DockPanel.DummyContent, container.DockState, true);
  865. pane.DockTo(container, previousPane, alignment, proportion);
  866. SetVisibleContentsToPane(pane);
  867. DockPanel.DummyContent.DockPanel = null;
  868. return pane;
  869. }
  870. private void SetVisibleContentsToPane(DockPane pane)
  871. {
  872. SetVisibleContentsToPane(pane, ActiveContent);
  873. }
  874. private void SetVisibleContentsToPane(DockPane pane, IDockContent activeContent)
  875. {
  876. for (int i=0; i<DisplayingContents.Count; i++)
  877. {
  878. IDockContent content = DisplayingContents[i];
  879. if (content.DockHandler.IsDockStateValid(pane.DockState))
  880. {
  881. content.DockHandler.Pane = pane;
  882. i--;
  883. }
  884. }
  885.             if (activeContent.DockHandler.Pane == pane)
  886.     pane.ActiveContent = activeContent;
  887. }
  888. private void InternalAddToDockList(INestedPanesContainer container, DockPane prevPane, DockAlignment alignment, double proportion)
  889. {
  890. if ((container.DockState == DockState.Float) != IsFloat)
  891. throw new InvalidOperationException(Strings.DockPane_DockTo_InvalidContainer);
  892. int count = container.NestedPanes.Count;
  893. if (container.NestedPanes.Contains(this))
  894. count --;
  895. if (prevPane == null && count > 0)
  896. throw new InvalidOperationException(Strings.DockPane_DockTo_NullPrevPane);
  897. if (prevPane != null && !container.NestedPanes.Contains(prevPane))
  898. throw new InvalidOperationException(Strings.DockPane_DockTo_NoPrevPane);
  899. if (prevPane == this)
  900. throw new InvalidOperationException(Strings.DockPane_DockTo_SelfPrevPane);
  901. INestedPanesContainer oldContainer = NestedPanesContainer;
  902. DockState oldDockState = DockState;
  903. container.NestedPanes.Add(this);
  904. NestedDockingStatus.SetStatus(container.NestedPanes, prevPane, alignment, proportion);
  905. if (DockHelper.IsDockWindowState(DockState))
  906. m_dockState = container.DockState;
  907. RefreshStateChange(oldContainer, oldDockState);
  908. }
  909. public void SetNestedDockingProportion(double proportion)
  910. {
  911. NestedDockingStatus.SetStatus(NestedDockingStatus.NestedPanes, NestedDockingStatus.PreviousPane, NestedDockingStatus.Alignment, proportion);
  912. if (NestedPanesContainer != null)
  913. ((Control)NestedPanesContainer).PerformLayout();
  914. }
  915. public DockPane Float()
  916. {
  917.             DockPanel.SuspendLayout(true);
  918. IDockContent activeContent = ActiveContent;
  919. DockPane floatPane = GetFloatPaneFromContents();
  920. if (floatPane == null)
  921. {
  922. IDockContent firstContent = GetFirstContent(DockState.Float);
  923.                 if (firstContent == null)
  924.                 {
  925.                     DockPanel.ResumeLayout(true, true);
  926.                     return null;
  927.                 }
  928. floatPane = DockPanel.DockPaneFactory.CreateDockPane(firstContent,DockState.Float, true);
  929. }
  930. SetVisibleContentsToPane(floatPane, activeContent);
  931.             DockPanel.ResumeLayout(true, true);
  932. return floatPane;
  933. }
  934. private DockPane GetFloatPaneFromContents()
  935. {
  936. DockPane floatPane = null;
  937. for (int i=0; i<DisplayingContents.Count; i++)
  938. {
  939. IDockContent content = DisplayingContents[i];
  940. if (!content.DockHandler.IsDockStateValid(DockState.Float))
  941. continue;
  942. if (floatPane != null && content.DockHandler.FloatPane != floatPane)
  943. return null;
  944. else
  945. floatPane = content.DockHandler.FloatPane;
  946. }
  947. return floatPane;
  948. }
  949. private IDockContent GetFirstContent(DockState dockState)
  950. {
  951. for (int i=0; i<DisplayingContents.Count; i++)
  952. {
  953. IDockContent content = DisplayingContents[i];
  954. if (content.DockHandler.IsDockStateValid(dockState))
  955. return content;
  956. }
  957. return null;
  958. }
  959. public void RestoreToPanel()
  960. {
  961.             DockPanel.SuspendLayout(true);
  962. IDockContent activeContent = DockPanel.ActiveContent;
  963. for (int i=DisplayingContents.Count-1; i>=0; i--)
  964. {
  965. IDockContent content = DisplayingContents[i];
  966.                 if (content.DockHandler.CheckDockState(false) != DockState.Unknown)
  967.     content.DockHandler.IsFloat = false;
  968. }
  969.             DockPanel.ResumeLayout(true, true);
  970. }
  971.         [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
  972.         protected override void WndProc(ref Message m)
  973.         {
  974.             if (m.Msg == (int)Win32.Msgs.WM_MOUSEACTIVATE)
  975.                 Activate();
  976.             base.WndProc(ref m);
  977.         }
  978.         #region IDockDragSource Members
  979.         #region IDragSource Members
  980.         Control IDragSource.DragControl
  981.         {
  982.             get { return this; }
  983.         }
  984.         #endregion
  985.         bool IDockDragSource.IsDockStateValid(DockState dockState)
  986.         {
  987.             return IsDockStateValid(dockState);
  988.         }
  989.         bool IDockDragSource.CanDockTo(DockPane pane)
  990.         {
  991.             if (!IsDockStateValid(pane.DockState))
  992.                 return false;
  993.             if (pane == this)
  994.                 return false;
  995.             return true;
  996.         }
  997.         Rectangle IDockDragSource.BeginDrag(Point ptMouse)
  998.         {
  999.             Point location = PointToScreen(new Point(0, 0));
  1000.             Size size;
  1001.             DockPane floatPane = ActiveContent.DockHandler.FloatPane;
  1002.             if (DockState == DockState.Float || floatPane == null || floatPane.FloatWindow.NestedPanes.Count != 1)
  1003.                 size = DockPanel.DefaultFloatWindowSize;
  1004.             else
  1005.                 size = floatPane.FloatWindow.Size;
  1006.             if (ptMouse.X > location.X + size.Width)
  1007.                 location.X += ptMouse.X - (location.X + size.Width) + Measures.SplitterSize;
  1008.             return new Rectangle(location, size);
  1009.         }
  1010.         public void FloatAt(Rectangle floatWindowBounds)
  1011.         {
  1012.             if (FloatWindow == null || FloatWindow.NestedPanes.Count != 1)
  1013.                 FloatWindow = DockPanel.FloatWindowFactory.CreateFloatWindow(DockPanel, this, floatWindowBounds);
  1014.             else
  1015.                 FloatWindow.Bounds = floatWindowBounds;
  1016.             DockState = DockState.Float;
  1017.         }
  1018.         public void DockTo(DockPane pane, DockStyle dockStyle, int contentIndex)
  1019.         {
  1020.             if (dockStyle == DockStyle.Fill)
  1021.             {
  1022.                 IDockContent activeContent = ActiveContent;
  1023.                 for (int i = Contents.Count - 1; i >= 0; i--)
  1024.                 {
  1025.                     IDockContent c = Contents[i];
  1026.                     if (c.DockHandler.DockState == DockState)
  1027.                     {
  1028.                         c.DockHandler.Pane = pane;
  1029.                         if (contentIndex != -1)
  1030.                             pane.SetContentIndex(c, contentIndex);
  1031.                     }
  1032.                 }
  1033.                 pane.ActiveContent = activeContent;
  1034.             }
  1035.             else
  1036.             {
  1037.                 if (dockStyle == DockStyle.Left)
  1038.                     DockTo(pane.NestedPanesContainer, pane, DockAlignment.Left, 0.5);
  1039.                 else if (dockStyle == DockStyle.Right)
  1040.                     DockTo(pane.NestedPanesContainer, pane, DockAlignment.Right, 0.5);
  1041.                 else if (dockStyle == DockStyle.Top)
  1042.                     DockTo(pane.NestedPanesContainer, pane, DockAlignment.Top, 0.5);
  1043.                 else if (dockStyle == DockStyle.Bottom)
  1044.                     DockTo(pane.NestedPanesContainer, pane, DockAlignment.Bottom, 0.5);
  1045.                 DockState = pane.DockState;
  1046.             }
  1047.         }
  1048.         public void DockTo(DockPanel panel, DockStyle dockStyle)
  1049.         {
  1050.             if (panel != DockPanel)
  1051.                 throw new ArgumentException(Strings.IDockDragSource_DockTo_InvalidPanel, "panel");
  1052.             if (dockStyle == DockStyle.Top)
  1053.                 DockState = DockState.DockTop;
  1054.             else if (dockStyle == DockStyle.Bottom)
  1055.                 DockState = DockState.DockBottom;
  1056.             else if (dockStyle == DockStyle.Left)
  1057.                 DockState = DockState.DockLeft;
  1058.             else if (dockStyle == DockStyle.Right)
  1059.                 DockState = DockState.DockRight;
  1060.             else if (dockStyle == DockStyle.Fill)
  1061.                 DockState = DockState.Document;
  1062.         }
  1063.         #endregion
  1064.     }
  1065. }