实现一个c#接口,该接口具有通过COM到VB6的事件

实现一个c#接口,该接口具有通过COM到VB6的事件,c#,events,com,interface,vb6,C#,Events,Com,Interface,Vb6,我有一个VB6类,需要实现我在C#中创建的接口。我已经能够通过COM成功地实现vb6类中接口的所有属性,但无法实现它所发生的事件。如果理解正确,我需要定义与添加和删除访问器等效的访问器来注册事件的使用者,但我无法让VB6接受定义了事件的接口。我正在将类的InterfaceType设置为InterfaceIsIDispatch,但在尝试编译时仍然会出现错误“实现的接口不正确:方法名称中有下划线”。接口没有定义任何方法,属性和事件都没有下划线 下面是接口定义 namespace AV8B.Overl

我有一个VB6类,需要实现我在C#中创建的接口。我已经能够通过COM成功地实现vb6类中接口的所有属性,但无法实现它所发生的事件。如果理解正确,我需要定义与添加和删除访问器等效的访问器来注册事件的使用者,但我无法让VB6接受定义了事件的接口。我正在将类的InterfaceType设置为InterfaceIsIDispatch,但在尝试编译时仍然会出现错误“实现的接口不正确:方法名称中有下划线”。接口没有定义任何方法,属性和事件都没有下划线

下面是接口定义

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;
   }
}
namespace AV8B.Overlay
{
[ComVisible(true)]
[Guid(“89519DCE-86D6-4962-8CEA-450F2AB31B4E”)]
公共委托void OverlySymbolPropertyChangedEventHandler(对象发送方,OverlySymbolPropertyChangedEventArgs e);
[ComVisible(true)]
[Guid(“9A59EF10-B688-4af9-8C21-FB95C7ED699A”)]
公共类OverlySymbolPropertyChangedEventArgs:PropertyChangedEventArgs
{
OverlySymbolPropertyChangedEventArgs(字符串propertyName):基(propertyName){}
}
[ComVisible(true)]
[Guid(“379B179C-85FA-4efb-8198-D1A4C80D645A”)]
公共接口IOverlaySymbol:INotifyPropertyChanged
{
bool SelectedForProcessing{get;set;}
int符号编号{get;}
字符串符号类型{get;}
双纬度{get;}
双经度{get;}
字符串颜色{get;}
整数大小{get;}
/// 
///此方法激发PropertyChanged事件。
/// 
void NotifyPropertyChanged();
/// 
///属性更改时激发的事件。
/// 
新事件覆盖SymbolPropertyChangedEventHandler PropertyChanged;
}
}

这背后的目标是将实现此接口的现有VB对象放置到绑定列表中,该列表将附加到列表网格视图。列表网格视图需要知道其项的属性何时更改,以便可以相应地更新

这听起来很复杂。也许一个更好的方法是

1) 在.net上创建一个接口的实现,并使用一种模式来描述“活动记录”的行为 2) 在使用方法为其创建一个包装器之后,如何简化

实体更改(参数) 保存更改(参数) 拯救 取消

从.net可以将事件抛出到vb6(用于更新网格或执行某些操作)

下面是示例列表


混合所有并执行测试

在VB6中无法实现事件,即使使用声明了事件的本机VB6类


要处理此阻抗,您可以将回调接口传递给VB6对象,并在.Net中实现一个代理,该代理在回调方法实现中引发事件。代理显然也需要转发属性/方法。

INotifyPropertyChanged
主要与属性绑定一起使用,正如您所述

具体来说,VB6控件(以及通常的ActiveX控件)大多已经内置了此功能,但它是一个不同的接口

您也许可以采用另一种方式:网格接受带有
INotifyPropertyChanged
的.Net控件和带有
INotifyPropertySink
的ActiveX控件。一些相关的助手可能是:


竖起大拇指

一个选项是使用标准COM事件,为您处理接口、订阅、取消订阅等

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

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

生成的COM接口可能包含下划线,即使您没有在C#接口定义中明确使用它。以前的同事实现了您想要做的事情(数据绑定COM对象到.NET GUI),但是COM实现是在C++中,而不是在VB6中,因为VB6只提供了一组简化的COM组件。