revit二次开发 外部事件调用方法

    /// <summary>
    /// 外部事件应该在OnStartup事件中注册,
    /// 否则可能会无法执行
    /// </summary>
    class ExternalEventManagement
    {
        bool _register = false;
        Dictionary<ExternalEventType, IExternalEventHandlerExt> _dicEventHandler = null;
        Dictionary<ExternalEventType, ExternalEvent> _dicExternalEvent = null;
        ExternalEventManagement()
        {
            _dicEventHandler = new Dictionary<ExternalEventType, IExternalEventHandlerExt>();
            _dicExternalEvent = new Dictionary<ExternalEventType, ExternalEvent>();
        }
        public static readonly ExternalEventManagement Instance = new ExternalEventManagement();

        /// <summary>
        /// 外部事件必须在OnStartup事件中注册
        /// </summary>
        public void RegisterExternalEvent()
        {
            if (_register)
                throw new Exception("外部事件重复注册!!!");

            _register = true;

            var ass = System.Reflection.Assembly.GetExecutingAssembly();
            var externalEventTypes = ass.GetTypes().Where(o => o.GetInterfaces().Contains(typeof(IExternalEventHandlerExt)) &&
                o.GetCustomAttributes(typeof(ExternalEventAttribute), false).Length > 0);

            foreach (var item in externalEventTypes)
            {
                var handle = ass.CreateInstance(item.FullName) as IExternalEventHandlerExt;

                var attrs = item.GetCustomAttributes(typeof(ExternalEventAttribute), false);
                var exAttr = attrs.FirstOrDefault(o => o is ExternalEventAttribute);
                if (exAttr != null)
                {
                    var externalEventType = (exAttr as ExternalEventAttribute).ExternalEventType;
                    var externalEvent = ExternalEvent.Create(handle);

                    _dicEventHandler.Add(externalEventType, handle);
                    _dicExternalEvent.Add(externalEventType, externalEvent);
                }
                else
                {
#if DEBUG
                    System.Windows.MessageBox.Show(
                        string.Format("外部事物类型: {0} 未实现自动注册, 未添加ExternalEventAttribute特性.", handle.GetType().FullName),
                        "警告消息",
                        System.Windows.MessageBoxButton.OK,
                        System.Windows.MessageBoxImage.Error);
#endif
                }
            }
            Framework.App.Instance.Loger.Log("外部事件注册完成");
        }

        public void RaiseExternalEvent(ExternalEventType externalEventType, params object[] paramList)
        {
            System.Diagnostics.Debug.Assert(_dicExternalEvent.ContainsKey(externalEventType));

            _dicEventHandler[externalEventType].SetParams(paramList);

            _dicExternalEvent[externalEventType].Raise();
        }
    }

 

    /// <summary>
    /// 外部事务扩展
    /// </summary>
    public interface IExternalEventHandlerExt : IExternalEventHandler
    {
        /// <summary>
        /// 设置 外部事务参数
        /// </summary>
        /// <param name="paramList"></param>
        void SetParams(params object[] paramList);
    }
    /// <summary>
    /// 外部事件特性,用来自动注册
    /// 
    /// 外部事件一定是有空构造函数的类, 否则反射失败
    /// </summary>
    [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
    public class ExternalEventAttribute : Attribute
    {
        public ExternalEventType ExternalEventType { get; private set; }
        public ExternalEventAttribute(ExternalEventType externalEventType)
        {
            ExternalEventType = externalEventType;
        }
    }
    public enum ExternalEventType
    {
        /// <summary>
        /// 打开本地文件并激活显示
        /// </summary>
        eOpenFileDocument = 10,
        eExeCommand = 20,
    }
        [ExternalEvent(ExternalEventType.eExeCommand)]
        class ExternalEventHandler : IExternalEventHandlerExt
        {
            Action<UIApplication> _action = null;
            public void Execute(UIApplication app)
            {
                try
                {
                    _action.Invoke(app);
                }
                catch (Exception ex)
                {
                    App.Instance.Loger.Error(ex);
                    MessageBox.Show(ex.Message, "错误消息", MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }
            public string GetName()
            {
                return "ExternalEventHandler";
            }

            public void SetParams(params object[] paramList)
            {
                _action = paramList[0] as Action<UIApplication>;
            }
        }

外部事件主要使用场景是:在非模态框中对document进行写操作,因为在非revit主线程中开启事务会异常。

方法使用说明:

1、自定义类实现IExternalEventHandlerExt接口,并且关联ExternalEventAttribute特性

2、ExternalEventManagement.Instance.RegisterExternalEvent()注册,它会自动注册所有实现了IExternalEventHandlerExt接口的类

3、使用ExternalEventManagement.Instance.RaiseExternalEvent(xxx,xxx),启动外部事件,指定类型,还可以传递参数。

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值