views:

403

answers:

3

Hi,

how do you declare a default indexed property in VB.NET such that it is callable from VBScript?

I have tried this using

<DispId(0)> _
Public ReadOnly Property Item(ByVal idx As Integer) As ...

but VBScript returns the error message

Wrong number of arguments or invalid property assignment Error Code 800A01C2

This error does not occur if I expose a normal property (non-indexed) from VB.NET.

Here is a sample:

'Class1.vb:

  Public Class Class1
    Public ReadOnly Property Dogs() As Dogs
        Get
            Return New Dogs()
        End Get
    End Property
  End Class

'Dogs.vb:

  Imports System.Runtime.InteropServices

  Public Class Dogs
    <DispId(0)> _
    Public ReadOnly Property Item(ByVal idx As Integer) As Dog
        Get
            Return New Dog
        End Get
    End Property
  End Class

'Dog.vb:

  Public Class Dog
    Public ReadOnly Property Name() As String
        Get
            Return "Fido"
        End Get
    End Property
  End Class

VBScript:

  Set obj = CreateObject("FmuComTest.Class1")

  MsgBox obj.Dogs.Item(0).Name   ' this works

  MsgBox obj.Dogs(0).Name        ' error message

Accessing the default indexed property Dogs.Item(idx) causes the error message.

Regards - Frank

A: 

In traditional VB, I think the ID used for the default property was -1. I have no idea if this makes any sense in terms of a DispId, though.

Gary McGill
According to the header files, -1 is DISPID_UNKNOWN, whereas 0 is DISPID_VALUE.
fmunkert
A: 

Try this SO question Default properties in VB.Net?

Stevo3000
+1  A: 

This MSDN blog post may shed some light on the matter. It seems VBScript & COM are picky about how defaults are invoked.

http://blogs.msdn.com/ericlippert/archive/2005/08/30/458051.aspx

Frozenskys
Obviously, the CLR does not implement IDispatch::Invoke() in the same way as native COM (as described in the above MSDN blog). Microsoft Support suggested to add an optional indexer to all properties that return a collection; this solved my problem.
fmunkert