Link to home
Start Free TrialLog in
Avatar of Lost_In_JavaScript_Land
Lost_In_JavaScript_Land

asked on

VB.Net and C# default property woes

The project I'm working on is to replace the Excel COM object with a .NET COM wrapper.  This will then allow for 3rd party spreadsheet applications (like OpenOffice) to emulate Excel for 3rd party applications that use Excel's API.

Now, I know AutomateIT has already started doing this, but I feel .NET is a better platform for developing this on, since it now becomes rather easy to implement this library on Linux platforms (thanks to projects like Wine, Mono and DotGNU.)

So far, I have suceeded with wrapping a few of the objects, but I'm having a particularly hard time with default properties in any .NET language.

For example, let's say that I have the following property defined in VB.NET, and have the classes DefaultProperty pointed at this (this is a function from a class named CollectionBase, which is what I'm using as a base for all collections I define):

    Public ReadOnly Property Item(ByVal index As Object) As Object
      Get
        Try
          Dim i As Integer = 0
         
          If (index.GetType().Name = "Int16") Or (index.GetType().Name = "Int32") Then
            Dim indexValue As Integer = Integer.Parse(index.ToString())
            For Each key As String In objColl.Keys
              If i = (indexValue - 1) Then
                Return Me.objColl(key)
              End If
             
              i += 1
            Next
          ElseIf index.GetType().Name = "String" Then
            Return Me.objColl(index)
          End If
        Catch e As Exception
          System.Windows.Forms.MessageBox.Show(e.Message)
          System.Windows.Forms.MessageBox.Show(e.StackTrace)
        End Try
       
        Return Nothing
      End Get
    End Property


If I do the following code in a WSH batch file:  Set wb = Application.Workbooks.Item(1)
It will return the first workbook in the collection.  But, if I do:  Set wb = Application.Workbooks(1)
It will give a scripting exception.

If you do the same two commands using the original Excel COM object, they both do exactly the same thing: return the first workbook.

I have tried doing the above, as well as defining default properties in C# code (by defining the "this[object index]" property)...but the WSH script still doesn't work.


Does anyone have suggestions on how I can get "Set wb = Application.Workbooks(1)" to work from WSH through my implementation of the Excel COM object?
ASKER CERTIFIED SOLUTION
Avatar of Mike Tomlinson
Mike Tomlinson
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Lost_In_JavaScript_Land
Lost_In_JavaScript_Land

ASKER

Unfortunately, that didn't work.  I also did a simple experiment where I exposed a Hashtable to COM (since a Hashtable uses default properties to access each object by it's key):

Imports System.Runtime.InteropServices
Imports System.Collections
Imports System.Reflection
Imports System

Namespace MyAssembly
    <ComVisible(True)> Public Class MyVBClass
        Private objHash As Hashtable

        Public Sub New()
            objHash = New Hashtable()
        End Sub

        Public ReadOnly Property myHashTable() As Hashtable
            Get
                Return objHash
            End Get
        End Property
    End Class
End Namespace

Then, using the following VBS script (which is just a text file with a .vbs extension):

set xapp = WScript.CreateObject("MyAssembly.MyVBClass")

xapp.myHashTable.add "abc", 1
MsgBox "Call #1: " & xApp.myHashTable.Item("abc")
MsgBox "Call #2: " & xApp.myHashTable("abc")


This code will execute the first message box fine, but the second one will throw an exception:
Wrong number of arguments or invalid property assignment: 'xapp.myHashTable'

Any thoughts?  Thanks! :)
I guess the solution that I was trying to implement was rather complex for my specific situation.  All I had to do was create an Application object which inherits Microsoft.Office.Interop.Excel.ApplicationClass, and I was able to do what I needed to do (although Excel has to be installed on the system.  blah.)

But, Idle_Mind, since your solution above did help me to eventually find a solution, I will award you the points.  :-)