I'm declaring two strings into my main form this way:
Public Shared SerNum As String = vbNullString
Public Shared SKey As String = vbNullString
Then I give some values to them. After that, I open another form and I try to get values from the two variables but only SerNum preserves his value while SKey turns out to be Nothing.
I repeatedly checked my code but I didn't found a reason for this to happen.
The second form is showed immediatly after giving values.
What can I check to find the error?
At the moment I solved by using a Public Shared Dictionary(of String, String) and putting both strings into it, but I would like to understand where I'm wrong.
EDIT
I found the mistake: SKey was also declared into my sub so the value wasn't assigned to the Public Shared variable but to the local variable.
I thought I had 'commented' that row...
I have a proposition for acceding to your variable from other form :
In From main let's name it "From1" must be like :
Public Class Form1
Public SerNum As String = vbNullString
Public SKey As String = vbNullString
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim fr As New Form2(Me)
SerNum = "ValueNum"
SKey = "ValueKey"
fr.Show()
End Sub
End Class
In your seconde from "Form2" :
Public Class Form2
Dim fr As New Form1
Public Sub New(fr As Form1)
InitializeComponent()
Me.fr = fr
End Sub
Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
MsgBox(fr.SKey)
MsgBox(fr.SerNum)
End Sub
Related
Obviously I cannot use strName in the Dictionary declaration line, but I'm just placing it there to represent what I'm trying to do. For example, if the User enters "carrot", I want the dictionary created to be named carrot. Is there a way to do this?
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim strName As String
strName = TextBox1.Text
Dim strName As New Dictionary(Of String, String)
End Sub
End Class
You can't. The name is useful for debugging and in reality the compiler will not use the name anyway - the name will be kept in the pdb file, nowhere else.
If you need to keep track of some dictionary by name, you could use another dictionary such as:
Private dictionaries As New Dictionary(Of String, Dictionary(Of String, String))()
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim strName = TextBox1.Text
Dim myNamedDictionary As Dictionary(Of String, String)
If dictionaries.ContainsKey(strName) Then
myNamedDictionary = dictionaries(strName)
Else
myNamedDictionary = New Dictionary(Of String, String)()
dictionaries.Add(strName, myNamedDictionary)
End If
' now you have a dictionary for the name you entered (carrot)
End Sub
To retrieve
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim carrotDictionary = dictionaries("carrot")
End Sub
I think this is as close as you will get.
You can, kind of. Using a compiler you can compile your own code, but the end result seems so unusable, I doubt this is what you want to do
Option Strict Off
Imports System.Reflection
Imports System.CodeDom.Compiler
Public Class Form1
Private dictionaryInstance As Object
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim strName = TextBox1.Text
Dim t = GetType(Form1)
Dim ns = t.Namespace
Dim provider = New VBCodeProvider()
Dim params = New CompilerParameters()
params.GenerateInMemory = True
params.ReferencedAssemblies.Add(Assembly.GetEntryAssembly().Location)
params.OutputAssembly = "OutputAssembly"
Dim code =
$"
Imports System
Imports System.Collections.Generic
Namespace {ns}
Partial Public Class DictionaryClass
Public {strName} As New Dictionary(Of String, String)
End Class
End Namespace"
Dim results = provider.CompileAssemblyFromSource(params, {code})
Dim assy = results.CompiledAssembly
Dim o As Object = assy.CreateInstance($"{ns}.DictionaryClass")
Me.dictionaryInstance = o
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
dictionaryInstance.carrot.Add("a", "b")
End Sub
End Class
I'm struggling with the solution of passing the variables through different classes in VB.
The goal is to run a Form to present the progress and other info (I made a BackgroundWorker inside Form1), while a different vb thread is doing the job.
I finished with the MainClass and myWrapper, which does not do the job in the Form1 window. I set the class WorkerArgs between them, to pass the arguments, but I can only create 2 different objects of WorkerArgs.
I need to pass the same WorkerArgs.startProgress value to Form1 Class... How to do it?
Public Class MainClass
Shared Sub Main()
Dim form1 As Form = New Form1
Dim myWrapper As WorkerArgs = New WorkerArgs
form1.Show()
myWrapper.startProgress = "start"
End Sub
End Class
Public Class WorkerArgs
Public startProgress As String
Public passPercentage As String
End Class
Public Class Form1
Public Sub OnLoad(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim args As WorkerArgs
BackgroundWorker1.RunWorkerAsync(args)
End Sub
Public Sub bgw1_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs) Handles BackgroundWorker1.DoWork
System.Threading.Thread.Sleep(1000)
' Access variables through e
Dim args As WorkerArgs = e.Argument
' Do something with args
Dim str As String = args.startProgress
If str = "start" Then
MessageBox.Show(str)
End If
End Sub
[...]
End Class
I'm using Visual Studio 2013. My issue is that I can't get any value of my form1 from any class.
This is my code
Public MyHour as DateTime
Public SomeValue as string
Public MyClass as SomeClass
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
MyHour = datetime.now()
Somevalue = "asjdasd"
MyClass = new Someclass()
End Sub
Here is the button1 click event code in form1:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Myclass.mysub()
End sub
When I call a sub on my class I can't access to anything of my form1:
public sub mysub()
Dim datetovalidate as datetime= form1.actualhour
Dim stringtovalidate as string = form1.somevalue
messagebox.show(datetovalidate.tostring)
messagebox.show(stringtovalidate)
end sub
From my class:
Datetovalidate shows me: 01/01/0001 00:00:00
Stringtovalidate shows me : ""
Even If I try to access to a property of a control in my form1 from my class nothing happens, and there is no exception being fired and no errors show me up for this situation. What can I do?
I recommend you pass the parameters you need into the subroutine:
Public Sub MySub(ByVal myHour as DateTime, ByVal someValue as String)
messagebox.show(myHour.tostring)
messagebox.show(someValue)
End Sub
Then, you'll call it from Form1
Myclass.MySub(MyHour, SomeValue)
You could instead pass the whole Form1 in there, but that's less recommended in case you want to call the method from a different form, or from something that isn't a form at all.
I'm trying to pass form name and object as parameters of my public sub because I have 2 forms and they are almost identical to one another.
For example I have richtextbox1 in Form1 and I also have richtextbox1 in Form2, I would like to create a public sub something like this.
Public Sub Sub1(ByVal frm_name As form, Byval obj_name As object)
frm_name.obj_name.Lines.Length 'Get the length of lines of that richtextbox
End Sub
Then when I want to call it
'Form 1 Codes
Public Class Form1
Private Sub Tmr1_Tick(sender As Object, e As EventArgs) Handles Tmr1.Tick
Sub1(me, richtextbox1)
End Sub
End Class
'Form 2 Codes
Public Class Form2
Private Sub Tmr1_Tick(sender As Object, e As EventArgs) Handles Tmr1.Tick
Sub1(me, richtextbox1)
End Sub
End Class
It is not working the way I want it, is there anything I can do for it to work?
Think about it. You are saying that you're passing the names of things but you're not. You're not passing the name of a form; you're passing the form itself. You're not passing the name of an object; you're passing the object itself. What is the actual point of this? It's to get the number of lines in a RichTextBox, right? So, write a method that takes a RichTextBox as an argument and then call it passing a RichTextBox.
Public Sub Sub1(rtb As RichTextBox)
Dim lineCount = rtb.Lines.Length
'...
End Sub
'Form 1 Codes
Public Class Form1
Private Sub Tmr1_Tick(sender As Object, e As EventArgs) Handles Tmr1.Tick
Sub1(richtextbox1)
End Sub
End Class
'Form 2 Codes
Public Class Form2
Private Sub Tmr1_Tick(sender As Object, e As EventArgs) Handles Tmr1.Tick
Sub1(richtextbox1)
End Sub
End Class
I'm writing a simple application - address book. User enters new addresses and they are added as an entry to a list visible on the main form (frmStart). I use one form to add and edit (AddContForm). Add button on the frmStart works fine, however I experience some problems with the edit button as when I press it and enter new data they are added as new entry however the previous entry is still there. Logic is handled by Contact.vb class. Please let me know how to fix this problem. Here is the code:
Contact.vb
Public Class Contact
Public Contact As String
Public Title As String
Public Fname As String
Public Surname As String
Public Address As String
Private myCont As String
Public Property Cont()
Get
Return myCont
End Get
Set(ByVal value)
myCont = Value
End Set
End Property
Public Overrides Function ToString() As String
Return Me.Cont
End Function
Public Sub Display()
Dim C As New Contact
C.Cont = frmAddCont.txtTitle.Text
C.Fname = frmAddCont.txtFName.Text
C.Surname = frmAddCont.txtSName.Text
C.Address = frmAddCont.txtAddress.Text
frmStart.lstContact.Items.Add(C)
End Sub
End Class
Here is frmStart.vb
Public Class frmStart
Public Button As String
Private Sub btnAdd_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAdd.Click
Button = ""
Button = "Add"
frmAddCont.ShowDialog()
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDel.Click
Button = ""
Button = "Del"
Dim DelCont As Contact
DelCont = Me.lstContact.SelectedItem()
lstContact.Items.Remove(DelCont)
End Sub
Private Sub lstContact_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lstContact.SelectedIndexChanged
End Sub
Private Sub btnEdit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnEdit.Click
Button = ""
Button = "Edit"
Dim C As Contact
If lstContact.SelectedItem IsNot Nothing Then
C = DirectCast(lstContact.SelectedItem, Contact)
frmAddCont.ShowDialog()
End If
End Sub
End Class
Here is AddContFrm.vb
Public Class frmAddCont
Public Class ControlObject
Dim Title As String
Dim FName As String
Dim SName As String
Dim Address As String
Dim TelephoneNumber As Integer
Dim emailAddress As String
Dim Website As String
Dim Photograph As String
End Class
Private Sub btnConfirmAdd_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnConfirmAdd.Click
Dim B As String
B = frmStart.Button
Dim C As New Contact
C.Display()
Me.Hide()
If B = "Edit" Then
C = DirectCast(frmStart.lstContact.SelectedItem, Contact)
frmStart.lstContact.SelectedItems.Remove(C)
End If
End Sub
Private Sub frmAddCont_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
End Sub
End Class
Update:
I really don't care much for whether the data on the AddForm is the old data or the new data. I don't understand how this code would help me achieve my goal. I think the problem now is that when I click edit previous entry on the list is not deleted (what I believe I have indicated in my question) - I tried to delete it (by using the if condition and checking what button was pressed) however it seems it is not working properly for some reason. I don't understand how your code could help me - please if possible explain it better.
If you're going to use the shared instance of frmAddCont, then it'll remember the data each time you show it, so you'd have to add some kind of Initialize method where you initialize all the controls to the defaults you want (for example empty textboxes).
However, the other way around it would be to do something like:
using(dlg as new frmAddCont)
{
If(dlg.ShowDialog() = DialogResult.OK)
{
Dim C As Contact = dlg.GetNewContact()
}
}
Please note, the above code is not tested and is just meant as a sample rather than the exact code you need.