Get List of Functions and Subs in a class file - vb.net

Is there a way to get a list of all of the Functions and Subs in Class file in Visual Studios? We're making extensive changes and I'd like to have a list in excel so I can use it to keep track of what I've already done.
I'd like to also get a list of every function/sub that references those subs/functions, but I can do that myself if necessary.
So, can this be done in Visual Studios?

Two options:
1. Programatically using Reflection and Type.GetMethods
See the MSDN page
Here is the example code on that page (I did not author this code, please see the link above)
Imports System
Imports System.Reflection
Imports System.Reflection.Emit
Imports Microsoft.VisualBasic
' Create a class having two public methods and one protected method.
Public Class MyTypeClass
Public Sub MyMethods()
End Sub 'MyMethods
Public Function MyMethods1() As Integer
Return 3
End Function 'MyMethods1
Protected Function MyMethods2() As [String]
Return "hello"
End Function 'MyMethods2
End Class 'MyTypeClass
Public Class TypeMain
Public Shared Sub Main()
Dim myType As Type = GetType(MyTypeClass)
' Get the public methods.
Dim myArrayMethodInfo As MethodInfo() = myType.GetMethods((BindingFlags.Public Or BindingFlags.Instance Or BindingFlags.DeclaredOnly))
Console.WriteLine((ControlChars.Cr + "The number of public methods is " & myArrayMethodInfo.Length.ToString() & "."))
' Display all the public methods.
DisplayMethodInfo(myArrayMethodInfo)
' Get the nonpublic methods.
Dim myArrayMethodInfo1 As MethodInfo() = myType.GetMethods((BindingFlags.NonPublic Or BindingFlags.Instance Or BindingFlags.DeclaredOnly))
Console.WriteLine((ControlChars.Cr + "The number of protected methods is " & myArrayMethodInfo1.Length.ToString() & "."))
' Display all the nonpublic methods.
DisplayMethodInfo(myArrayMethodInfo1)
End Sub 'Main
Public Shared Sub DisplayMethodInfo(ByVal myArrayMethodInfo() As MethodInfo)
' Display information for all methods.
Dim i As Integer
For i = 0 To myArrayMethodInfo.Length - 1
Dim myMethodInfo As MethodInfo = CType(myArrayMethodInfo(i), MethodInfo)
Console.WriteLine((ControlChars.Cr + "The name of the method is " & myMethodInfo.Name & "."))
Next i
End Sub 'DisplayMethodInfo
End Class 'TypeMain
2. With Visual Studio IDE and Code Metrics
Right click the Project
Calculate Code Metrics
In Code Metrics Results pane
Right click the Class
Open the Selection in Microsoft Excel
Might be an easier option.

Related

Is it possible to change the appearance of a custom class's object in the VBA editor's locals and watch windows? [duplicate]

Although an experienced VBA programmer it is the first time that I make my own classes (objects). I am surprised to see that all properties are 'duplicated' in the Locals Window. A small example (break at 'End Sub'):
' Class module:
Private pName As String
Public Property Let Name(inValue As String)
pName = inValue
End Property
Public Property Get Name() As String
Name = pName
End Property
' Normal module:
Sub Test()
Dim objTest As cTest
Set objTest = New cTest
objTest.Name = "John Doe"
End Sub
Why are both Name and pName shown in the Locals Window? Can I in some way get rid of pName?
As comments & answers already said, that's just the VBE being helpful.
However if you find it noisy to have the private fields and public members listed in the locals toolwindow, there's a way to nicely clean it up - here I put the Test procedure inside ThisWorkbook, and left the class named Class1:
So what's going on here? What's this?
Here's Class1:
Option Explicit
Private Type TClass1
Name As String
'...other members...
End Type
Private this As TClass1
Public Property Get Name() As String
Name = this.Name
End Property
Public Property Let Name(ByVal value As String)
this.Name = value
End Property
The class only has 1 private field, a user-defined type value named this, which holds all the encapsulated data members.
As a result, the properties' underlying fields are effectively hidden, or rather, they're all regrouped under this, so you won't see the underlying field values unless you want to see them:
And as an additional benefit, you don't need any pseudo-Hungarian prefixes anymore, the properties' implementations are crystal-clear, and best of all the properties have the exact same identifier name as their backing field.
All the Inspection windows not only show the public interface of the objects to you, but also their private members. AFAIK there is nothing you can do about it.
Consider it a nice feature to get even more insights while debugging.
In my experience this is less of an issue in real world objects as they tend to have more fields and properties. Assuming a consistent naming (as your example shows), fields and properties are nicely grouped together.
If you really dont want to see even Mathieu's This you could wrap it into a function. This is a bit more involved, and can be achieved using
a second class that stores the data in public variables. This will be marginally slower then Mattieu's implementation
a collection object that accesses the data using keys. This does not require additional clutter in the project exporer's 'class module' list but will be a little slower if you call the This repeatedly in fast sucession
An example for each is given below. If you break in the Class's Initialisation function, you can add me to the watch window and only the Name property will be listed
Using 2 Objects example
insert a classmodule and name it: InvisibleObjData
Option Explicit
Public Name As String
Public plop
Private Sub Class_Initialize()
Name = "new"
plop = 0
End Sub
insert a classmodule and name it: InvisibleObj
Option Explicit
Private Function This() As InvisibleObjData
Static p As New InvisibleObjData 'static ensures the data object persists at successive calls
Set This = p
End Function
Private Sub Class_Initialize()
This.Name = "invisible man": Debug.Print Name
Me.Name = "test": Debug.Print Name
This.plop = 111: Debug.Print This.plop
End Sub
Property Let Name(aname As String): This.Name = aname: End Property
Property Get Name() As String: Name = This.Name: End Property
'_______________________________________________________________________________________
' in the immediate window type
'
' set x=new invisibleObj
If you dont like splitting the class over two objects, a similar behaviour can be generated using a 'wrapped' collection object:
insert a classmodule and name it: InvisibleCol
Option Explicit
Private Function This() As Collection
Static p As New Collection
'static ensures the collection object persists at successive calls
'different instances will have different collections
'note a better dictionary object may help
Set This = p
End Function
Private Function add2this(s, v)
'a better dictionary object instead of the collection would help...
On Error Resume Next
This.Remove s
This.Add v, s
End Function
Private Sub Class_Initialize()
add2this "name", "invisible man": Debug.Print Name
Me.Name = "test": Debug.Print Name
add2this "plop", 111
Debug.Print This("plop") ' use the key to access your data
Debug.Print This!plop * 2 ' use of the BANG operator to reduce the number of dbl quotes
' Note: This!plop is the same as This("plop")
End Sub
Property Let Name(aname As String): add2this "name", aname: End Property
Property Get Name() As String: Name = This!Name: End Property
'_______________________________________________________________________________________
' in the immediate window type
'
' set x=new invisibleCol

Can you put VBA code in a bare module, outside of Function or Sub?

I'm trying to keep a Collection Class of Classes persistent while a Userform is running so that the form objects they create can still have event handlers.
But if I create any classes for these in subs or functions, their respective classes and event handlers would be cleared at the end of whatever subroutine created it.
I should specify that user input determines how many classes there will be, so I can't just hard code the event handlers into the userform module.
You can use a publicly declared dictionary to hold instances of your class that will be available to your project. You declare variables outside of a function or sub and declare them as Public for other modules and their subs/functions to be able to use them. They stay resident in memory between calls while the application is open.
Consider a class called c_gumball:
Public color As String
Public diameterInches As Double
Public Function getSize(unit As String) As Double
Select Case unit
Case "mm"
getSize = diameterInches * 25.4
Case "cm"
getSize = diameterInches * 2.54
Case "yd"
getSize = diameterInches / 36
End Select
End Function
And then a new module called m_gbmachine:
Public gumballMachine As Dictionary
Public Sub createGumbalMachine()
gumballMachine = New Dictionary
End Sub
Public Sub addGumball(color As String, sizeInInches As Double, nameKey As String)
Dim gb As c_gumball
Set gb = New c_gumball
gb.color = "green"
gb.diameterInches = 1.2
gumballMachine.Add Key = nameKey, gb
End Sub
Public Sub removeGumball(nameKey As String)
gumballMachine.Remove (nameKey)
End Sub
Any module can now use m_gbmachine.gumballMachine dictionary and see what's in it. They can add gumballs using it's functions.
Perhaps in your userform you create a gumball called "gumball2" in your dictioanry and then want to get the color property of "gumball2" in the gumballMachine dictionary, you could do:
Public Sub button_Click()
'add gumball 2 to the machine
m_gbmachine.addGumball "green", 1.2, "gumball2"
End Sub
Public Sub someFormRoutine()
'msgbox the color of gumball 2
MsgBox m_gbmachine.gumballMachine("gumball2").color
End Sub
You can go deeper and change this module over to a class of it's own and have many gumball machine instances as well.

Vb6 Deep Count the number of properties in a UDT Object [duplicate]

I have a feeling the answer to this is going to be "not possible", but I'll give it a shot...
I am in the unenviable position of modifying a legacy VB6 app with some enhancements. Converting to a smarter language isn't an option.
The app relies on a large collection of user defined types to move data around. I would like to define a common function that can take a reference to any of these types and extract the data contained.
In pseudo code, here's what I'm looking for:
Public Sub PrintUDT ( vData As Variant )
for each vDataMember in vData
print vDataMember.Name & ": " & vDataMember.value
next vDataMember
End Sub
It seems like this info needs to be available to COM somewhere... Any VB6 gurus out there care to take a shot?
Thanks,
Dan
Contrary to what others have said, it IS possible to get run-time type information for UDT's in VB6 (although it is not a built-in language feature). Microsoft's TypeLib Information Object Library (tlbinf32.dll) allows you to programmatically inspect COM type information at run-time. You should already have this component if you have Visual Studio installed: to add it to an existing VB6 project, go to Project->References and check the entry labeled "TypeLib Information." Note that you will have to distribute and register tlbinf32.dll in your application's setup program.
You can inspect UDT instances using the TypeLib Information component at run-time, as long as your UDT's are declared Public and are defined within a Public class. This is necessary in order to make VB6 generate COM-compatible type information for your UDT's (which can then be enumerated with various classes in the TypeLib Information component). The easiest way to meet this requirement would be to put all your UDT's into a public UserTypes class that will be compiled into an ActiveX DLL or ActiveX EXE.
Summary of a working example
This example contains three parts:
Part 1: Creating an ActiveX DLL project that will contain all the public UDT declarations
Part 2: Creating an example PrintUDT method to demonstrate how you can enumerate the fields of a UDT instance
Part 3: Creating a custom iterator class that allows you easily iterate through the fields of any public UDT and get field names and values.
The working example
Part 1: The ActiveX DLL
As I already mentioned, you need to make your UDT's public-accessible in order to enumerate them using the TypeLib Information component. The only way to accomplish this is to put your UDT's into a public class inside an ActiveX DLL or ActiveX EXE project. Other projects in your application that need to access your UDT's will then reference this new component.
To follow along with this example, start by creating a new ActiveX DLL project and name it UDTLibrary.
Next, rename the Class1 class module (this is added by default by the IDE) to UserTypes and add two user-defined types to the class, Person and Animal:
' UserTypes.cls '
Option Explicit
Public Type Person
FirstName As String
LastName As String
BirthDate As Date
End Type
Public Type Animal
Genus As String
Species As String
NumberOfLegs As Long
End Type
Listing 1: UserTypes.cls acts as a container for our UDT's
Next, change the Instancing property for the UserTypes class to "2-PublicNotCreatable". There is no reason for anyone to instantiate the UserTypes class directly, because it's simply acting as a public container for our UDT's.
Finally, make sure the Project Startup Object (under Project->Properties) is set to to "(None)" and compile the project. You should now have a new file called UDTLibrary.dll.
Part 2: Enumerating UDT Type Information
Now it's time to demonstrate how we can use TypeLib Object Library to implement a PrintUDT method.
First, start by creating a new Standard EXE project and call it whatever you like. Add a reference to the file UDTLibrary.dll that was created in Part 1. Since I just want to demonstrate how this works, we will use the Immediate window to test the code we will write.
Create a new Module, name it UDTUtils and add the following code to it:
'UDTUtils.bas'
Option Explicit
Public Sub PrintUDT(ByVal someUDT As Variant)
' Make sure we have a UDT and not something else... '
If VarType(someUDT) <> vbUserDefinedType Then
Err.Raise 5, , "Parameter passed to PrintUDT is not an instance of a user-defined type."
End If
' Get the type information for the UDT '
' (in COM parlance, a VB6 UDT is also known as VT_RECORD, Record, or struct...) '
Dim ri As RecordInfo
Set ri = TLI.TypeInfoFromRecordVariant(someUDT)
'If something went wrong, ri will be Nothing'
If ri Is Nothing Then
Err.Raise 5, , "Error retrieving RecordInfo for type '" & TypeName(someUDT) & "'"
Else
' Iterate through each field (member) of the UDT '
' and print the out the field name and value '
Dim member As MemberInfo
For Each member In ri.Members
'TLI.RecordField allows us to get/set UDT fields: '
' '
' * to get a fied: myVar = TLI.RecordField(someUDT, fieldName) '
' * to set a field TLI.RecordField(someUDT, fieldName) = newValue '
' '
Dim memberVal As Variant
memberVal = TLI.RecordField(someUDT, member.Name)
Debug.Print member.Name & " : " & memberVal
Next
End If
End Sub
Public Sub TestPrintUDT()
'Create a person instance and print it out...'
Dim p As Person
p.FirstName = "John"
p.LastName = "Doe"
p.BirthDate = #1/1/1950#
PrintUDT p
'Create an animal instance and print it out...'
Dim a As Animal
a.Genus = "Canus"
a.Species = "Familiaris"
a.NumberOfLegs = 4
PrintUDT a
End Sub
Listing 2: An example PrintUDT method and a simple test method
Part 3: Making it Object-Oriented
The above examples provide a "quick and dirty" demonstration of how to use the TypeLib Information Object Library to enumerate the fields of a UDT. In a real-world scenario, I would probably create a UDTMemberIterator class that would allow you to more easily iterate through the fields of UDT, along with a utility function in a module that creates a UDTMemberIterator for a given UDT instance. This would allow you to do something like the following in your code, which is much closer to the pseudo-code you posted in your question:
Dim member As UDTMember 'UDTMember wraps a TLI.MemberInfo instance'
For Each member In UDTMemberIteratorFor(someUDT)
Debug.Print member.Name & " : " & member.Value
Next
It's actually not too hard to do this, and we can re-use most of the code from the PrintUDT routine created in Part 2.
First, create a new ActiveX project and name it UDTTypeInformation or something similar.
Next, make sure that the Startup Object for the new project is set to "(None)".
The first thing to do is to create a simple wrapper class that will hide the details of the TLI.MemberInfo class from calling code and make it easy to get a UDT's field's name and value. I called this class UDTMember. The Instancing property for this class should be PublicNotCreatable.
'UDTMember.cls'
Option Explicit
Private m_value As Variant
Private m_name As String
Public Property Get Value() As Variant
Value = m_value
End Property
'Declared Friend because calling code should not be able to modify the value'
Friend Property Let Value(rhs As Variant)
m_value = rhs
End Property
Public Property Get Name() As String
Name = m_name
End Property
'Declared Friend because calling code should not be able to modify the value'
Friend Property Let Name(ByVal rhs As String)
m_name = rhs
End Property
Listing 3: The UDTMember wrapper class
Now we need to create an iterator class, UDTMemberIterator, that will allow us to use VB's For Each...In syntax to iterate the fields of a UDT instance. The Instancing property for this class should be set to PublicNotCreatable (we will define a utility method later that will create instances on behalf of calling code).
EDIT: (2/15/09) I've cleaned the code up a bit more.
'UDTMemberIterator.cls'
Option Explicit
Private m_members As Collection ' Collection of UDTMember objects '
' Meant to be called only by Utils.UDTMemberIteratorFor '
' '
' Sets up the iterator by reading the type info for '
' the passed-in UDT instance and wrapping the fields in '
' UDTMember objects '
Friend Sub Initialize(ByVal someUDT As Variant)
Set m_members = GetWrappedMembersForUDT(someUDT)
End Sub
Public Function Count() As Long
Count = m_members.Count
End Function
' This is the default method for this class [See Tools->Procedure Attributes] '
' '
Public Function Item(Index As Variant) As UDTMember
Set Item = GetWrappedUDTMember(m_members.Item(Index))
End Function
' This function returns the enumerator for this '
' collection in order to support For...Each syntax. '
' Its procedure ID is (-4) and marked "Hidden" [See Tools->Procedure Attributes] '
' '
Public Function NewEnum() As stdole.IUnknown
Set NewEnum = m_members.[_NewEnum]
End Function
' Returns a collection of UDTMember objects, where each element '
' holds the name and current value of one field from the passed-in UDT '
' '
Private Function GetWrappedMembersForUDT(ByVal someUDT As Variant) As Collection
Dim collWrappedMembers As New Collection
Dim ri As RecordInfo
Dim member As MemberInfo
Dim memberVal As Variant
Dim wrappedMember As UDTMember
' Try to get type information for the UDT... '
If VarType(someUDT) <> vbUserDefinedType Then
Fail "Parameter passed to GetWrappedMembersForUDT is not an instance of a user-defined type."
End If
Set ri = tli.TypeInfoFromRecordVariant(someUDT)
If ri Is Nothing Then
Fail "Error retrieving RecordInfo for type '" & TypeName(someUDT) & "'"
End If
' Wrap each UDT member in a UDTMember object... '
For Each member In ri.Members
Set wrappedMember = CreateWrappedUDTMember(someUDT, member)
collWrappedMembers.Add wrappedMember, member.Name
Next
Set GetWrappedMembersForUDT = collWrappedMembers
End Function
' Creates a UDTMember instance from a UDT instance and a MemberInfo object '
' '
Private Function CreateWrappedUDTMember(ByVal someUDT As Variant, ByVal member As MemberInfo) As UDTMember
Dim wrappedMember As UDTMember
Set wrappedMember = New UDTMember
With wrappedMember
.Name = member.Name
.Value = tli.RecordField(someUDT, member.Name)
End With
Set CreateWrappedUDTMember = wrappedMember
End Function
' Just a convenience method
'
Private Function Fail(ByVal message As String)
Err.Raise 5, TypeName(Me), message
End Function
Listing 4: The UDTMemberIterator class.
Note that in order to make this class iterable so that For Each can be used with it, you will have to set certain Procedure Attributes on the Item and _NewEnum methods (as noted in the code comments). You can change the Procedure Attributes from the Tools Menu (Tools->Procedure Attributes).
Finally, we need a utility function (UDTMemberIteratorFor in the very first code example in this section) that will create a UDTMemberIterator for a UDT instance, which we can then iterate with For Each. Create a new module called Utils and add the following code:
'Utils.bas'
Option Explicit
' Returns a UDTMemberIterator for the given UDT '
' '
' Example Usage: '
' '
' Dim member As UDTMember '
' '
' For Each member In UDTMemberIteratorFor(someUDT) '
' Debug.Print member.Name & ":" & member.Value '
' Next '
Public Function UDTMemberIteratorFor(ByVal udt As Variant) As UDTMemberIterator
Dim iterator As New UDTMemberIterator
iterator.Initialize udt
Set UDTMemberIteratorFor = iterator
End Function
Listing 5: The UDTMemberIteratorFor utility function.
Finally, compile the project and create a new project to test it out.
In your test projet, add a reference to the newly-created UDTTypeInformation.dll and the UDTLibrary.dll created in Part 1 and try out the following code in a new module:
'Module1.bas'
Option Explicit
Public Sub TestUDTMemberIterator()
Dim member As UDTMember
Dim p As Person
p.FirstName = "John"
p.LastName = "Doe"
p.BirthDate = #1/1/1950#
For Each member In UDTMemberIteratorFor(p)
Debug.Print member.Name & " : " & member.Value
Next
Dim a As Animal
a.Genus = "Canus"
a.Species = "Canine"
a.NumberOfLegs = 4
For Each member In UDTMemberIteratorFor(a)
Debug.Print member.Name & " : " & member.Value
Next
End Sub
Listing 6: Testing out the UDTMemberIterator class.
If you change all your Types to Classes. You have options. The big pitfall of changing from a type to a class is that you have to use the new keyworld. Every time there a declaration of a type variable add new.
Then you can use the variant keyword or CallByName. VB6 doesn't have anytype of reflection but you can make lists of valid fields and test to see if they are present for example
The Class Test has the following
Public Key As String
Public Data As String
You can then do the following
Private Sub Command1_Click()
Dim T As New Test 'This is NOT A MISTAKE read on as to why I did this.
T.Key = "Key"
T.Data = "One"
DoTest T
End Sub
Private Sub DoTest(V As Variant)
On Error Resume Next
Print V.Key
Print V.Data
Print V.DoesNotExist
If Err.Number = 438 Then Print "Does Not Exist"
Print CallByName(V, "Key", VbGet)
Print CallByName(V, "Data", VbGet)
Print CallByName(V, "DoesNotExist", VbGet)
If Err.Number = 438 Then Print "Does Not Exist"
End Sub
If you attempt to use a field that doesn't exist then error 438 will be raised. CallByName allows you to use strings to call the field and methods of a class.
What VB6 does when you declare Dim as New is quite interesting and will greatly minimize bugs in this conversion. You see this
Dim T as New Test
is not treated exactly the same as
Dim T as Test
Set T = new Test
For example this will work
Dim T as New Test
T.Key = "A Key"
Set T = Nothing
T.Key = "A New Key"
This will give a error
Dim T as Test
Set T = New Test
T.Key = "A Key"
Set T = Nothing
T.Key = "A New Key"
The reason for this is that in the first example VB6 flags T so that anytime a member is accessed it check whether the T is nothing. If it is it will automatically create a new instance of the Test Class and then assign the variable.
In the second example VB doesn't add this behavior.
In most project we rigorously make sure we go Dim T as Test, Set T = New Test. But in your case since you want to convert Types into Classes with the least amount of side effects using Dim T as New Test is the way to go. This is because the Dim as New cause the variable to mimic the way types works more closely.
#Dan,
It looks like your trying to use RTTI of a UDT. I don't think you can really get that information without knowing about the UDT before run-time.
To get you started try:
Understanding UDTs
Because of not having this reflection capability. I would create my own RTTI to my UDTs.
To give you a baseline. Try this:
Type test
RTTI as String
a as Long
b as Long
c as Long
d as Integer
end type
You can write a utility that will open every source file and add The RTTI with the name of the type to the UDT. Probably would be better to put all the UDTs in a common file.
The RTTI would be something like this:
"String:Long:Long:Long:Integer"
Using the memory of the UDT you can extract the values.

How to access an excel Add-In String parameter from excel workbook VSTO

I tried following the examples on MSDN. I have a String parameter that i need to access from VB.Net VSTO Excel WorkBook. I have opened up ComVisible in the Add-In and declared my interface, and declared a class to expose the interface.
The function i want to expose is called CheckLicStatus() and it should return a string depending on the license status, either "Active" or "Expired". Help!
I also feel that the way i am retrieving a string parameter from a passed object is wrong.
This is the Add-In Code exposing the function:
'Open up ComVisible
<ComVisible(True), InterfaceType(ComInterfaceType.InterfaceIsDual) _
Public Interface IAddInLicense
Function CheckLicStatus() As String
End Interface
'Decalre class to expose to out of process clients
<ComVisible(True)> _
<ClassInterface(ClassInterfaceType.None)> _
Public Class AddInLicense
Implements IAddInLicense
' get license status
Public Function CheckLicStatus() As String Implements IAddInLicense.CheckLicStatus
CheckLicStatus = ""
If LicIsActive Then
CheckLicStatus = "Active"
MsgBox("license is active")
Else
CheckLicStatus = "Expired"
MsgBox("License is Expired")
End If
End Function
End Class
Private myLicense As AddInLicense
Protected Overrides Function RequestComAddInAutomationService() As Object
If myLicense Is Nothing Then
myLicense = New AddInLicense()
End If
Return myLicense
End Function
This is the VSTO excel code trying to access the value of the function:
Public Sub CheckLicStatus()
Dim addIn As Office.COMAddIn = Globals.ThisWorkbook.Application.COMAddIns.Item("EstimateAddIn")
Dim myLicense As EstimateAddIn.IAddInLicense = TryCast( _
addIn.Object, EstimateAddIn.IAddInLicense)
Try
licstatus = myLicense.CheckLicStatus()
MsgBox(licstatus)
Catch ex As Exception
MsgBox("Could Not Get licstatus")
End Try
End Sub
I also have this code in a separate module:
Namespace EstimateAddIn
Interface IAddInLicense
Function CheckLicStatus() As String
End Interface
End Namespace

Emit Reflection (vb.net) Dynamically Reflect dropbox results in property grid

trying to add a dropdown into a property grid
Im using VS2010 VB.net with reflection
For my full solution - Download it here
https://www.nyvault.com/files/reflection/xml_propgrid_reflect_sk.zip
Password is
1
The point of this project is to populate a propertyGrid
I dont want to create a custom grid, i just want to populate the already made out of the box generic microsoft thing.
basically, I get the class to be created with reflection. using data from XML
Some of the fields use a custom type (this will be used for the dropdown)
This is what happens when I run the solution:
So i make the class, and it looks fine
It creates everything and sets it up. then when I make an instance of this class in my MAIN()
in calls a default constructor [new()] for the type(which is hardcoded dropdown items) instead of the custom constructor I wanted [new(byval test as integer)]
basically here are the class constructors for the custom type (located in customlist.vb)
Public Sub New()
' Gather all the localized strings currently loaded
' Gather all the strintTables from the current project.
For i As Integer = 0 To 4
myStringCollection.Add(New MyString(100 + i, "Test " & i))
Next
End Sub
Public Sub New(ByVal val As Integer)
For i As Integer = 0 To val
myStringCollection.Add(New MyString(100 + i, "Testy " & i))
Next
End Sub
it calls the Public Sub New()
but i want to call the Public Sub New(ByVal val As Integer)
please help, this has been making me rip my hair out for two months.