LayoutAnchorableItem.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  1. /*************************************************************************************
  2. Extended WPF Toolkit
  3. Copyright (C) 2007-2013 Xceed Software Inc.
  4. This program is provided to you under the terms of the Microsoft Public
  5. License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license
  6. For more features, controls, and fast professional support,
  7. pick up the Plus Edition at http://xceed.com/wpf_toolkit
  8. Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids
  9. ***********************************************************************************/
  10. using System;
  11. using System.Collections.Generic;
  12. using System.Linq;
  13. using System.Text;
  14. using Xceed.Wpf.AvalonDock.Layout;
  15. using System.Windows.Input;
  16. using System.Windows;
  17. using Xceed.Wpf.AvalonDock.Commands;
  18. using System.Windows.Data;
  19. namespace Xceed.Wpf.AvalonDock.Controls
  20. {
  21. public class LayoutAnchorableItem : LayoutItem
  22. {
  23. LayoutAnchorable _anchorable;
  24. internal LayoutAnchorableItem()
  25. {
  26. }
  27. internal override void Attach(LayoutContent model)
  28. {
  29. _anchorable = model as LayoutAnchorable;
  30. _anchorable.IsVisibleChanged += new EventHandler(_anchorable_IsVisibleChanged);
  31. base.Attach(model);
  32. }
  33. internal override void Detach()
  34. {
  35. _anchorable.IsVisibleChanged -= new EventHandler(_anchorable_IsVisibleChanged);
  36. _anchorable = null;
  37. base.Detach();
  38. }
  39. protected override void Close()
  40. {
  41. var dockingManager = _anchorable.Root.Manager;
  42. dockingManager._ExecuteCloseCommand(_anchorable);
  43. }
  44. ICommand _defaultHideCommand;
  45. ICommand _defaultAutoHideCommand;
  46. ICommand _defaultDockCommand;
  47. protected override void InitDefaultCommands()
  48. {
  49. _defaultHideCommand = new RelayCommand((p) => ExecuteHideCommand(p), (p) => CanExecuteHideCommand(p));
  50. _defaultAutoHideCommand = new RelayCommand((p) => ExecuteAutoHideCommand(p), (p) => CanExecuteAutoHideCommand(p));
  51. _defaultDockCommand = new RelayCommand((p) => ExecuteDockCommand(p), (p) => CanExecuteDockCommand(p));
  52. base.InitDefaultCommands();
  53. }
  54. protected override void ClearDefaultBindings()
  55. {
  56. if (HideCommand == _defaultHideCommand)
  57. BindingOperations.ClearBinding(this, HideCommandProperty);
  58. if (AutoHideCommand == _defaultAutoHideCommand)
  59. BindingOperations.ClearBinding(this, AutoHideCommandProperty);
  60. if (DockCommand == _defaultDockCommand)
  61. BindingOperations.ClearBinding(this, DockCommandProperty);
  62. base.ClearDefaultBindings();
  63. }
  64. protected override void SetDefaultBindings()
  65. {
  66. if (HideCommand == null)
  67. HideCommand = _defaultHideCommand;
  68. if (AutoHideCommand == null)
  69. AutoHideCommand = _defaultAutoHideCommand;
  70. if (DockCommand == null)
  71. DockCommand = _defaultDockCommand;
  72. Visibility = _anchorable.IsVisible ? Visibility.Visible : System.Windows.Visibility.Hidden;
  73. base.SetDefaultBindings();
  74. }
  75. #region HideCommand
  76. /// <summary>
  77. /// HideCommand Dependency Property
  78. /// </summary>
  79. public static readonly DependencyProperty HideCommandProperty =
  80. DependencyProperty.Register("HideCommand", typeof(ICommand), typeof(LayoutAnchorableItem),
  81. new FrameworkPropertyMetadata(null,
  82. new PropertyChangedCallback(OnHideCommandChanged),
  83. new CoerceValueCallback(CoerceHideCommandValue)));
  84. /// <summary>
  85. /// Gets or sets the HideCommand property. This dependency property
  86. /// indicates the command to execute when an anchorable is hidden.
  87. /// </summary>
  88. public ICommand HideCommand
  89. {
  90. get { return (ICommand)GetValue(HideCommandProperty); }
  91. set { SetValue(HideCommandProperty, value); }
  92. }
  93. /// <summary>
  94. /// Handles changes to the HideCommand property.
  95. /// </summary>
  96. private static void OnHideCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  97. {
  98. ((LayoutAnchorableItem)d).OnHideCommandChanged(e);
  99. }
  100. /// <summary>
  101. /// Provides derived classes an opportunity to handle changes to the HideCommand property.
  102. /// </summary>
  103. protected virtual void OnHideCommandChanged(DependencyPropertyChangedEventArgs e)
  104. {
  105. }
  106. /// <summary>
  107. /// Coerces the HideCommand value.
  108. /// </summary>
  109. private static object CoerceHideCommandValue(DependencyObject d, object value)
  110. {
  111. return value;
  112. }
  113. private bool CanExecuteHideCommand(object parameter)
  114. {
  115. if (LayoutElement == null)
  116. return false;
  117. return _anchorable.CanHide;
  118. }
  119. private void ExecuteHideCommand(object parameter)
  120. {
  121. if (_anchorable != null && _anchorable.Root != null && _anchorable.Root.Manager != null)
  122. _anchorable.Root.Manager._ExecuteHideCommand(_anchorable);
  123. }
  124. #endregion
  125. #region AutoHideCommand
  126. /// <summary>
  127. /// AutoHideCommand Dependency Property
  128. /// </summary>
  129. public static readonly DependencyProperty AutoHideCommandProperty =
  130. DependencyProperty.Register("AutoHideCommand", typeof(ICommand), typeof(LayoutAnchorableItem),
  131. new FrameworkPropertyMetadata(null,
  132. new PropertyChangedCallback(OnAutoHideCommandChanged),
  133. new CoerceValueCallback(CoerceAutoHideCommandValue)));
  134. /// <summary>
  135. /// Gets or sets the AutoHideCommand property. This dependency property
  136. /// indicates the command to execute when user click the auto hide button.
  137. /// </summary>
  138. /// <remarks>By default this command toggles auto hide state for an anchorable.</remarks>
  139. public ICommand AutoHideCommand
  140. {
  141. get { return (ICommand)GetValue(AutoHideCommandProperty); }
  142. set { SetValue(AutoHideCommandProperty, value); }
  143. }
  144. /// <summary>
  145. /// Handles changes to the AutoHideCommand property.
  146. /// </summary>
  147. private static void OnAutoHideCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  148. {
  149. ((LayoutAnchorableItem)d).OnAutoHideCommandChanged(e);
  150. }
  151. /// <summary>
  152. /// Provides derived classes an opportunity to handle changes to the AutoHideCommand property.
  153. /// </summary>
  154. protected virtual void OnAutoHideCommandChanged(DependencyPropertyChangedEventArgs e)
  155. {
  156. }
  157. /// <summary>
  158. /// Coerces the AutoHideCommand value.
  159. /// </summary>
  160. private static object CoerceAutoHideCommandValue(DependencyObject d, object value)
  161. {
  162. return value;
  163. }
  164. private bool CanExecuteAutoHideCommand(object parameter)
  165. {
  166. if (LayoutElement == null)
  167. return false;
  168. if (LayoutElement.FindParent<LayoutAnchorableFloatingWindow>() != null)
  169. return false;//is floating
  170. return _anchorable.CanAutoHide;
  171. }
  172. private void ExecuteAutoHideCommand(object parameter)
  173. {
  174. if (_anchorable != null && _anchorable.Root != null && _anchorable.Root.Manager != null)
  175. _anchorable.Root.Manager._ExecuteAutoHideCommand(_anchorable);
  176. }
  177. #endregion
  178. #region DockCommand
  179. /// <summary>
  180. /// DockCommand Dependency Property
  181. /// </summary>
  182. public static readonly DependencyProperty DockCommandProperty =
  183. DependencyProperty.Register("DockCommand", typeof(ICommand), typeof(LayoutAnchorableItem),
  184. new FrameworkPropertyMetadata(null,
  185. new PropertyChangedCallback(OnDockCommandChanged),
  186. new CoerceValueCallback(CoerceDockCommandValue)));
  187. /// <summary>
  188. /// Gets or sets the DockCommand property. This dependency property
  189. /// indicates the command to execute when user click the Dock button.
  190. /// </summary>
  191. /// <remarks>By default this command moves the anchorable inside the container pane which previously hosted the object.</remarks>
  192. public ICommand DockCommand
  193. {
  194. get { return (ICommand)GetValue(DockCommandProperty); }
  195. set { SetValue(DockCommandProperty, value); }
  196. }
  197. /// <summary>
  198. /// Handles changes to the DockCommand property.
  199. /// </summary>
  200. private static void OnDockCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  201. {
  202. ((LayoutAnchorableItem)d).OnDockCommandChanged(e);
  203. }
  204. /// <summary>
  205. /// Provides derived classes an opportunity to handle changes to the DockCommand property.
  206. /// </summary>
  207. protected virtual void OnDockCommandChanged(DependencyPropertyChangedEventArgs e)
  208. {
  209. }
  210. /// <summary>
  211. /// Coerces the DockCommand value.
  212. /// </summary>
  213. private static object CoerceDockCommandValue(DependencyObject d, object value)
  214. {
  215. return value;
  216. }
  217. private bool CanExecuteDockCommand(object parameter)
  218. {
  219. if (LayoutElement == null)
  220. return false;
  221. return LayoutElement.FindParent<LayoutAnchorableFloatingWindow>() != null;
  222. }
  223. private void ExecuteDockCommand(object parameter)
  224. {
  225. LayoutElement.Root.Manager._ExecuteDockCommand(_anchorable);
  226. }
  227. #endregion
  228. #region Visibility
  229. ReentrantFlag _visibilityReentrantFlag = new ReentrantFlag();
  230. protected override void OnVisibilityChanged()
  231. {
  232. if (_anchorable != null && _anchorable.Root != null)
  233. {
  234. if (_visibilityReentrantFlag.CanEnter)
  235. {
  236. using (_visibilityReentrantFlag.Enter())
  237. {
  238. if (Visibility == System.Windows.Visibility.Hidden)
  239. _anchorable.Hide(false);
  240. else if (Visibility == System.Windows.Visibility.Visible)
  241. _anchorable.Show();
  242. }
  243. }
  244. }
  245. base.OnVisibilityChanged();
  246. }
  247. void _anchorable_IsVisibleChanged(object sender, EventArgs e)
  248. {
  249. if (_anchorable != null && _anchorable.Root != null)
  250. {
  251. if (_visibilityReentrantFlag.CanEnter)
  252. {
  253. using (_visibilityReentrantFlag.Enter())
  254. {
  255. if (_anchorable.IsVisible)
  256. Visibility = Visibility.Visible;
  257. else
  258. Visibility = Visibility.Hidden;
  259. }
  260. }
  261. }
  262. }
  263. #endregion
  264. #region CanHide
  265. /// <summary>
  266. /// CanHide Dependency Property
  267. /// </summary>
  268. public static readonly DependencyProperty CanHideProperty =
  269. DependencyProperty.Register("CanHide", typeof(bool), typeof(LayoutAnchorableItem),
  270. new FrameworkPropertyMetadata((bool)true,
  271. new PropertyChangedCallback(OnCanHideChanged)));
  272. /// <summary>
  273. /// Gets or sets the CanHide property. This dependency property
  274. /// indicates if user can hide the anchorable item.
  275. /// </summary>
  276. public bool CanHide
  277. {
  278. get { return (bool)GetValue(CanHideProperty); }
  279. set { SetValue(CanHideProperty, value); }
  280. }
  281. /// <summary>
  282. /// Handles changes to the CanHide property.
  283. /// </summary>
  284. private static void OnCanHideChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  285. {
  286. ((LayoutAnchorableItem)d).OnCanHideChanged(e);
  287. }
  288. /// <summary>
  289. /// Provides derived classes an opportunity to handle changes to the CanHide property.
  290. /// </summary>
  291. protected virtual void OnCanHideChanged(DependencyPropertyChangedEventArgs e)
  292. {
  293. if (_anchorable != null)
  294. _anchorable.CanHide = (bool)e.NewValue;
  295. }
  296. #endregion
  297. }
  298. }