通过COM将具有事件的C#接口实现到VB6中

3

我有一个VB6类需要实现我在C#中创建的接口。我已经成功地通过COM实现了接口的所有属性,但是无法实现它具有的事件。如果我理解正确,我将需要定义相当于添加和删除访问器以注册事件的消费者,但我无法让VB6接受具有定义事件的接口。我将类的InterfaceType设置为InterfaceIsIDispatch,但仍然在尝试编译时收到“Bad interface for Implements: method has underscore in name”错误。接口没有定义任何方法,属性和事件也没有下划线。

以下是接口定义:

namespace AV8B.Overlay
{
   [ComVisible(true)]
   [Guid("89519DCE-86D6-4962-8CEA-450F2AB31B4E")]
   public delegate void OverlaySymbolPropertyChangedEventHandler(object sender, OverlaySymbolPropertyChangedEventArgs e);

   [ComVisible(true)]
   [Guid("9A59EF10-B688-4af9-8C21-FB95C7ED699A")]
   public class OverlaySymbolPropertyChangedEventArgs : PropertyChangedEventArgs
   {
      OverlaySymbolPropertyChangedEventArgs(string propertyName) : base(propertyName) { }
   }

   [ComVisible(true)]
   [Guid("379B179C-85FA-4efb-8198-D1A4C80D645A")]
   public interface IOverlaySymbol : INotifyPropertyChanged
   {
      bool SelectedForProcessing { get; set; }
      int SymbolNumber { get; }
      string SymbolType { get; }
      double Latitude { get; }
      double Longitude { get; }
      string Color { get; }
      int Size { get; }

      /// <summary>
      /// This method fires the PropertyChanged event.
      /// </summary>
      void NotifyPropertyChanged();

      /// <summary>
      /// The event that fires when a property changes.
      /// </summary>
      new event OverlaySymbolPropertyChangedEventHandler PropertyChanged;
   }
}

这样做的目的是将已经实现该接口的VB对象放置到一个绑定列表中,该列表将附加到一个列表网格视图上。列表网格视图需要知道其项的属性何时发生更改,以便及时更新。

生成的 COM 接口可能包含下划线,即使您在 C# 接口定义中没有显式使用它。一位前同事已经实现了您正在尝试做的事情(将 COM 对象绑定到 .NET GUI 中),但是 COM 实现是用 C++ 而不是 VB6 完成的,因为 VB6 仅提供了一个减少的 COM 功能集。 - Seb
4个回答

1

INotifyPropertyChanged 主要用于属性绑定,就像你所描述的那样。

具体来说,VB6 控件(以及 ActiveX 控件)已经大多数内置了此功能,但是这是不同的接口。

您可以尝试反向操作:您的网格接受带有 INotifyPropertyChanged 的 .Net 控件和带有 INotifyPropertySink 的 ActiveX 控件。一些相关的辅助工具可能包括:

点赞!


0

一种选择是使用标准的COM事件,它们会为您处理接口、订阅、取消订阅等操作。

如果您只有一个单独的对象,那么普通的事件/委托对将被公开为COM事件,但对于更复杂的接口和事件,您需要创建自己的事件接收器接口,并使用以下方式将其与每个类本身关联:

[System.Runtime.InteropServices.ComSourceInterfaces(typeof(ISystem_COMEventSink))]

0

听起来很复杂。也许更好的方法是:

1)在.NET上创建您接口的一个实现,并使用“Active Record”模式来处理行为 2)然后创建一个包装器,其中包含以下简单方法:

entityChange(parameters) saveChange(parameters) SaveAll CancellAll

从.NET中,您可以向VB6抛出事件(以更新网格或执行其他操作)

这里有一些示例列表 http://www.elguille.info/NET/servidorNETparaCOM/servidorNETparaCOM.htm

将所有内容混合在一起并进行测试。


0

在VB6中无法实现事件,即使使用原生VB6类声明了事件也不行。

为了处理这个阻抗,您可以向VB6对象传递回调接口,并在.Net中实现一个代理,在回调方法实现中引发事件。该代理还需要转发属性/方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接