Using vb.net, how can I use a class, which does not have a namespace? - vb.net

I have a file called class.vb.
In a separate project, I would like to utilize this class. However, class.vb doesn't use a namespace.
class.vb:
Imports System
Public Class MyClass
Public Sub DoSomething()
Console.WriteLine("Hello")
End Sub
End Class
Attempting to illustrate what I would like to do:
Imports MyAlias = C:\whatever\class.vb
Public Class MyOtherClass
Public Sub DoSomethingElse()
MyAlias.MyClass.DoSomething()
End Sub
End Class
If this is possible, what's wrong with doing this? Perhaps there are differences between how a normal namespace import works and the file import..

To utilize an already existing class you need to right click on the folder (or simply the project) you want to add your class in (from visual studio) and do Add Existing Item. Then browse your file explorer and select your class. Once done it should be included properly.
If the class uses other classes from your previous project make sure you include them aslo.
If there are still problems after that you could simply create an empty class and copy paste the content into it

Related

Prevent implicit import of modules [duplicate]

I have a situation where I have several VB.NET Modules in the same Logical-Module of a large application.
I would like the update function of each module to be public, but I would like users to be forced to qualify the function call with the module name.
ModuleName.Update()
instead of
Update()
Is this possible?
Thanks.
No.
The VB.NET specifications automatically use Type Promotion to allow this behavior to occur. The only way to avoid this is to have a type at the namespace that has the same name (Update) which would prevent (defeat) the type promotion provided in VB.NET.
Yes, it is possible, if you are willing to wrap the module within a namespace of the same name as the module:
Namespace ModuleName
Module ModuleName
...
End Module
End Namespace
Using modules is usually a poor design, because its methods become visible directly in the name space.
Consider replacing them with Classes. Put Shared on all the members:
Class ClassName
Public Shared Property SomeData As Integer
Public Shared Sub Update()
End Sub
End Class
Update would be referenced as:
ClassName.Update()
Make it impossible to instantiate, by having a Private instance constructor (is NOT Shared):
Private Sub New()
End Sub
Any needed class instantiation can be done like this:
Shared Sub New()
... code that runs once - the first time any member of class is accessed ...
End Sub

Hide VBA procedures from Excel application but not from other projects

I know this is a long shot, but with the limitations in "Option Private Module" and even worse "Private Sub/Function", does anyone know if there is a way of hiding VBA procedures from the Excel application but not from other projects?
I have an XLAM with a subset of reusable functionality that I like to include and reference from new Excel projects, but using "Option Private Module" hinders this and if I omit it, a bunch of unusable or obscure functions and subs become visible and available to the application.
Convert your standard modules in the XLAM to class modules (set to
Public Not Creatable);
Create an additional Class Module that returns an instance (with a
bit of additional work, the instance) of each such module; and
Create a single standard module with one property that returns the instance of the main class-entry module.
Class1:
Option Explicit
Public Sub IAmInvisible()
End Sub
ModuleEntry:
Option Explicit
Private mClass As New Class1
Public Property Get TheClass() As Class1
Set TheClass = mClass
End Property

.net assembly does not appear in Excel's References

I'm following Rich Newman's guide to using .net code assemblies in Excel. I have made a small test class called MyPro[p in a project called MyProperty that looks like this:
Imports System.Runtime.InteropServices
Public Class MyProp
Public Function GetData() As String
Return "Hello World"
End Function
End Class
It compiles fine, puts a CLSID into regedit, and (after browsing to find the TLB) allows itself to be added to Excel's References. However, I can't actually use it. I tried this in VBA:
Private Sub test()
Dim test As New MyProperty.MyProp
MsgBox test.GetData()
End Sub
Which returns:
"Class does not support Automation or does not support the expected interface"
I assume that the error means that it can't find GetData or I'm calling it incorrectly. I have re-added the TLB, with no effect.
Any ideas?
The problem has to do with the order of operations in the bindings. You can make this work by DIMming the object then Newing it on a separate line.

How to select an image from resources via a string?

I'm coding a pokedex type deal as practice for my class.
Basically, I have a class titled "pokemon". One of the properties of the class is "ImgName" Which I want to use to display an image from the resources with the same name.
VB doesn't allow me to call the ImgName as a string and then use 'My.Resources.ImgName'
How can i do this, or what are some alternative options to it? I want it to be determined by a property in the pokemon object, and i don't want to have to hard code in an if-elseif statement for every single pokemon.
One way is you can have a resource file added to your project. Then drop the resource into it. You will be able to address it like this:
My.Resources.Resource1.ImgName
Resource1 is your resource file name, and ImgName is the resource name here. But you need to do hard code for every call. However, you get full intellisense support with type checking.
If you don't want hard code, here is a stripped down version of my production code:
Imports System.Reflection
Imports System.Xml.Linq
Public Class EmbeddedResourceManager
Private Class EmbeddedResourceManagerCore
Private Shared _executingAssembly As Assembly
Private Shared _resourcePrefix As String
Shared Sub New()
_executingAssembly = Assembly.GetExecutingAssembly
_resourcePrefix = _executingAssembly.GetName.Name & "."
End Sub
Public Shared Function GetStream(resourceRelName As String) As IO.Stream
Return _executingAssembly.GetManifestResourceStream(_resourcePrefix & resourceRelName)
End Function
End Class
Public Shared Function GetImage(ByVal resourceName As String) As Bitmap
Return New Bitmap(EmbeddedResourceManagerCore.GetStream(resourceName))
End Function
End Class
So whenever you need, just call EmbeddedResourceManager.GetImage and pass the resource name, as it appears in your project (your image file needs to be attached to a project). You need to have Build Action for an image in question to be set to Embedded Resource.
This piles up all your resource into an executable, which has both benefits and drawbacks, depending on the situation. Still, it should work for your needs, since I am assuming number of different pokemons is limited and does not change throughout the game (i.e. downloaded from a 3rd party server in real time etc.).
BackgroundImage = My.Resources.ResourceManager.GetObject(aString)
10 time easier than previous answer imho

Change connection string from class library in main application at run-time

You can change the connection string at run-time like this. You make the connection string setting available for writing as a separate property inside the MySettings class:
Partial Friend NotInheritable Class MySettings
Public WriteOnly Property RunTimeConnectionString()
Set(ByVal value)
My.Settings("MyConnectionString") = value
End Set
End Property
End Class
Then, in some place when the application is being initialized (before using any table adapters of typed datasets), write something like:
My.Settings.RunTimeConnectionString = My.Settings.ProductionConnectionString
Where ProductionConnectionString is a simple String setting. It is a User Scope setting so every user can change it (by assigning a value to it, similar to the code above) and save it by calling My.Settings.Save()
This code works well for connection strings which were initially created in the main project and stored in it's settings (= app.config file).
The connection string in the app.config actually has a longer name: MyApp.MySettings.MyConnectionString.
When you have a connection string stored in the app.config in a class library project, and reference that project in the main project, the app.config files will somehow be merged, so the class library has it's settings.
The thing that don't know how to do, is change a setting from the class library at run-time. I could copy the connection string setting from the class library to the main project's app.config. I must keep the same name, which looks something like: MyClassLibrary.My.MySettings.MyConnectionString.
Can the same principle I showed above be somehow applied to this second connection string?
I tested a little more, and found out that the same solution can be used inside a class library.
I made a new class (in the class library) with a shared (static) method like this:
Public Class MySettingsChanger
Public Shared Sub SetConnectionString(ByVal cnnString As String)
My.Settings.RunTimeConnectionString = cnnString
End Sub
End Class
And extended the MySettings class (in the class library) the same way as in the main project:
Namespace My
Partial Friend NotInheritable Class MySettings
Public WriteOnly Property RunTimeConnectionString()
Set(ByVal value)
My.Settings("MyConnectionString") = value
End Set
End Property
End Class
End Namespace
At least it works in my case. The name of the connection in the main project and in the class library is the same only (the short name, not the whole ProjectNamespace.MySettings.ConnectionName). I haven't tested with having a different name of the connection in the class library, but think it should not matter.
I searched more, and found a way, but it isn't really runtime. At least not as runtime as I would like it to be. Anyway, here is the code, I tested it and it worked, but required me to restart the application first. That's not very runtime to me.
Dim configLocation As String = Reflection.Assembly.GetExecutingAssembly().Location
Dim config As Configuration.Configuration = Configuration.ConfigurationManager.OpenExeConfiguration(configLocation)
config.ConnectionStrings.ConnectionStrings.Clear()
For i As Integer = 0 To Configuration.ConfigurationManager.ConnectionStrings.Count - 1
Dim connection As New Configuration.ConnectionStringSettings(Configuration.ConfigurationManager.ConnectionStrings(i).Name, My.Settings.ProductionConnectionString)
connection.ProviderName = Configuration.ConfigurationManager.ConnectionStrings(i).ProviderName
config.ConnectionStrings.ConnectionStrings.Add(connection)
Next
config.Save()
This is the article where I found this code.
Thanks for the message on the blog. Yes, it is hardly run-time as it requires you to stop running for the changes to be picked up. Unfortunately, because settings are loaded once and only once (when the app domain is loaded), there isn't a way for the settings infrastructure to pick up changes while running.
The only option is to either restart the app or recyle the app pool if a web application. Beyond that, you would have to roll your own.
I did the best I could :-)