If you strongly type handler to a delegate type IronPython should convert the function to the delegate type on the call. I had meant to write "EventHandler<HtmlEventArgs>" in my original sample code but somehow I ended up using the Python syntax EventHandler[HtmlEventArgs] :)
Yeah, the comment's write, I'm wrong http://msdn.microsoft.com/en-us/library/2sk3x8a7(VS.71).aspx lists op_AdditionAssignment but not InPlaceAdd. > -----Original Message----- > From: users-boun...@lists.ironpython.com [mailto:users- > boun...@lists.ironpython.com] On Behalf Of Jimmy Schementi > Sent: Monday, February 15, 2010 7:08 PM > To: Discussion of IronPython > Subject: Re: [IronPython] Monkey-patching CLR types > > Thanks Dino! > > I've got something to at least compile, but I'm getting the error > "ArgumentTypeException: unsupported operand type(s) for +=: > 'PythonBrowserEvent' and 'function'". OK, makes sense, it's not finding > InPlaceAdd(Python.Runtime.Method), right? Since I can't link against > IronPython, what type should I use instead of Python.Runtime.Method? > System.Dynamic.IDynamicMetaObjectProvider, as that's the only DLR > interface that Method implements? If so, then I'm not sure how to > convert it to an Action<object, HtmlEventArgs>. > > Also, should I be using "op_AdditionAssignment" instead of InPlaceAdd? > The usage in ReflectedEvent.cs > (http://ironpython.codeplex.com/sourcecontrol/changeset/view/63991?proj > ectName=IronPython#384571) seems to say that. > > If it helps, here's what I have so far: > > public static class HtmlElementExtension { > [SpecialName] > public static object GetBoundMember(HtmlElement element, string > name) { > object propertyValue = element.GetProperty(name); > // No way to tell if a property actually exists, so best we > can do > // do is check if it's null ... > if (propertyValue == null) { > return new PythonBrowserEvent(element, name); > } > return propertyValue; > } > } > > public class PythonBrowserEvent { > private readonly HtmlElement _element; > private readonly string _event; > > internal PythonBrowserEvent(HtmlElement element, string > eventStr) { > _element = element; > _event = eventStr; > } > > [SpecialName] > public object InPlaceAdd(object handler) { > _element.AttachEvent(_event, > new EventHandler<HtmlEventArgs>((Action<object, > HtmlEventArgs>)handler)); > return null; > } > } > > > -----Original Message----- > > From: users-boun...@lists.ironpython.com [mailto:users- > > boun...@lists.ironpython.com] On Behalf Of Dino Viehland > > Sent: Sunday, February 14, 2010 4:58 PM > > To: Discussion of IronPython > > Subject: Re: [IronPython] Monkey-patching CLR types > > > > You can define an extension property that gets/sets a value which > supports in > > place addition / subtraction. Something like this: > > > > [assembly: ExtensionType(typeof(HtmlElement), > > typeof(HtmlElementExtension))] > > public static class HtmlElementExtension { > > [SpecialName, PropertyMethod] > > public static MyEvent Getonclick(HtmlElement element) { > > return new MyEvent(element); > > } > > [SpecialName, PropertyMethod] > > public static void Setonclick(HtmlElement element, object > value) { > > // You could return a value from InPlaceAdd and validate it > > here > > // to report an error on a direct assignment - this is what > > // ReflectedEvent does in IronPython. > > } > > } > > > > public class MyEvent { > > private readonly HtmlElement _element; > > public MyEvent(HtmlElement element) { > > _element = element; > > } > > [SpecialName] > > public object InPlaceAdd(EventHandler[HtmlEventArgs] > handler) { > > _element.AttachEvent("onclick", handler); > > return null; > > } > > // also needs InPlaceSubtract > > } > > > > -----Original Message----- > > From: users-boun...@lists.ironpython.com [mailto:users- > > boun...@lists.ironpython.com] On Behalf Of Jimmy Schementi > > Sent: Sunday, February 14, 2010 2:06 PM > > To: Discussion of IronPython > > Subject: [IronPython] Monkey-patching CLR types > > > > (Yes, I'm asking a question this time =P) > > > > I want to know my options for adding functionality to an existing CLR > type. > > Specifically I want to make hooking DOM events cleaner: in > Silverlight today > > you cannot hook DOM events with the standard += syntax that > IronPython uses > > for CLR events: > > > > object.onclick += foo > > > > Instead you must do this: > > > > object.AttachEvent("onclick", EventHandler[HtmlEventArgs](foo)) > > > > In IronRuby I fixed that by just monkey-patching > > System.Windows.Browser.HtmlObject, but in IronPython I cannot monkey- > patch > > built-in types. However, I do something similar with accessing DOM > properties > > (instead of element.GetProperty("innerHTML") it's just > element.innerHTML) > > with DLR's ExtensionType, which is the same way IronPython exposes > special > > methods on CLR types as well: > > > > [assembly: ExtensionType(typeof(HtmlElement), > > typeof(HtmlElementExtension))] > > public static class HtmlElementExtension { > > [SpecialName] > > public static object GetBoundMember(HtmlElement element, > string name) > > { > > return element.GetProperty(name); > > } > > } > > > > But after looking through Python's Binder and the DLR's ActionBinder > for how > > they use ExtensionTypes, I couldn't get a definitive answer on how to > capture > > an method call plus an operator. Any ideas? > > > > ~Jimmy > > > > _______________________________________________ > > Users mailing list > > Users@lists.ironpython.com > > http://lists.ironpython.com/listinfo.cgi/users-ironpython.com > > _______________________________________________ > > Users mailing list > > Users@lists.ironpython.com > > http://lists.ironpython.com/listinfo.cgi/users-ironpython.com > > _______________________________________________ > Users mailing list > Users@lists.ironpython.com > http://lists.ironpython.com/listinfo.cgi/users-ironpython.com _______________________________________________ Users mailing list Users@lists.ironpython.com http://lists.ironpython.com/listinfo.cgi/users-ironpython.com