There is a new sample up demonstrating generic event handling in entry point classes. Click here to download EventSample VB v2.1 – Exposing Generic Events in Entry Point Classes
Excerpt from EventSample VB v2.1 EventHandlerT in EntryPoint Classes.doc:
At this time there is no direct way to expose an EventHandler<T> in the host to VSTA add-ins. This sample uses a workaround which involves using non-generic event handling between the host and proxy, and generic event handling between the proxy and add-in. This is accomplished by raising the non-generic events in the host and adding methods to the proxy to translate the events and event args. The host and proxy must be modified; however, the host item provider and host type map provider do not require any alterations.
This workaround only works for generic events raised by the entry point class the add-in is based on. There is a separate workaround for generic events raised by other classes which is more involved.
This sample is a modified version of the Event Sample VB v 2. To run this sample, extract the zip file and run the included setup file SetupEventSample VB v 2.1.js. Build the solution to move the proxy to the GAC and build the included sample add-in to load the assembly. Both events hooked into the by the add-in will be triggered by entering a message into the input box and selecting “Add”.
The proxy and add-ins use tight versioning, the proxy assembly is marked as version 2.1 and the project templates included use this assembly as version specific. To use the included AutoProxyGen Input.xml file to regenerate the main proxy file, update the file locations (the proxy included will work so this is not necessary). Only one modification was done to the auto-generated proxy file, in the entry point class and it’s base the non-generic events were changed from public to private so that only the generic events are visible to add-ins.
Workaround Components:
1) Define custom event args.
2) Define an EventHandler<T> in the EntryPoint class using the custom event args (must be the entry point the add-in will be based on).
3) Define a delegate using the custom event args. This will be used to communicate between the host and proxy.
4) Define an event based on the delegate defined in 3 above. This will be used to communicate between the host and proxy.
5) Anytime the EventHandler<T> is raised, raise the event based on the delegate, this event will trigger the EventHandler<T> in the proxy/add-in.
6) Create the proxy as normal. This will define in the proxy:
a. The custom event args from 1.
b. The delegate using the custom event args from 3.
c. The event based on the delegate from 4 in both the class and the entry point class.
This will skip:
a. The EventHandler<T> (all generics are skipped).
ProxyGen.exe Warning: 21040 : The following event type MainApplication contains generic type information and will not be parsed: cEventHandlerT.
7) Re-implement the custom EventArgs in the proxy while keeping the auto-generated custom EventArgs. Do this by using a different name for the re-implemented custom event args, or nesting them in a class.
8) Expand the partially defined entry point class in the proxy (suggest to do this is a separate code file) adding:
a. A private event EventHandler<T> for the custom event args for internal use by the proxy. Do not define the add and remove methods for this event.
b. A flag for the private event defined above initialized to false.
c. The EventHandler<T> defined in the host skipped by ProxyGen using the re-implemented event args deined in 7 above. Define the add and remove methods for this event. In the Add method, hook the value passed in to the private event defined in 8a above. Then, if the flag defined in 8b is false, hook the auto-generated generic event handler defined in the main proxy file to a new method to be defined in the expanded entry point class (defined below) and set the flag to true. In the remove method, remove the value from the private event defined in 8a above.
d. Add a method which satisfies the signature for the generic event handling, using the original event args. In this method, translate the original event args to the re-implemented event args. Use the re-implemented event args to raise the private event defined in 3a.
9) Expand the partially defined class in the proxy adding the EventHandler<T> (suggest to do this in the same separate code file).
Posted
Oct 08 2008, 03:52 PM
by
Melody