使用这篇文章,我已经设置好了这个COM可见接口来定义我的事件:
[ComVisible(true)]
[Guid("3D8EAA28-8983-44D5-83AF-2EEC4C363079")]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface IParserStateEvents
{
void OnParsed();
void OnReady();
void OnError();
}
这些事件的触发是由实现了此接口的类来完成的:
[ComVisible(true)]
public interface IParserState
{
void Initialize(VBE vbe);
void Parse();
void BeginParse();
Declaration[] AllDeclarations { get; }
Declaration[] UserDeclarations { get; }
}
这是实现方式:
[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();
}
}
//...
_state_StateChanged
处理程序响应来自后台工作线程引发的事件。
COM客户端代码是一个类似于以下内容的VBA类:
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
尽管从 对象浏览器 看起来一切正常:
但当 VBA 代码调用 BeginParse
时,断点会命中 C# 代码,但所有处理程序都为 null
,因此 VBA 处理程序不会运行:
我做错了什么?
ParserState
上的属性更改为[[ClassInterface(ClassInterfaceType.None)]
有帮助吗? - Bradley GraingerHandles
语法是 VB.NET 的... - Mathieu Guindon