动态添加委托失败

Liekkas 2015-02-05 09:35:43

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里添加委托失败,怎么回事?
...全文
250 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
生财 2015-02-10
  • 打赏
  • 举报
回复
GetEvent("MouseDown"); WPF里没有这个东西 WPF里叫 mouseleftbuttondown
  • 打赏
  • 举报
回复
WPF里UIElement采用的都是路由事件 参考 http://www.cnblogs.com/loveis715/archive/2012/04/10/2441513.html
Liekkas 2015-02-05
  • 打赏
  • 举报
回复
貌似用winform 调用GetObjectEventList返回成功,而wpf 调用GetObjectEventList返回失败
於黾 2015-02-05
  • 打赏
  • 举报
回复
把代码和现象反复贴出来好几遍,是没有意义的 你先确定这个函数里到底执行到哪就出问题了 如果它一开始就出问题了,你还是重写方法吧
Liekkas 2015-02-05
  • 打赏
  • 举报
回复
就是获取PropertyInfo得到的是null
Liekkas 2015-02-05
  • 打赏
  • 举报
回复

 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 propertyInfo = p_Object.GetType().GetProperty("Events", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.IgnoreCase);//用NonPublic也是propertyInfo 也是空值
 
  
            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;
        }
於黾 2015-02-05
  • 打赏
  • 举报
回复
其实就是Delegate[] GetObjectEventList这东西出问题了呗,放那么多无关代码都是迷惑人的 断点跟,看它到底在哪一句就变成null了
Liekkas 2015-02-05
  • 打赏
  • 举报
回复
没有报错,就是委托添加不了,发现返回的是null

 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);

            Delegate d = GetBinding();//这里发现返回的是空值
        }
传入的是一致的

    private void confirmBtn_Click(object sender, EventArgs e)
        {
            EventWrapper events = null;

	   if (eventList.SelectedIndex >= 0)
			events = eventList.Items[eventList.SelectedIndex] as EventWrapper;

            Delegate d = new System.Windows.Input.MouseButtonEventHandler(aa);
            events.AddEventHandler(null, d);
            activeEvents[events] = d;

        }
  • 打赏
  • 举报
回复
报的什么错,事件委托和签名跟你传入的handler一致吗
Liekkas 2015-02-05
  • 打赏
  • 举报
回复
为什么winform有呢?那WPF怎么获取控件的事件的所有委托?
本拉灯 2015-02-05
  • 打赏
  • 举报
回复
引用 10 楼 Liekkas 的回复:
[quote=引用 9 楼 wyd1520 的回复:] WPF 里面没有Events 这个你要DEBUG WPF的事件方法是啥, WPF与WIN下不一样地。
引用 9 楼 wyd1520 的回复:
WPF 里面没有Events 这个你要DEBUG WPF的事件方法是啥, WPF与WIN下不一样地。
是的,你说得很对,winform控件的父类有 protected EventHandlerList Events { get; } 而wpf没有,不知道wpf有没有类似于上面winform的Events 属性[/quote] 木有的。控件的基类没提供事件集合。
Liekkas 2015-02-05
  • 打赏
  • 举报
回复
Liekkas 2015-02-05
  • 打赏
  • 举报
回复
引用 9 楼 wyd1520 的回复:
WPF 里面没有Events 这个你要DEBUG WPF的事件方法是啥, WPF与WIN下不一样地。
引用 9 楼 wyd1520 的回复:
WPF 里面没有Events 这个你要DEBUG WPF的事件方法是啥, WPF与WIN下不一样地。
是的,你说得很对,winform控件的父类有 protected EventHandlerList Events { get; } 而wpf没有,不知道wpf有没有类似于上面winform的Events 属性
本拉灯 2015-02-05
  • 打赏
  • 举报
回复
WPF 里面没有Events 这个你要DEBUG WPF的事件方法是啥, WPF与WIN下不一样地。
Liekkas 2015-02-05
  • 打赏
  • 举报
回复

System.Windows.Controls.Button btn = new System.Windows.Controls.Button();
            Delegate d2 = new System.Windows.Input.MouseButtonEventHandler(btn_MouseDown);

            System.Reflection.EventInfo eInfo = btn.GetType().GetEvent("MouseDown");
            eInfo.AddEventHandler(btn, d2);

            PropertyInfo pi = btn.GetType().GetProperty("Events", BindingFlags.Instance | BindingFlags.NonPublic); 
            EventHandlerList ehl = (EventHandlerList)pi.GetValue(btn, null);
            FieldInfo fieldInfo = (typeof(System.Windows.Forms.Control)).GetField("EventMouseDown", BindingFlags.Static | BindingFlags.NonPublic);

            Delegate d1 = ehl[fieldInfo.GetValue(null)];
            foreach (Delegate del in d1.GetInvocationList())
                Console.WriteLine(del.Method.Name);
经过测试发现,继承winform的控件,利用这段代码就可以动态添加委托,并可以知道所添加的委托,但是对WPF控件就不行,上面代码就是在获取PropertyInfo返回null,是不是对于WPF控件GetProperty的第一个参数不能用“Events”,还是其它原因,寻找高人进来解答

110,534

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧