Using this article, I've set up this COM-visible interface to define my events:
[ComVisible(true)]
[Guid("3D8EAA28-8983-44D5-83AF-2EEC4C363079")]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface IParserStateEvents
{
void OnParsed();
void OnReady();
void OnError();
}
The events are meant to be fired by a class that implements this interface:
[ComVisible(true)]
public interface IParserState
{
void Initialize(VBE vbe);
void Parse();
void BeginParse();
Declaration[] AllDeclarations { get; }
Declaration[] UserDeclarations { get; }
}
Here's the implementation:
[ComVisible(true)]
[Guid(ClassId)]
[ProgId(ProgId)]
[ClassInterface(ClassInterfaceType.AutoDual)]
[ComDefaultInterface(typeof(IParserState))]
[ComSourceInterfaces(typeof(IParserStateEvents))]
[EditorBrowsable(EditorBrowsableState.Always)]
public class ParserState : IParserState
{
//...
public event Action OnParsed;
public event Action OnReady;
public event Action OnError;
private void _state_StateChanged(object sender, System.EventArgs e)
{
var errorHandler = OnError; // always null
if (_state.Status == Parsing.VBA.ParserState.Error && errorHandler != null)
{
errorHandler.Invoke();
}
var parsedHandler = OnParsed; // always null
if (_state.Status == Parsing.VBA.ParserState.Parsed && parsedHandler != null)
{
parsedHandler.Invoke();
}
var readyHandler = OnReady; // always null
if (_state.Status == Parsing.VBA.ParserState.Ready && readyHandler != null)
{
readyHandler.Invoke();
}
}
//...
The _state_StateChanged
handler is responding to events raised from a background worker thread.
The COM client code is a VBA class looking like this:
Private WithEvents state As Rubberduck.ParserState
Public Sub Initialize()
Set state = New Rubberduck.ParserState
state.Initialize Application.vbe
state.BeginParse
End Sub
Private Sub state_OnError()
Debug.Print "error"
End Sub
Private Sub state_OnParsed()
Debug.Print "parsed"
End Sub
Private Sub state_OnReady()
Debug.Print "ready"
End Sub
While everything looks right from the Object Browser:
...when the VBA code calls BeginParse
, breakpoints get hit in the C# code, but all handlers are null
, and so the VBA handlers don't run:
What am I doing wrong?