DockPane.cs 45 KB

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