RevitModelessWindow.cs 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. /*-------------------------------------------------------------------------
  2. * 功能描述:RevitModelessWindow
  3. * 作者:xulisong
  4. * 创建时间: 2019/6/4 10:52:55
  5. * 版本号:v1.0
  6. * -------------------------------------------------------------------------*/
  7. using System;
  8. using FWindSoft.Common;
  9. using FWindSoft.Data;
  10. using System.Linq;
  11. using System.Text;
  12. using System.Threading.Tasks;
  13. using System.Windows.Controls;
  14. using System.Windows.Media;
  15. using FWindSoft.WindowsApi;
  16. using System.Windows;
  17. namespace FWindSoft.Revit.Window
  18. {
  19. public class RevitModelessWindow:RevitWindow
  20. {
  21. public RevitModelessWindow()
  22. {
  23. RevitCommand = new IdlingEventCommand();
  24. Activated += RevitModelessWindow_Activated;
  25. }
  26. #region 内部事件相关
  27. protected override void OnLoaded(RoutedEventArgs e)
  28. {
  29. base.OnLoaded(e);
  30. RevitCommand.Register(ExternalApplication.CurrentApp);
  31. }
  32. protected override void OnClosed(EventArgs e)
  33. {
  34. base.OnClosed(e);
  35. RevitCommand.Unregister(ExternalApplication.CurrentApp);
  36. }
  37. private void RevitModelessWindow_Activated(object sender, System.EventArgs e)
  38. {
  39. Activated -= RevitModelessWindow_Activated;
  40. ActiveRevitForm();
  41. //RegistCommand();
  42. }
  43. #endregion
  44. protected MomentVariable<bool> IsAppCancel { get; set; } = new MomentVariable<bool>();
  45. /// <summary>
  46. /// 激活Revit主窗体
  47. /// </summary>
  48. protected void ActiveRevitForm()
  49. {
  50. WinAPI.SetForegroundWindow(App.MainHandle);
  51. }
  52. /// <summary>
  53. /// 发一次Esc键命令
  54. /// </summary>
  55. private void SendEscCmd()
  56. {
  57. ActiveRevitForm();
  58. InputUtil.KeyPressEvent(Keys.Escape);
  59. }
  60. /// <summary>
  61. /// 发两次Esc键命令
  62. /// </summary>
  63. protected void SendEscCmdDbl()
  64. {
  65. ActiveRevitForm();
  66. InputUtil.KeyPressEvent(Keys.Escape);
  67. InputUtil.KeyPressEvent(Keys.Escape);
  68. }
  69. protected virtual void ReExecute()
  70. {
  71. IsAppCancel.Value = true;
  72. SendEscCmd();
  73. }
  74. #region 细节相关处理
  75. private void AdaptComboBoxPopup(Visual visual)
  76. {
  77. //避免下拉框等弹出窗体,鼠标滑动到弹出部分时造成鼠标状态判定失败
  78. for (int i = 0; i < VisualTreeHelper.GetChildrenCount(visual); i++)
  79. {
  80. Visual childVisual = (Visual)VisualTreeHelper.GetChild(visual, i);
  81. if (childVisual != null)
  82. {
  83. if (childVisual is ComboBox)
  84. {
  85. var cmb = childVisual as ComboBox;
  86. cmb.DropDownOpened += (o,e) => PauseWatchMouse = true;
  87. cmb.DropDownClosed += (o, e) => PauseWatchMouse = false;
  88. }
  89. AdaptComboBoxPopup(childVisual);
  90. }
  91. }
  92. }
  93. public bool ValueChanged { get; private set; }
  94. public void RaiseValueChanged()
  95. {
  96. ValueChanged = true;
  97. }
  98. #endregion
  99. #region 控件值发生变化监控
  100. /*
  101. * 1、当命令生效之后,记录历史值。比较历史值和当前值,判断值是否改变
  102. * 2、控件可能动态增加或减少,不适合使用监测命令的方式去监控
  103. */
  104. #endregion
  105. protected IdlingEventCommand RevitCommand { get; set; }
  106. protected virtual HandlerResult Execute(RevitEventArgs args)
  107. {
  108. return HandlerResult.None;
  109. }
  110. protected virtual void AfterExecute(RevitEventArgs args)
  111. {
  112. }
  113. protected RevitHandler CreateHandler(Func<RevitEventArgs, HandlerResult> handler, Action<RevitEventArgs> callBack,bool allowWhile)
  114. {
  115. RevitHandler revitHandler = new RevitHandler();
  116. revitHandler.Executing += (sender, args) =>
  117. {
  118. TaskCompletionSource<object> tcs = null;
  119. if (callBack != null)
  120. {
  121. tcs = new TaskCompletionSource<object>();
  122. tcs.Task.ContinueWith((t) => callBack(args));
  123. }
  124. try
  125. {
  126. do
  127. {
  128. args.Result = handler(args);
  129. if (args.Result == HandlerResult.Abort)
  130. {
  131. //终止则退出
  132. break;
  133. }
  134. if (!IsAppCancel.Value)
  135. {
  136. break;
  137. }
  138. } while (allowWhile&&args.Result == HandlerResult.Successed);
  139. }
  140. finally
  141. {
  142. this.Close();
  143. tcs?.SetResult(null);
  144. }
  145. };
  146. return revitHandler;
  147. }
  148. protected void RegistCommand(bool isWhile)
  149. {
  150. IdlingCommand command = new IdlingCommand(CreateHandler(Execute, AfterExecute, isWhile));
  151. RevitCommand.Execute(command);
  152. }
  153. /// <summary>
  154. /// 标识参数改变不重新执行命令,但激活revit主窗体
  155. /// </summary>
  156. public bool ChangedNoReExecute { get; set; }
  157. /// <summary>
  158. /// 界面的属性值是否改变
  159. /// </summary>
  160. /// <returns></returns>
  161. protected virtual bool IsPropertyChanged()
  162. {
  163. //对比当前值与历史值
  164. return true;
  165. }
  166. #region 鼠标监控
  167. protected override void OnMouseLeaveT()
  168. {
  169. if (PauseWatchMouse) return;
  170. base.OnMouseLeaveT();
  171. bool isParamsChanged = IsPropertyChanged();
  172. if (ChangedNoReExecute || !isParamsChanged)
  173. {
  174. ActiveRevitForm();
  175. }
  176. else
  177. {
  178. try
  179. {
  180. ReExecute();
  181. }
  182. catch
  183. {
  184. }
  185. }
  186. }
  187. protected override void OnMouseEnterT()
  188. {
  189. base.OnMouseEnterT();
  190. //记录当前值
  191. //WatchControlData();
  192. }
  193. #endregion
  194. }
  195. }