I need to access textbox values that are in Form1 from Module1 in my VB.net program. I thought I read somewhere that you can make your controls Public and then you can access the values. I tried this but it does not work. What do I need to do?
Here is my code:
Module Module1
Dim connectionMaster = New ConnectionMaster()
Dim uname As String
Dim pw As String
Dim frmInstance As Form2
frmInstance = New Form2
uname = frmInstance.Username
pw = frmInstance.Password
Username and Password are in Form2. When I try to build this, I get the error message "Value of type 'System.Windows.Forms.TextBox' cannot be converted to 'String'"
I changed the above to:
uname = frmInstance.Username.text
pw = frmInstance.Password.text
and now it works!
One simple way to do this is to create 2 public properties in your module.
Private _name As String
Public Property UserName() As String
Get
Return _username
End Get
Private Set(ByVal value As String)
_username = value
End Set
End Property
Then in your form, upon calling your module, you just need to pass the value to the module.
Related
I'm programming in a MVVM pattern and I have problems using textbox values in my function. When I call my function it does not use the values the user entered in the textbox. It is just empty. I looks like it inherits empty fields and just skips the filled in textbox fields. Please take a look at my code here
I call the addUser function from the AccountAddView here
Public Class AccountaddView
Public Sub btnAccountAdd_Click(sender As Object, e As RoutedEventArgs) Handles btnAccountAdd.Click
If txtPasswordAdd.Password <> txtPasswordAdd2.Password Then
warningLabel.Visibility = Visibility.Visible
Else
Dim model = New AccountaddModel()
model.addUser()
The functions triggers the Model
Public Class AccountaddModel
Inherits AccountaddViewModel
Public Function addUser()
Dim url As String = "https://azurefunctionsmywebsite" + "&name=" + username + "&pass=" + pass + "&role=" + role
Dim request As WebRequest = WebRequest.Create(url)
Dim response As WebResponse = request.GetResponse()
Dim result As String = New StreamReader(response.GetResponseStream()).ReadToEnd()
End Function
End Class
As you can see the Model inherits from the AccountAddViewModel. This class stores the variables that the user filled in the textbox
Public Class AccountaddViewModel
Inherits AccountaddView
Public username As String = txtUsernameAdd.Text
Public pass As String = txtPasswordAdd.Password
Public role As String = txtProjectrolAdd.Text
End Class
I have no errors. When I fill in the username,pass and role as an user the URL in the function does not fill it with the data. It is just empty.
I hope someone can help me out with this inheritance issue.
Basically, I am rewriting some code working for years. Over the time I have many (60+) references to forms - there's a menuitem with OnClick event for each form, where a form reference was created:
Private Sub SomeForm_Click(sender As Object, e As EventArgs) Handles MenuItemForSomeForm.Click
NewTab("Some Form", New SomeForm, 0)
End Sub
...where first parameter is a name to put in a tabPage.Text where the form is opened, second is a new instance of the (particular) form SomeForm and 0 is a default record to display (0 means no default record).
Now, I created a dynamic menu and stored the form names in a database (due to better access control over the access rights, etc). Now, because the menu is generated at runtime, I can't have the OnClick event with separate instance definition of the form and have to create it at runtime, after the MenuItems are created. The side-effect idea was to cut the code short by using only 1 OnClick event or such with MenuItem.Tag paremeter as FormName. Something like:
Private Sub clickeventhandler(sender As Object, e As EventArgs)
Dim tsmi As ToolStripMenuItem = CType(sender, ToolStripMenuItem)
Dim newForm As New >>>FormFrom(tsmi.Tag.ToString)<<< ' only explanation, this won't work
MainW.OpenModuleInTab(new newForm, tsmi.Tag.ToString, 0)
However I am failing to find a way to create form (instances) from this string reference. Reference through collection (i.e. List(of) or Dictionary) would be fine too, I believe.
The structure is obviously:
Object → Form → Form1 (class) → MyForm1 (instance)
I know I can create an object like this:
' Note that you are getting a NEW instance of MyClassA
Dim MyInstance As Object = Activator.CreateInstance(Type.GetType(NameOfMyClass))
I can re-type it to a Form type:
Dim NewForm as Form = CType(MyInstance,Form)
... to acccess some of the form properties like Width, TopLevel, etc., but that's about it. I can't do:
Dim NewForm1 as Form1 = CType(NewForm,Form1)
...because obviously, Form1 comes as a string "Form1".
I don't know how to create a Form1 reference from a "Form1" text (then it would be easy to create an instance) or how to create an instance directly (MyForm1).
SOLUTION
As sugested, I used reflection to get the form. The only way working for me I found was this:
Dim T As Type = System.Type.GetType(FormName, False)
If T Is Nothing Then 'if not found prepend default namespace
Dim Fullname As String = Application.ProductName & "." & FormName
T = System.Type.GetType(Fullname, True, True)
End If
Dim f2 As New Form ' here I am creating a form and working with it
f2 = CType(Activator.CreateInstance(T), Form)
f2.TopLevel = False
f2.Name = FormName.Replace(" ", "") & Now.ToString("yyyyMMddmmhh")
f2.FormBorderStyle = FormBorderStyle.None
f2.Dock = DockStyle.Fill
I am using VB.net CallByName to set public variable and same function to run a sub method (every form contains RecordID variable and LoadRecords sub):
CallByName(f2, "RecordID", CallType.Set, 111)
CallByName(f2, "LoadRecords", CallType.Method, Nothing)
For testing purposes, I put following into the testing form:
Public RecordID As Int32
Public Sub LoadRecords()
MsgBox("Load records!!!!" & vbCrLf & "RecordID = " & RecordID)
End Sub
Activator.CreateInstance(TypeFromName("Form1"))
TypeFromName Function:
Dim list As Lazy(Of Type()) = New Lazy(Of Type())(Function() Assembly.GetExecutingAssembly().GetTypes())
Function TypeFromName(name As String) As Type
Return list.Value.Where(Function(t) t.Name = name).FirstOrDefault()
End Function
So, let's go with the idea that I have an assembly called "WindowsApp2" and in that assembly I've defined Form1 and Form2. I've also created this module in the same assembly:
Public Module Module1
Public Function GetDoStuffWiths() As Dictionary(Of Type, System.Delegate)
Dim DoStuffWiths As New Dictionary(Of Type, System.Delegate)()
DoStuffWiths.Add(GetType(WindowsApp2.Form1), CType(Sub(f) WindowsApp2.Module1.DoStuffWithForm1(f), Action(Of WindowsApp2.Form1)))
DoStuffWiths.Add(GetType(WindowsApp2.Form2), CType(Sub(f) WindowsApp2.Module1.DoStuffWithForm2(f), Action(Of WindowsApp2.Form2)))
Return DoStuffWiths
End Function
Public Sub DoStuffWithForm1(form1 As Form1)
form1.Text = "This is Form 1"
End Sub
Public Sub DoStuffWithForm2(form2 As Form2)
form2.Text = "This is Form 2"
End Sub
End Module
Now, in another assembly "ConsoleApp1" I write this:
Sub Main()
Dim DoStuffWiths As Dictionary(Of Type, System.Delegate) = WindowsApp2.Module1.GetDoStuffWiths()
Dim formAssembly = System.Reflection.Assembly.Load("WindowsApp2")
Dim typeOfForm = formAssembly.GetType("WindowsApp2.Form1")
Dim form As Form = CType(Activator.CreateInstance(typeOfForm), Form)
DoStuffWiths(typeOfForm).DynamicInvoke(form)
Application.Run(form)
End Sub
When I run my console app I get a form popping up with the message "This is Form 1".
If I change the line formAssembly.GetType("WindowsApp2.Form1") to formAssembly.GetType("WindowsApp2.Form2") then I get the message "Wow this is cool".
That's how you can work with strongly typed objects that you dynamically instantiate.
Dim AssemblyProduct As String = System.Reflection.Assembly.GetExecutingAssembly().GetName.Name
Dim FormName As String = "Form1"
Dim NewForm As Object = Reflection.Assembly.GetExecutingAssembly.CreateInstance(AssemblyProduct & "." & FormName)
If TypeOf (NewForm) Is Form1 Then
Dim NewForm1 As Form1 = CType(NewForm, Form1)
NewForm1.BackColor = Color.AliceBlue
NewForm1.Show()
End If
I have Class named "User", code:
Public Class User
Private m_id As String
Private m_user_name As String
Public Sub New(ByVal id As String, ByVal name As String, ByVal pwd As String)
m_id = id
m_user_name = name
m_pwd = pwd
End Sub
Public Property Id() As String
Get
Return m_id
End Get
Set(ByVal value As String)
m_id = value
End Set
End Property
Public Property Name() As String
Get
Return m_user_name
End Get
Set(ByVal value As String)
m_user_name = value
End Set
End Property
End Class
And I want to report all the user's information, so I also have another class named "Users", code:
Public Class Users
inherits List(Of User)
Public Sub New()
'Query users' information from Table in Database
Add(New User(...)
End Sub
End Class
When I clicked on "Print" button, it will pop up the report. I have only one Form with Report Viewer, but I have a lot of reports using this Form with Report Viewer. so I code like this:
Public Class Form1
Private Sub Form1_Load(...) Handles MyBase.Load
Dim bs As New BindingSource
bs.DataSource= New Users
Dim rpt As New Microsoft.Reporting.WinForms.ReportDataSource
rpt.Name = "Report_User"
rpt.Value = bs
ReportViewer1.LocalReport.DataSources.Add(rpt)
ReportViewer1.LocalReport.ReportEmbeddedResource = rpt.Name
ReportViewer1.RefreshReport()
End Sub
But it doesn't show anything... Please help me... I really need your help..
Thanks in advance
Now I can resolve my problem.. Click here for reference
I've created a custom user control that has several properties. One specifies which database I want the control to access. I want to be able to present the user of the control a drop down from which he can select which database the control will interact with.
How do I get the dropdown to work? I can get default values, but have yet to figure out how to get the selectable list.
Any help is apprectiated.
Thanks.
Marshall
You just need to attach your own TypeConverter to your property. You will override the GetStandardValuesSupported and GetStandardValues methods (maybe GetStandardValuesExclusive too) to return the list of databases you want to show.
If you are new to the PropertyGrid and the TypeConverter, here is a document.
It turns out to be simpler than I thought.
I had an enumeration set up for the property, but was having trouble using it for the property type. Said it was unaccessable outside of the class.
Then I had a 'duh' moment and changed the enumeration from Friend to Public, and then I was able to use the enumeration as the property type. As a result the values from the enumeration are listed in a dropdown when I look at the values for that property of the controls.
Thanks to all that answered.
Marshall
I'm a little confused about your problem.
If your user control contains a DropDownList control, just inititalize somewhere in the user control.
The easiest way is in the Codebehind for the usercontrol, just do DropDownList.Items.Add() or whatever the syntax is for adding an item.
Here is the template I use to create a custom datasource for my comboboxes:
Private Class Listing
Private _List As New ArrayList
Public Sub Add(ByVal ItemNumber As Integer, ByVal ItemName As String)
_List.Add(New dataItem(ItemNumber, ItemName))
End Sub
Public ReadOnly Property List() As ArrayList
Get
Return _List
End Get
End Property
End Class
Private Class dataItem
Private _ItemNumber As Integer
Private _ItemName As String
Public Sub New(ByVal intItemNumber As Integer, ByVal strItemName As String)
Me._ItemNumber = intItemNumber
Me._ItemName = strItemName
End Sub
Public ReadOnly Property ItemName() As String
Get
Return _ItemName
End Get
End Property
Public ReadOnly Property ItemNumber() As Integer
Get
Return _ItemNumber
End Get
End Property
Public ReadOnly Property DisplayValue() As String
Get
Return CStr(Me._ItemNumber).Trim & " - " & _ItemName.Trim
End Get
End Property
Public Overrides Function ToString() As String
Return CStr(Me._ItemNumber).Trim & " - " & _ItemName.Trim
End Function
End Class
And this is how I load it:
ListBindSource = New Listing
Me.BindingSource.MoveFirst()
For Each Row As DataRowView In Me.BindingSource.List
Dim strName As String = String.Empty
Dim intPos As Integer = Me.BindingSource.Find("Number", Row("Number"))
If intPos > -1 Then
Me.BindingSource.Position = intPos
strName = Me.BindingSource.Current("Name")
End If
ListBindSource.Add(Row("Number"), strName)
Next
cboNumber.DataSource = ListBindSource.POList
cboNumber.DisplayMember = "DisplayValue"
cboNumber.ValueMember = "Number"
AddHandler cboNumber.SelectedIndexChanged, AddressOf _
cboNumber_SelectedIndexChanged
Hope this helps. One thing to keep in mind is that if cboNumber has a handler already assigned to the SelectedIndexchanged event, you will encounter problems. So don't create a default event.
I'm doing a lab for school, and I came across something I have never done before: create a default constructor within my class. It involves creating a private field to store the connection string, and then create a default constructor that sets the connection string.
Here is what I have so far:
Public Class Appointments
Private sqlconnection As String = ConfigurationSettings.AppSettings("ConnectionString")
Private Property connectionstring() As String
Get
Return sqlconnection
End Get
Set(ByVal value As String)
End Set
End Property
Public Sub New(ByVal sConnectionString As String)
sqlconnection = sConnectionString
End Sub
Am I doing this right? What is going on?
Looks good to me but you've already initilized the connection string as a private variable up top.
Are you supposed to allow someone to pass in a connection string?
Your set may need to be:
Set(ByVal value as String)
sqlconnection = value
End Set
You also need a parameterless constructor, something which gives the string a value when you instantiate an object.
For instance the parameterless constructor could be set by a web / app config file:
public sub new()
sqlconnection = ConfigurationSettings.AppSettings("ConnectionString")
end sub
The whole thing could be:
Public Class Appointments
Private sqlconnection As String
Private Property connectionstring() As String
Get
Return sqlconnection
End Get
Set(ByVal value As String)
sqlconnection = value
End Set
End Property
Public Sub New()
sqlconnection = ConfigurationSettings.AppSettings("ConnectionString")
End Sub
'optional you could add this but not sure how much of a fuss your professor might make it
'parameterized constructor
Public Sub New(ByVal sConnectionString As String)
sqlconnection = sConnectionString
End Sub
End Class
A default constructor is a constructor which takes no arguments. In this case you've defined a constructor which takes 1 argument and sets it to a private field. You'll need to change your code in the following ways
Have the constructor take no parameters
Move the initialization of the private field into the constructor
Like so
Public Class Appointments
Private sqlconnection As String
...
Public Sub New()
sqlconnection = ConfigurationSettings.AppSettings("ConnectionString")
End Sub
End Class
Whether you are doing it right or not depends on what you want to do.
What you are doing is the following:
You declare a private String field called sqlconnection and you initialize it to contain a value from the config file:
Private sqlconnection As String = ConfigurationSettings.AppSettings("ConnectionString")
...then you have set up a property to expose the field:
Private Property connectionstring() As String
Get
Return sqlconnection
End Get
Set(ByVal value As String)
End Set
End Property
Noticable here is that you do not do anything in the Set accessor. If the property is to be readonly; remove the Set accessor and mark the property as ReadOnly. Also, the property is Private, effectively giving it the same scope as the field. Perhaps this is intentional, but if you want to be able to get (or set) the value of the property from outside the class, it should not be Private.
Finllaly, you define a constructor, taking a String parameter, the value of which is assigned to the private field:
Public Sub New(ByVal sConnectionString As String)
sqlconnection = sConnectionString
End Sub
This looks quite OK, even though it is a bit unnecessary to initialize the field, when you replace the value in the constructor. Since the class does not define a parameter-less constructor, there is no way to create it without replacing the value of sqlconnection.