Search code examples
vb.netcomwebbrowser-controlcom-interop

"invalid property assignment" when using a collection with the WebBrowser control and ObjectForScripting


I'm simulating a third-party VB.net application for a system I am working on - the real back-end (that I don't have access to) uses a WebBrowser control and some interfacing javascript (that I do have access to).

Most of this is working, but I'm having some trouble adding the collections referenced in the javascript. In the javascript file various references like this are present:

var insSetCount = booking.InsertionSets.Count;
for (var nInsSet = 1; nInsSet <= insSetCount; nInsSet++) {
    var insSet = booking.InsertionSets(nInsSet);
}

This object looks to be a collection of some sort... I've read that generic lists are not supported by COM, so I've tried adding Public InsertionSets As ArrayList. However, I got the following error on the third line of the above javascript:

TypeError: Wrong number of arguments or invalid property assignment

I then tried rolling my own collection with an explicit Default Property assignment:

<ComVisible(True)>
Public Class InsertionSetCollection
    Inherits CollectionBase

    Public Sub New()
        MyBase.New()
    End Sub

    Public Sub Add(ByVal obj As InsertionSet)
        List.Add(obj)
    End Sub

    Default Public ReadOnly Property Item(ByVal index As Integer) As InsertionSet
        Get
            Return CType(List.Item(index - 1), InsertionSet)
        End Get
    End Property

End Class

But this approach had the same result as when I used the ArrayList.

I've worked around the problem for the moment by replacing all references to InsertionSets(i) with InsertionSets.Item(i) in the javascript - which does seem to work, but of course involves modifying production code.

Can anyone give me any pointers at to which collection type I should be using here, or alternatively how to effectively use a Default Property with COM Interop?

I've extracted my VB.net code here: http://pastebin.com/wx7ZR1ME, please let me know if something important is missing.


Solution

  • The following would work in C#, note [DispId(0)]. Hopefully, you could convert it to VB.NET:

    [ComVisible(True)]
    public class ScritingArray {
        ArrayList _items = new ArrayList();
    
        [DispId(0)]
        public object this[int index] 
        {
            get { return _items[index]; }
            set { _items[index] = value; }
        }
    }