当前位置: 代码迷 >> C# >> 动态添加嘱托失败
  详细解决方案

动态添加嘱托失败

热度:111   发布时间:2016-05-05 04:34:44.0
动态添加委托失败

public class EventWrapper : EventDescriptor
    {
        object controlledObject;
        EventDescriptor controlledEvent;
        EventInfo eventInfo;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="controlledObject"></param>
        /// <param name="eventInfo"></param>
        public EventWrapper(object controlledObject, EventInfo eventInfo)
            : base(eventInfo.GetTargetEventName(), null)
        {
            this.controlledObject = controlledObject;
            this.eventInfo = eventInfo;

            foreach (EventDescriptor pd in TypeDescriptor.GetEvents(controlledObject))
            {
                if (pd.Name == eventInfo.SourceEvent)
                {
                    this.controlledEvent = pd;
                    break;
                }
            }
            if (this.controlledEvent == null)
                throw new System.InvalidOperationException("sourceEvent is not found in controlled object");
        }

        #region
        /// <summary>
        /// 
        /// </summary>
        /// <param name="component"></param>
        /// <param name="value"></param>
        public override void AddEventHandler(object component, Delegate value)
        {
            var ub = UndoRedoManager.GetUndoBufferFor(controlledObject as System.Windows.UIElement);
            ub.AddCommand(new ModifyGraphicsObject(controlledObject as System.Windows.UIElement));

            //System.Reflection.EventInfo eInfo = ComponentType.GetEvent(Name);
            //eInfo.AddEventHandler(controlledObject, value);
            controlledEvent.AddEventHandler(controlledObject, value);//这里添加失败怎么回事?

        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="component"></param>
        /// <param name="value"></param>
        public override void RemoveEventHandler(object component, Delegate value)
        {
            var ub = UndoRedoManager.GetUndoBufferFor(controlledObject as System.Windows.UIElement);
            ub.AddCommand(new ModifyGraphicsObject(controlledObject as System.Windows.UIElement));

            controlledEvent.RemoveEventHandler(controlledObject, value);
        }

        /// <summary>
        /// 
        /// </summary>
        public override Type ComponentType
        {
            get
            {
                return controlledEvent.ComponentType;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public override Type EventType
        {
            get
            {
                return controlledEvent.EventType;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public override bool IsMulticast
        {
            get { return controlledEvent.IsMulticast; }
        }

       
        #endregion
        /// <summary>
        /// 
        /// </summary>
        /// <param name="controlledObject"></param>
        /// <param name="eventInfo"></param>
        /// <returns></returns>
        public static bool CheckIfApplicable(object controlledObject, EventInfo eventInfo)
        {
            foreach (EventDescriptor pd in TypeDescriptor.GetEvents(controlledObject))
            {
                if (pd.Name == eventInfo.SourceEvent)
                    return true;
            }

            return false;
        }

        /// <summary>
        /// 
        /// </summary>
        public object ControlledObject
        {
            get { return controlledObject; }
        }
        /// <summary>
        /// 
        /// </summary>
        public EventDescriptor ControlledEvent
        {
            get { return controlledEvent; }
        }
        /// <summary>
        /// 
        /// </summary>
        internal EventInfo EventInfo
        {
            get { return eventInfo; }
        }
        /// <summary>
        /// 
        /// </summary>
        public override AttributeCollection Attributes
        {
            get
            {
                List<Attribute> attrs = new List<Attribute>();
                if (eventInfo.Editor != null && eventInfo.Editor.IsSubclassOf(typeof(System.Drawing.Design.UITypeEditor)))
                    attrs.Add(new EditorAttribute(eventInfo.Editor, typeof(System.Drawing.Design.UITypeEditor)));
                if (string.IsNullOrEmpty(eventInfo.Group) == false)
                    attrs.Add(new CategoryAttribute(eventInfo.Group));

                return new AttributeCollection(attrs.ToArray());
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public override string DisplayName
        {
            get
            {
                return eventInfo.GetTargetEventDisplayName();
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public override string Description
        {
            get
            {
                if (string.IsNullOrEmpty(eventInfo.Description))
                    return controlledEvent.Description;
                else
                    return eventInfo.Description;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public override bool IsBrowsable
        {
            get
            {
                return controlledEvent.IsBrowsable;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public override string Name
        {
            get
            {
                return eventInfo.GetTargetEventName();
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return DisplayName;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public Delegate GetBinding()
        {
            Delegate[] d =  GetObjectEventList(controlledObject, Name, ComponentType);
            if (d != null && d.Length > 0)
                return d[0];

            return null;
        }

        private Delegate[] GetObjectEventList(object p_Object, string p_EventName, Type p_EventType)
        {
            PropertyInfo _PropertyInfo = p_Object.GetType().GetProperty("Events", BindingFlags.Instance | BindingFlags.FlattenHierarchy | BindingFlags.IgnoreCase);

            PropertyInfo propertyInfo = p_Object.GetType().GetProperty("Events", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.IgnoreCase);
           
            if (_PropertyInfo != null)
            {
                object _EventList = _PropertyInfo.GetValue(p_Object, null);
                if (_EventList != null && _EventList is EventHandlerList)
                {
                    EventHandlerList _List = (EventHandlerList)_EventList;
                    FieldInfo _FieldInfo = p_EventType.GetField(p_EventName, BindingFlags.Static | BindingFlags.FlattenHierarchy | BindingFlags.IgnoreCase);
                    if (_FieldInfo == null) return null;
                    Delegate _ObjectDelegate = _List[_FieldInfo.GetValue(p_Object)];
                    if (_ObjectDelegate == null) return null;
                    return _ObjectDelegate.GetInvocationList();
                }
            }
            return null;
        }

    }


想动态添加委托,重写的AddEventHandler里添加委托失败,怎么回事?
------解决思路----------------------
报的什么错,事件委托和签名跟你传入的handler一致吗
------解决思路----------------------
其实就是Delegate[] GetObjectEventList这东西出问题了呗,放那么多无关代码都是迷惑人的
断点跟,看它到底在哪一句就变成null了
------解决思路----------------------
把代码和现象反复贴出来好几遍,是没有意义的
你先确定这个函数里到底执行到哪就出问题了
如果它一开始就出问题了,你还是重写方法吧
------解决思路----------------------
WPF 里面没有Events 这个你要DEBUG WPF的事件方法是啥,
WPF与WIN下不一样地。
------解决思路----------------------
引用:
Quote: 引用:

WPF 里面没有Events 这个你要DEBUG WPF的事件方法是啥,
WPF与WIN下不一样地。


引用:
WPF 里面没有Events 这个你要DEBUG WPF的事件方法是啥,
WPF与WIN下不一样地。


是的,你说得很对,winform控件的父类有 
protected EventHandlerList Events { get; }
而wpf没有,不知道wpf有没有类似于上面winform的Events 属性


木有的。控件的基类没提供事件集合。
------解决思路----------------------
WPF里UIElement采用的都是路由事件
参考
http://www.cnblogs.com/loveis715/archive/2012/04/10/2441513.html
------解决思路----------------------
GetEvent("MouseDown");
WPF里没有这个东西
WPF里叫 mouseleftbuttondown
  相关解决方案