/*------------------------------------------------------------------------- * 功能描述:RevitModelessWindow * 作者:xulisong * 创建时间: 2019/6/4 10:52:55 * 版本号:v1.0 * -------------------------------------------------------------------------*/ using System; using FWindSoft.Common; using FWindSoft.Data; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Controls; using System.Windows.Media; using FWindSoft.WindowsApi; using System.Windows; namespace FWindSoft.Revit.Window { public class RevitModelessWindow:RevitWindow { public RevitModelessWindow() { RevitCommand = new IdlingEventCommand(); Activated += RevitModelessWindow_Activated; } #region 内部事件相关 protected override void OnLoaded(RoutedEventArgs e) { base.OnLoaded(e); RevitCommand.Register(ExternalApplication.CurrentApp); } protected override void OnClosed(EventArgs e) { base.OnClosed(e); RevitCommand.Unregister(ExternalApplication.CurrentApp); } private void RevitModelessWindow_Activated(object sender, System.EventArgs e) { Activated -= RevitModelessWindow_Activated; ActiveRevitForm(); //RegistCommand(); } #endregion protected MomentVariable IsAppCancel { get; set; } = new MomentVariable(); /// /// 激活Revit主窗体 /// protected void ActiveRevitForm() { WinAPI.SetForegroundWindow(App.MainHandle); } /// /// 发一次Esc键命令 /// private void SendEscCmd() { ActiveRevitForm(); InputUtil.KeyPressEvent(Keys.Escape); } /// /// 发两次Esc键命令 /// protected void SendEscCmdDbl() { ActiveRevitForm(); InputUtil.KeyPressEvent(Keys.Escape); InputUtil.KeyPressEvent(Keys.Escape); } protected virtual void ReExecute() { IsAppCancel.Value = true; SendEscCmd(); } #region 细节相关处理 private void AdaptComboBoxPopup(Visual visual) { //避免下拉框等弹出窗体,鼠标滑动到弹出部分时造成鼠标状态判定失败 for (int i = 0; i < VisualTreeHelper.GetChildrenCount(visual); i++) { Visual childVisual = (Visual)VisualTreeHelper.GetChild(visual, i); if (childVisual != null) { if (childVisual is ComboBox) { var cmb = childVisual as ComboBox; cmb.DropDownOpened += (o,e) => PauseWatchMouse = true; cmb.DropDownClosed += (o, e) => PauseWatchMouse = false; } AdaptComboBoxPopup(childVisual); } } } public bool ValueChanged { get; private set; } public void RaiseValueChanged() { ValueChanged = true; } #endregion #region 控件值发生变化监控 /* * 1、当命令生效之后,记录历史值。比较历史值和当前值,判断值是否改变 * 2、控件可能动态增加或减少,不适合使用监测命令的方式去监控 */ #endregion protected IdlingEventCommand RevitCommand { get; set; } protected virtual HandlerResult Execute(RevitEventArgs args) { return HandlerResult.None; } protected virtual void AfterExecute(RevitEventArgs args) { } protected RevitHandler CreateHandler(Func handler, Action callBack,bool allowWhile) { RevitHandler revitHandler = new RevitHandler(); revitHandler.Executing += (sender, args) => { TaskCompletionSource tcs = null; if (callBack != null) { tcs = new TaskCompletionSource(); tcs.Task.ContinueWith((t) => callBack(args)); } try { do { args.Result = handler(args); if (args.Result == HandlerResult.Abort) { //终止则退出 break; } if (!IsAppCancel.Value) { break; } } while (allowWhile&&args.Result == HandlerResult.Successed); } finally { this.Close(); tcs?.SetResult(null); } }; return revitHandler; } protected void RegistCommand(bool isWhile) { IdlingCommand command = new IdlingCommand(CreateHandler(Execute, AfterExecute, isWhile)); RevitCommand.Execute(command); } /// /// 标识参数改变不重新执行命令,但激活revit主窗体 /// public bool ChangedNoReExecute { get; set; } /// /// 界面的属性值是否改变 /// /// protected virtual bool IsPropertyChanged() { //对比当前值与历史值 return true; } #region 鼠标监控 protected override void OnMouseLeaveT() { if (PauseWatchMouse) return; base.OnMouseLeaveT(); bool isParamsChanged = IsPropertyChanged(); if (ChangedNoReExecute || !isParamsChanged) { ActiveRevitForm(); } else { try { ReExecute(); } catch { } } } protected override void OnMouseEnterT() { base.OnMouseEnterT(); //记录当前值 //WatchControlData(); } #endregion } }