I'm trying to create a new Collection -
Dim theSet as New Collection
but, I am using the Textsharp PDF creator in my project -
Imports iTextSharp.text
Imports iTextSharp.text.pdf
and Textsharp apparently creates it's own "collection" Namespace, removing the VB.NET one.
Is there a way to override this and use the VB.NET Collection statement?
Thanks
There is not much you can do about a library polluting the namespace with common words like that. It has a Java background and counted on a case-sensitive language. You'll have to help the compiler by being explicit that you meant to use the VB.NET Collection class and not the iTextSharp.pdf.text.collection namespace. Either type out of the full class name to disambiguate:
Dim theSet as New Microsoft.VisualBasic.Collection
Or add an alias:
Imports VBCollection = Microsoft.VisualBasic.Collection
...
Dim theSet as New VBCollection
That same aliasing trick works on the library as well:
Imports Pdf = iTextSharp.text.pdf
And you'll have to prefix Pdf. whenever you want to reference a type from that namespace.
Related
I have a text file that contains different types of data on each row. I'm trying to read the file and create a different (sub)class instance for each one. So I did...
Dim t As Type = Type.GetType("DtaRow")
And this returns Nothing. This is odd, because the very next bit of code in the same file/namespace/everything is...
Public Class DtaRow...
In fact, the code I'm typing formerly just called it's New method without problem. So maybe I need to do this...
System.Reflection.Assembly.GetExecutingAssembly().GetType("DtaRow")
Nope, that's Nothing as well. So then I followed some instructions I found here about looping over the Assemblies to look in all of them... no luck there either. So then I try looking for "Int32" and a bunch of others, phail.
Can someone tell me the obvious thing I'm doing wrong here?
Since a single Assembly can have multiple Namespaces and a type of the same name can exist in more that one NameSpace, you have to qualify the type name with the Namespace. From MSDN:
If the type is in the currently executing assembly or in Mscorlib.dll, it is sufficient to supply the type name qualified by its namespace.
' should work
myT = Type.GetType("MyNameSpace.DtaRow")
' similarly:
myT = Type.GetType("System.Int32")
The NameSpace is integral to the Type name and NET does much the same:
Dim a As New Animal
myT = a.GetType()
Console.WriteLine(myT.ToString())
' => MyApplication1.Animal
If the code is in a form or class in the same namespace, Me.GetType.Namespace will get you the string name you can prepend; or you can use a dummy class. However, the mention of using the code in/as an extension might make that problematic. First Me will not be legal and using a dummy type will report the NameSpace for the dummy object.
If there is only one NameSpace to deal with, just use a variable and set it once:
Friend myNameSpace As String
...
' elsewhere something like a MainForm sets it:
myNameSpace - Me.GetType().NameSpace & "."
Then, just prepend that to the type names you load.
For more than one involved NameSpace, I'd use a Dictionary(Of String, String) using the type name as the key and NameSpace qualified string as the value:
myTypeName.Add("DtaRow", "FooNameSpace.DtaRow")
myTypeName.Add("Animal", "CircusActs.Animal")
I want to create a variable that can be used across multiple forms.
It's going to be a temporary storage place for integers.
There are a couple of ways to do this in VB: a VB-specific way and a non-VB specific way (i.e. one that could also be implemented in C#.
The VB-specific way is to create a module and place the variable in the module:
Public Module GlobalVariables
Public MyGlobalString As String
End Module
The non-VB-specific way is to create a class with shared properties:
Public Class GlobalVariables
Public Shared Property MyGlobalString As String
End Class
The primary difference between the two approaches is how you access the global variables.
Assuming you are using the same namespace throughout, the VB-specific way allows you to access the variable without a class qualifier:
MyGlobalString = "Test"
For the non-VB-specific way, you must prefix the global variable with the class:
GlobalVariables.MyGlobalString = "Test"
Although it is more verbose, I strongly recommend the non-VB-specific way because if you ever want to transition your code or skillset to C#, the VB-specific way is not portable.
IN VB6 just declare on top code
public GlobalVariable as string
then you can use GlobalVariable in any form as you like.
like
GlobalVariable = "house"
then you can use /call in other form
text1 = GlobalVariable
will show value "house"
You can just add it as PUBLIC to ANY Module
Example:
Module Module1
'Global variables
Public glbtxtTemplateName As String 'GLOBAL VARIABLE FOR TEMPLATE
VB loads the Modals first as a class and all PUBLIC items therein are shared directly. Think about it this way.
Lets say we have a MODULE called "MY_PROCESSES"
When you declare a SUB or a FUNCTION in "MY_PROCESSES" if you want it to be used OUTSIDE of "MY_PROCESSES" you declare as PUBLIC like this
PUBLIC SUB LOAD_TEMPLATE()
....
To get to LOAD_TEMPLATE you just call it in your code from anywhere:
LOAD_TEMPLATE
So if I need to set or use the global variable that I made public in my module I just refer to it by name:
glbtxtTemplateName="TEMPLATE_NAME"
IF glbtxtTemplateName="" then LoadTemplate
I do like building the class as above because you can reference it faster without remembering the variable but if you only need 1 or 2 global variables you can name them like we used to with Hungarian Notation style name.
This method is really quite simple and elegant. Old is new and New is Old.
I have a huge library with lots of namespaces and classes, nested to >10 levels deep. In most projects I will be using only one of the most nested namespaces at a time, so there is some kind of root, above which I will not Import. For example, the object I need lies within:
Imports MyObject = ns1.ns2.ns3.ns4.ns5.MyObject
And another one in:
Imports MyOtherObject = ns1.ns2.ns3.ns4.ns5.ns6.MyOtherObject
Problem is that ns1 and other nsX can be very long name, so the whole lines goes way off screen and it's hard to follow. I was hoping you could declare an alias like this:
Imports MyRoot = ns1.ns2.ns3.ns4.ns5
And then use the above:
Imports MyObject = MyRoot.MyObject
Imports MyOtherObject = MyRoot.ns6.MyOtherObject
But it does not work like this, i.e. Imports do not see each other.
I tried using project-wide settings - same behavior. Is there a solution or a workaround?
I was thinking maybe it's possible to package namespaces into another namespace? (similar to how My works, but I could not find any good source on how to implement this)
I have a class library project named MyWidget, with the only class being named MyWidget.
In another project, I've added a reference to my class library, and in my new class, I've tried typing in
Imports MyWidget
and
Imports MyWidget.MyWidget
However, later in my class when I try to create a new reference, Visual Studio is not allowing me to type in this:
Private widget As MyWidget
However, Visual Studio is giving me a "Type Expected." error and forcing me to also include the namespace, like so:
Private widget As MyWidget.MyWidget
I read the MSDN documentation regarding the Imports statement. I should be able to leave off the namespace when declaring the object because I have the imports statement at the top of the program. I've tested this with standard namespaces, and it works fine, but when I try it out with my class, it doesn't.
Am I missing something in the MyWidget class that will allow me to leave off the namespace when declaring the object?
I also tried renaming the namespace to MyClasses, thinking maybe that Visual Studio was getting the namespace confused with the class. However, even with
Imports MyClasses.MyWidget
I still get an error when trying to define a MyWidget object without the MyClasses Namespace.
Since the Namespace and Class have the same name the compiler gets confused when you try to instantiate MyWidget, despite the Imports statement. Just because there is an Imports statement, doesn't mean you can't fully quanlify a type (even if you have Imports System.IO.File, you can still call System.IO.File.WriteAllText), thus the confusion on the compilers end. An alternative would be to use an Alias.
Imports AWidget = MyWidget.MyWidget
Then..
Dim objWidget As New AWidget
It appears that the issue was the namespace and the class having the same name. After changing the namespace to MyClasses and the class to MyWidget, the following statements worked:
Imports MyClasses
...
Private widget as MyWidget
I see that in VB.net I can define something like a typedef using the Imports statement:
Imports MyDict = System.Collections.Generic.Dictionary(Of String, System.Collections.Generic.Dictionary(Of String, System.Collections.Generic.Dictionary(Of String, String)))
Now I want to use this MyDict in some files of my project. Suppose the above statement is defined in MyForm.vb file, what should I do in AnotherForm.vb file to access this definition?
Imports like this are just an alias for that specific file - they don't create a new "type". You will need to copy the entire line into your other files if you want to use MyDict in the same way.
That being said, a three layer nested dictionary structure is something I'd consider making a custom type to handle. This is a fairly complicated "dictionary", and having a custom type would allow you to potentially write your code in a cleaner, safer manner.