How can I assign a property value using 'With {...}' syntax? - vb.net

In the new Sub New , I want to Insert value of property
Ex:
1-Class
Public Class A
Property Name As String
Sub New()
MsgBox(Name) 'Empty
End Sub
End Class
2- Form
Dim a As New A With {.Name = "ABCDE"} 'MsgBox Empty

Dim a As New A With {.Name = "ABCDE"} 'MsgBox Empty
The message box will be empty, because in the above statement the order of execution is:
First new gets called and all the statements inside the subroutine new gets executed.
Then the initialization step happens for the variables in with statement.
Now the alternate solution, if you want to print the name is during initialization:
You can print during property set, as shown below. (you can use a bool variable for not printing further when name is set a value.)
Public Class A
'PROPERTY GET AND SET
Private _name As String
Public Property Name() As String
Get
Return _name
End Get
Set(ByVal value As String)
_name = value
MsgBox(_name) 'PRINT HERE
End Set
End Property
'NEW SUBROUTINE
Sub New()
End Sub
End Class
calling:
Dim a1 As New A With
{.Name = "ABCDE"}

Related

vba Class Property Values, setting default values, storing values to string

another stumped newb here, trying to wrap my head around a problem.
I'm trying to use a class module, instead of public variables, with property get and set.
I want to set these values in a userform with text boxes, and update a listbox in the userform as they are entered, preferably on a text box event _afterupdate,
When the user hits the save button I'd like the profile attributes to be stored to a range.
No doubt this is going to be a laughable mess, but I've been stumped for days, and I'm coming here hat in hand. I just can't figure it out.
Class Mod Example:
Private mProfileName As String
Private mStartDate As Date
Private mEndDate As Date
Private mOngoing As Boolean
Sub Class_Initialise()
'Set default values for properties
mLastName = "Enter Last Name"
mStartDate = "Enter Date"
mEndDate = Date
mOngoing = True
End Sub
'********************************
'The relevant property procedures:
'********************************
Property Get ProfileName() As String
ProfileName = mProfileName
End Property
Property Let ProfileName(Value As String)
mProfileName = Value
End Property
Property Get EndDate() As Date
EndDate = mEndDate
End Property
Property Let EndDate (Value As Date)
mEndDate = Value
End Property
Property Get Ongoing() As Boolean
Ongoing = mOngoing
End Property
Property Let Ongoing(Value As Boolean)
If mEndDate = Date Then
mOngoing = True
End If
End Property
In the Userform I currently have:
Option Explicit
'hopefully not needed:
'Private mTextBoxUpdated As Boolean
'Private mListBoxUpdated As Boolean
'Private mEnteredText As String
'Private mIndexText As String
Private DictThisForm As Dictionary
Private ProfileData As clsProfileData
Private Sub UserForm_Initialize()
Debug.Print "UserForm Intialised"
Set DictThisForm = New Dictionary
Debug.Print "DictThisForm Created"
Set ProfileData = New clsProfileData
Call UserForm_UpdateListBox
And this laughable mess: (not even close to working)
Sub UserForm_UpdateListBox()
With lbxListBox1
.Clear
.ColumnCount = 2
.AddItem
'.List(0, 1) = "Profile Name",ProfileData.ProfileName '
'another attempt
'the below throws a Type Mismatch Error
.AddItem ProfileData.ProfileName, "Profile Name"
.AddItem ProfileData.StartDate, "Start Date"
.AddItem ProfileData.EndDate, "End Date"
.AddItem ProfileData.OnGoing, "Ongoing?"
And (with privately declared module level variables)
Private Sub tbxProfileName_AfterUpdate()
ProfileData.FirstName = tbxProfileName.Text
enter code here
Call UserForm_UpdateListBox
End Sub
At the moment I'm just trying to test the class module and see if I can get the properties values into a variable, or better, get those property values into a range on a hidden page, maybe via a dictionary, and update the list from there? Getting the property values into a listbox seems to be an unwieldy mess...
Sub testClassProfile()
Dim getPropertyAsStringVar As String
Dim NewProfile As clsProfileData
Set NewProfile = New clsProfileData
getPropertyAsStringVar = NewProfile.FirstName
Debug.Print getPropertyAsStringVar
End Sub
Current Debug.Print output is "" ie zip. No default values.
Any advice greatly appreciated.
Please let me know if I'm asking too much at once and I'll try to narrow the scope of the question just to my current issue, I thought the context might be helpful...
Not really an "answer", but it's too hard to respond to your comment with another comment!
Here is an example of how you can pass a class to a userform. Might help!
The TestModule Code
Option Explicit
Public Sub test()
'//Basic declaration of a UserForm
Dim testUF As UserForm1
Set testUF = New UserForm1
'//Now we create a test class - see the Property Get/Set for the string.
Dim testC1 As Class1
Set testC1 = New Class1
testC1.TestString = "Hello"
'//In the UserForm, I've created a property that accepts a class. Assign the
"TestClass" instance tothe UserForm Instance
testUF.Class1 = testC1
testUF.Show
End Sub
...And here is the userform. Note the property that I've added to accept a class instance.
Option Explicit
Private classInstance As Class1
Public Property Get Class1() As Variant
Set Class1 = classInstance
End Property
Public Property Let Class1(ByVal vNewValue As Variant)
Set classInstance = vNewValue
End Property
Private Sub UserForm_Click()
Me.Caption = classInstance.TestString
End Sub
And the class:
Option Explicit
Private mtest As String
Public Property Get TestString() As String
TestString = mtest
End Property
Public Property Let TestString(ByVal vNewValue As String)
mtest = vNewValue
End Property
When you run the "Test" code, you will see that instances of a class and a userform (which is actually just a "Class" as well) are created, and one instance is passed to another. It is (behind the scenes) passed "by reference", so any changes made to TestCl within the userform would be retained outside of the class, allowing it to be modified by the UserForm, and then returned back to the controlling code for use later.
The signature for the Initialize method is
Private Sub Class_Initialize()
... that's not what you have so it will not be run when an object based on the class is created. To make sure it's correct, inside your class code module select "Class" from the left-hand drop-down at the top, then select the required method from the right-hand selection.
Edit: this looks off -
Property Get Ongoing() As Boolean
Ongoing = mOngoing
End Property
Property Let Ongoing(Value As Boolean)
If mEndDate = Date Then
mOngoing = True
End If
End Property
The Ongoing property doesn't really depend on the backing field or need to be set (since its value depends only on mEndDate, so you can drop the Let and just use a Get something like this -
Property Get Ongoing() As Boolean
Ongoing = (mEndDate <= Date)
End Property

Assigning Private Property values

I'm testing out PetaPoco to determine if it meets our needs. I was under the impression that it would delve into my class and see the private properties that I've marked up as valid columns. Unfortunately, it's not behaving as expected. Can you please take a look and let me know if I'm doing something wrong.
My test class:
Imports PetaPoco
<PetaPoco.TableName("PaulTest")>
<PetaPoco.PrimaryKey("ID")>
Public Class PaulTest
<PetaPoco.Column("ID")>
Private Property pvtID As Integer
Private pvtName As String
Private Sub New()
End Sub
Public Sub New(name As String)
If String.IsNullOrEmpty(name) Then
Throw New ArgumentException("Passed Name is empty")
End If
Me.pvtName = name
End Sub
<PetaPoco.Ignore>
Public ReadOnly Property ID As Integer
Get
Return pvtID
End Get
End Property
<PetaPoco.Column("Name")>
Public Property Name As String
Get
Return pvtName
End Get
Set(value As String)
If String.IsNullOrEmpty(value) Then
Throw New ArgumentException("Passed Name is empty")
End If
Me.pvtName = value
End Set
End Property
End Class
The call to the DB (_db is a PetaPoco database object)
Return (_db.Fetch(Of Peta.Domain.PaulTest)(";EXEC selAllPaulTest")).OrderBy(Function(PaulTest) (PaulTest.ID)).ToList()
What's in the database
ID Name
107 Paul
What's being returned:
PaulTest.ID = 0
PaulTest.pvtID = 0
PaulTest.Name = "Paul"
PaulTest.pvtName = "Paul"
<PetaPoco.Ignore> attribute instructs PetaPoco to ignore the column during mapping. As such, the property Id will always be returning the default value of 0.
If you want to prevent the Id property from being modified, comment our or delete the attribute and add a private setter to the Id property as in the following code snippet.
' <PetaPoco.Ignore>
Public Property Id As Integer
Get
Return pvtID
End Get
Private Set(value As Integer)
pvtID = value
End Set
End Property

Pass string to Dialog in VB.net

I have a form and from this I call
dialogPrintDiet.ShowDialog()
which launchs my dialog. I need to pass a string value and need the easiest way to do this in VB.NET .
Try properties, for example setting some text boxes in your dialog:
Property FirstName() As String
Get
Return txtFirstName.Text
End Get
Set(ByVal Value As String)
txtFirstName.Text = Value
End Set
End Property
Property LastName() As String
Get
Return txtLastName.Text
End Get
Set(ByVal Value As String)
txtLastName.Text = Value
End Set
End Property
You can either add a property to the form or you can add a parameter to your form's constructor.
An example of the first method would look like (where Message is the name of the property)
frm.Message = "Some text"
An example of the second method would look like
Dim frm As New SampleForm ( "Some text" )
Your form code would be something like
Public Class SampleForm
Private someMessage As String
Public Sub New(ByVal msg As String)
InitializeComponent()
If Not (String.IsNullOrEmpty(msg)) Then
someMessage = msg
End If
End Sub
Property Message() As String
Get
Return someMessage
End Get
Set(ByVal Value As String)
someMessage = Value
End Set
End Property
End Class

how to add value to combobox item

How can I add data value of each item to combobox in Visual Basic 2010?
Like html drop-down box.
Or is there anyway to add values to each item ?
I am adding item from MySQL database like this:
Command = New MySqlCommand("SELECT * FROM `maillist` WHERE l_id = '" & id & "'", connection)
Command.CommandTimeout = 30
Reader = Command.ExecuteReader()
If Reader.HasRows = True Then
While Reader.Read()
ComboBox1.Items.Add(Reader("name"))
End While
End If
I need to add Reader("ID") as value of each item...
Although this question is 5 years old I have come across a nice solution.
Use the 'DictionaryEntry' object to pair keys and values.
Set the 'DisplayMember' and 'ValueMember' properties to:
Me.myComboBox.DisplayMember = "Key"
Me.myComboBox.ValueMember = "Value"
To add items to the ComboBox:
Me.myComboBox.Items.Add(New DictionaryEntry("Text to be displayed", 1))
To retreive items like this:
MsgBox(Me.myComboBox.SelectedItem.Key & " " & Me.myComboBox.SelectedItem.Value)
I am assuming that you are wanting to add items to a ComboBox on an Windows form. Although Klaus is on the right track I believe that the ListItem class is a member of the System.Web.UI.WebControls namespace. So you shouldn't be using it in a Windows forms solution. You can, however, create your own class that you can use in its place.
Create a simple class called MyListItem (or whatever name you choose) like this:
Public Class MyListItem
Private mText As String
Private mValue As String
Public Sub New(ByVal pText As String, ByVal pValue As String)
mText = pText
mValue = pValue
End Sub
Public ReadOnly Property Text() As String
Get
Return mText
End Get
End Property
Public ReadOnly Property Value() As String
Get
Return mValue
End Get
End Property
Public Overrides Function ToString() As String
Return mText
End Function
End Class
Now when you want to add the items to your ComboBox you can do it like this:
myComboBox.Items.Add(New MyListItem("Text to be displayed", "value of the item"))
Now when you want to retrieve the value of the selected item from your ComboBox you can do it like this:
Dim oItem As MyListItem = CType(myComboBox.SelectedItem, MyListItem)
MessageBox.Show("The Value of the Item selected is: " & oItem.Value)
One of the keys here is overriding the ToString method in the class. This is where the ComboBox gets the text that is displayed.
Matt made an excellent point, in his comment below, about using Generics to make this even more flexible. So I wondered what that would look like.
Here's the new and improved GenericListItem class:
Public Class GenericListItem(Of T)
Private mText As String
Private mValue As T
Public Sub New(ByVal pText As String, ByVal pValue As T)
mText = pText
mValue = pValue
End Sub
Public ReadOnly Property Text() As String
Get
Return mText
End Get
End Property
Public ReadOnly Property Value() As T
Get
Return mValue
End Get
End Property
Public Overrides Function ToString() As String
Return mText
End Function
End Class
And here is how you would now add Generic items to your ComboBox. In this case an Integer:
Me.myComboBox.Items.Add(New GenericListItem(Of Integer)("Text to be displayed", 1))
And now the retrieval of the item:
Dim oItem As GenericListItem(Of Integer) = CType(Me.myComboBox.SelectedItem, GenericListItem(Of Integer))
MessageBox.Show("The value of the Item selected is: " & oItem.Value.ToString())
Keep in mind that the type Integer can be any type of object or value type. If you want it to be an object from one of your own custom classes that's fine. Basically anything goes with this approach.
If you want to use SelectedValue then your combobox must be databound.
To set up the combobox:
ComboBox1.DataSource = GetMailItems()
ComboBox1.DisplayMember = "Name"
ComboBox1.ValueMember = "ID"
To get the data:
Function GetMailItems() As List(Of MailItem)
Dim mailItems = New List(Of MailItem)
Command = New MySqlCommand("SELECT * FROM `maillist` WHERE l_id = '" & id & "'", connection)
Command.CommandTimeout = 30
Reader = Command.ExecuteReader()
If Reader.HasRows = True Then
While Reader.Read()
mailItems.Add(New MailItem(Reader("ID"), Reader("name")))
End While
End If
Return mailItems
End Function
Public Class MailItem
Public Sub New(ByVal id As Integer, ByVal name As String)
mID = id
mName = name
End Sub
Private mID As Integer
Public Property ID() As Integer
Get
Return mID
End Get
Set(ByVal value As Integer)
mID = value
End Set
End Property
Private mName As String
Public Property Name() As String
Get
Return mName
End Get
Set(ByVal value As String)
mName = value
End Set
End Property
End Class
Instead of adding Reader("Name") you add a new ListItem. ListItem has a Text and a Value property that you can set.
Yeah, for most cases, you don't need to create a class with getters and setters. Just create a new Dictionary and bind it to the data source. Here's an example in VB using a for loop to set the DisplayMember and ValueMember of a combo box from a list:
Dim comboSource As New Dictionary(Of String, String)()
cboMenu.Items.Clear()
For I = 0 To SomeList.GetUpperBound(0)
comboSource.Add(SomeList(I).Prop1, SomeList(I).Prop2)
Next I
cboMenu.DataSource = New BindingSource(comboSource, Nothing)
cboMenu.DisplayMember = "Value"
cboMenu.ValueMember = "Key"
Then you can set up a data grid view's rows according to the value or whatever you need by calling a method on click:
Private Sub cboMenu_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cboMenu.SelectionChangeCommitted
SetListGrid(cboManufMenu.SelectedValue)
End Sub
Now you can use insert method instead add
' Visual Basic
CheckedListBox1.Items.Insert(0, "Copenhagen")

PropertyInfo.GetValue() "Object does not match target type."

I'm digging into Reflection for the first time and I'm truely stuck. I've googled everything I can think of. I'm 90% where I wanna be now.
I'm trying to return the value of a Property in a custom class through Reflection.
Here's my class declaration:
Public Class Class2
Private newPropertyValue2 As String
Public Property NewProperty2() As String
Get
Return newPropertyValue2
End Get
Set(ByVal value As String)
newPropertyValue2 = value
End Set
End Property
End Class
The class I've written to look at the class through reflection looks like this:
Public Class ObjectCompare
Private _OriginalObject As PropertyInfo()
Public Property OriginalObject() As PropertyInfo()
Get
Return _OriginalObject
End Get
Set(ByVal value As PropertyInfo())
_OriginalObject = value
End Set
End Property
Public Sub CompareObjects()
Dim property_value As Object
For i As Integer = 0 To OriginalObject.Length - 1
If OriginalObject(i).GetIndexParameters().Length = 0 Then
Dim propInfo As PropertyInfo = OriginalObject(i)
Try
property_value = propInfo.GetValue(Me, Nothing)
Catch ex As TargetException
End Try
End If
Next
End Sub
End Class
I put a breakpoint on the property_value = propInfo.GetValue(Me, Nothing) line to see what the result is.
Here's how I call my code:
Dim test As New Class2
test.NewProperty2 = "2"
Dim go As New ObjectCompare
Dim propInf As PropertyInfo()
propInf = test.GetType.GetProperties()
go.OriginalObject = propInf
go.CompareObjects()
Through reflection I can see the PropertyName and Type, all I need is the value of the Property! Now when I get to the breakpoint, I get a TargetException and the error message says "Object does not match target type." Its now 1AM in the morning and I'm wrecked, any help right now would be appreciated. I've searched MSDN and Google to death and then on last time for fun ;)
Me refers to the ObjectCompare object, which is different than the class from which the PropertyInfo objects were derived (Class2). You need to also pass in an object of the type from which you retrieved the PropertyInfo objects.
Public Sub CompareObjects(ByVal It as Object)
Dim property_value As Object
For i As Integer = 0 To OriginalObject.Length - 1
If OriginalObject(i).GetIndexParameters().Length = 0 Then
Dim propInfo As PropertyInfo = OriginalObject(i)
Try
property_value = propInfo.GetValue(It, Nothing)
Catch ex As TargetException
End Try
End If
Next
End Sub
go.CompareObjects(test)
I'm not really sure I know what you are trying to do here but I'll have a stab at it.
Here is the code that I have come up:
Calling:
Dim test As New Class2
test.NewProperty2 = "2"
Dim go As New ObjectCompare
go.CompareObjects(test)
Class:
Public Class Class2
Private newPropertyValue2 As String
Public Property NewProperty2() As String
Get
Return newPropertyValue2
End Get
Set(ByVal value As String)
newPropertyValue2 = value
End Set
End Property
End Class
Compare:
Public Class ObjectCompare
Public Sub CompareObjects(ByVal MyType As Object)
For Each Prop In MyType.GetType().GetProperties()
Dim value = Prop.GetValue(MyType, Nothing)
Console.WriteLine(value)
Next
Console.ReadLine()
End Sub
End Class