Trigger parent property - vb.net

How Can I update parent property? My example code below.
When Demo2 property (Class2) set a value, I want run code Demo property (Class1)
Any help would be appreciated.
'My example code
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim d As New Class1
d.Demo.Demo2 = True ' Set value
End Sub
End Class
Public Class Class1
Dim c As Class2
Public Sub New()
c = New Class2
End Sub
Public Property Demo As Class2
Get
Return c
End Get
Set(value As Class2)
'**How can I run this row?**
c = value
End Set
End Property
End Class
Public Class Class2
Private b As Boolean
Public Property Demo2 As Boolean
Get
Return b
End Get
Set(value As Boolean)
b = value
End Set
End Property
End Class

Related

What should I add to a custom class so it works with System.Windows.Forms.Listbox.Items.Contains()..?

What should I add to a custom class so it works with System.Windows.Forms.Listbox.Items.Contains()..?
I've created a class called "FileItem" for handling filenames in ListBoxes. It works as expected, but if I try to use ListBox.Items.Contains() to prevent duplicate items from being added, nothing happens. The Contains() function never returns True.
Here's the code. Add it to a VB.Net form named frmTest with a ListBox1, Button1, and Button2. Run it and press Button1 multiple times. The duplicate warning message is never displayed.
Public Class frmTest
Private Sub frmTest_Load(sender As Object, e As EventArgs) Handles Me.Load
With ListBox1
.DisplayMember = "ShortName"
.ValueMember = "LongName"
End With
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim f As FileItem = New FileItem("C:\Windows\Notepad.exe")
If ListBox1.Items.Contains(f) Then
MsgBox("The file is already added and will be skipped.")
Else
ListBox1.Items.Add(f)
End If
f = Nothing
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim msg As String = ""
For Each item As FileItem In ListBox1.Items
msg &= item.FullName & vbCr
Next
MsgBox(msg)
End Sub
Private Class FileItem
Private ReadOnly _FullName As String
Private ReadOnly _ShortName As String
Public Sub New(ByVal FullName As String)
_FullName = FullName
If FullName.Contains("\") Then
Dim pos As Integer = FullName.LastIndexOf("\")
_ShortName = FullName.Substring(pos + 1)
End If
End Sub
Public ReadOnly Property FullName() As String
Get
Return _FullName
End Get
End Property
Public ReadOnly Property ShortName() As String
Get
Return _ShortName
End Get
End Property
Public Overrides Function ToString() As String
Return _FullName
End Function
End Class
End Class

NotifyPropertyChanged Doesn't work, why?

I am trying to call a Property with INotifyPropertyChanged from ClassB to ClassA, but this doesn't work! What am I doing wrong?
Class A
Public Class ClassA
Implements System.ComponentModel.INotifyPropertyChanged
Public Event PropertyChanged(ByVal sender As Object, ByVal e As
System.ComponentModel.PropertyChangedEventArgs) Implements
System.ComponentModel.INotifyPropertyChanged.Prope rtyChanged
Protected Overridable Sub OnPropertyChanged(ByVal e As
System.ComponentModel.PropertyChangedEventArgs)
RaiseEvent PropertyChanged(Me, e)
End Sub
Private m_prop1 As String
Public Property Prop1() As String
Get
Return m_prop1
End Get
Set(ByVal value As String)
m_prop1 = value
End Set
End Property
End Class
Class B
Public Class Class B
Inherits Class A
Private m_prop2 As String
Public Property Prop2() As String
Get
Return m_prop2
End Get
Set(ByVal value As String)
m_prop2 = value
Dim e As New System.ComponentModel.PropertyChangedEventArgs("Prop1")
OnPropertyChanged(e)
End Set
End Property
End Class
This example works!!.
Class A
Public Class ClassA
Implements System.ComponentModel.INotifyPropertyChanged
Public Event PropertyChanged(ByVal sender As Object, ByVal e As
System.ComponentModel.PropertyChangedEventArgs) Implements
System.ComponentModel.INotifyPropertyChanged.Prope rtyChanged
Protected Overridable Sub OnPropertyChanged(ByVal e As
System.ComponentModel.PropertyChangedEventArgs)
RaiseEvent PropertyChanged(Me, e)
End Sub
Private m_prop1 As String
Public Property Prop1() As String
Get
Return m_prop1
End Get
Set(ByVal value As String)
m_prop1 = value
End Set
End Property
End Class
Class B
Public Class Class B
Inherits Class A
Private m_prop2 As String
Public Property Prop2() As String
Get
Return m_prop2
End Get
Set(ByVal value As String)
m_prop2 = value
Dim e As New System.ComponentModel.PropertyChangedEventArgs("Prop3")
OnPropertyChanged(e)
End Set
End Property
Private m_prop3 As String
Public Property Prop3() As String
Get
Return m_prop3
End Get
Set(ByVal value As String)
m_prop3 = value
End Set
End Property
End Class
But I want to replace that the PropertyChanged "Prop3" call "Prop1" from another class. This is possible?
I solve it, I create a variable m_ClassA in ClassB and then I put it as a parameter "sender" of the OnPropertyChanged method.
Class A
Public Class ClassA
Implements System.ComponentModel.INotifyPropertyChanged
Public Event PropertyChanged(ByVal sender As Object, ByVal e As
System.ComponentModel.PropertyChangedEventArgs) Implements
System.ComponentModel.INotifyPropertyChanged.Prope rtyChanged
Protected Overridable Sub OnPropertyChanged(ByVal sender As Object, ByVal e As
System.ComponentModel.PropertyChangedEventArgs)
RaiseEvent PropertyChanged(sender, e)
End Sub
Private m_prop1 As String
Public Property Prop1() As String
Get
Return m_prop1
End Get
Set(ByVal value As String)
m_prop1 = value
End Set
End Property
End Class
Class B
Public Class ClassB
Inherits ClassA
Private m_ClassA as ClassA
Public Sub New(ByVal c as ClassA)
m_ClassA = c
End Sub
Private m_prop2 As String
Public Property Prop2() As String
Get
Return m_prop2
End Get
Set(ByVal value As String)
m_prop2 = value
Dim e As New System.ComponentModel.PropertyChangedEventArgs("Prop1")
OnPropertyChanged(m_ClassA,e)
End Set
End Property
End Class

Nested user controls events

I'm trying to understand how I can expose an event in this situation:
Class C has an event E
Class B instance an object of class C
Class A instance an object of class B
When the event is raised from class C, is possible to manage it directly from class A?
Public Class C
Public Event E()
Public Sub Function_of_C()
RaiseEvent E()
End Sub
End Class
Public Class B
Public WithEvents m_C as new C
End Class
Public Class A
Public WithEvents m_B as new B
Private Sub Function_of_A() Handles m_B.m_C.E '<-- Doesn't work
'Do something
End Sub
End Class
As explained in the comment to your question. You need to bubble up the event in class B when it receives from C.
Sub Main
Dim test = new A()
End Sub
Public Class C
Public Event E()
Public Sub Function_of_C()
RaiseEvent E()
End Sub
End Class
Public Class B
Public WithEvents m_C as new C
Public Event E()
Public Sub FnB() Handles m_C.E
Console.WriteLine("In B received Event from C")
RaiseEvent E()
End Sub
Public Sub TriggerC()
Console.WriteLine("In B TriggerC, call C.Function_Of_C")
m_C.Function_Of_C()
End Sub
End Class
Public Class A
Public WithEvents m_B as new B
Private Sub Function_of_A() Handles m_B.E
Console.WriteLine("In A received Event from B")
End Sub
public Sub New()
Console.WriteLine("In A constructor, call B.TriggerC")
m_b.TriggerC()
End Sub
End Class
Just as a supplement to Steve's answer, here's an example of the common design pattern to forward events:
Public Class Doorbell
Public Event Ding As EventHandler
Protected Overridable Sub OnDing(e As EventArgs)
RaiseEvent Ding(Me, e)
End Sub
Friend Sub RaiseDing()
Me.OnDing(EventArgs.Empty)
End Sub
End Class
Public Class House
Implements IDisposable
Public Event DoorbellDing As EventHandler
Public Property Doorbell() As Doorbell
Get
Return Me.m_doorbell
End Get
Set(value As Doorbell)
If (Not value Is Me.m_doorbell) Then
Me.UnookDoorbell()
Me.m_doorbell = value
Me.HookDoorbell()
End If
End Set
End Property
Public Sub Dispose() Implements IDisposable.Dispose
Me.UnookDoorbell()
End Sub
Private Sub HandleDoorbellDing(sender As Object, e As EventArgs)
Me.OnDoorbellDing(e)
End Sub
Private Sub OnDoorbellDing(e As EventArgs)
RaiseEvent DoorbellDing(Me, e)
End Sub
Private Sub HookDoorbell()
If (Not Me.m_doorbell Is Nothing) Then
AddHandler Me.m_doorbell.Ding, AddressOf Me.HandleDoorbellDing
End If
End Sub
Private Sub UnookDoorbell()
If (Not Me.m_doorbell Is Nothing) Then
RemoveHandler Me.m_doorbell.Ding, AddressOf Me.HandleDoorbellDing
End If
End Sub
Private m_doorbell As Doorbell
End Class

ListChanged Event not firing?

I have a class with a bindinglist(of T) in it. The bindinglist is bound to a datagridview on my form. When items are added to the bindinglist, they show up in the datagridview however the scrollbar never changes to accommodate for the new data. I am starting to think this is because the Listchanged event isn't being fired (or properly captured by my form). I have my code set up like this:
Data Class:
Public Class data
Implements INotifyPropertyChanged
Public Sub new(byVal att1 as string, ByVal att2 as string)
Attribute1 = att1
Attribute2 = att2
End sub
Private mAttribute1 as string
Public Property Attribute1 as string
Get
return mAttribute1
End get
Set(ByVal value as string)
mAttribute1 = value
OnPropertyChanged("Attribute1")
End Set
End Property
Private mAttribute2 as string
Public Property Attribute2 as string
Get
return mAttribute2
End Get
Set(ByVal value as string)
mAttribute2 = value
OnPropertyChanged("Attribute2")
End Set
End Property
Public Sub OnPropertyChanged(ByVal name As String)
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(name))
End Sub
Public Sub ChangeDataFormat()
'change from one format to the other
End Sub
End Class
Data Generator Class:
Public Class dataGenerator()
private myThread as New System.Theading.Thread(address of StartDataGeneration)
Public Sub new()
mDataList = new bindingList(of Data)
mDataList.RaiseListChangedEvents = True
Private WithEvents mDataList as bindingList(Of Data)
Public readonly DataList as bindingList(of Data)
Get
Return mDataList
End Get
End property
Private Sub StartDataGeneration()
dim att1 as integer = 1
dim att2 as integer = 2
for i as Integer = 0 to 1000
mDataList.Insert(0,New Data(att1.ToString,att2.ToString)
att1 *= 2
att2 *=3
next
End Sub
Public Sub StartDataThread()
myThread.Start()
End Sub
Public Sub ChangeDataFormat()
for each d as data in mDataList
d.ChangeDataFormat()
next
End Sub
End Class
Form:
Public class Form1
Private myGenerators as new BindingList(of dataGenerator)
Private myDataGrids as new BindingList(of DataGridView)
Private Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Mybase.Load
dim NumberOfGenerators as integer = Convert.ToInt32(My.Settings.CraneCount)
for i as integer = 1 to NumberOfGenerators
Dim newGenerator As New DataGenerator()
Dim newTab as Ne tabPage(i.ToString)
Dim NewGrid as New DataGridView
newTab.Controls.Add(newGrid)
newGrid.DataSource = newGenerator.DataList
myGenerators.Add(newGrid)
next
End Sub
Private Sub ButtonStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonStart.Click
for each generator as dataGenerator in myGenerators
generator.StartDataThread()
next
End Sub
Private Sub ButtonChangeFormat_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonChangeFormat.Click
for each generator as dataGenerator in myGenerators
generator.ChangeDataFormat()
next
End Sub
End Class
I know that there is a lot of code but I wanted to be clear. So when I click the start button the new items start appearing, however, once they get to the bottom of the grid the scroll bar doesn't appear. If I click the Change Format button the data changes format and updates in the grid properly. I was under the impression that the ListChanged event would automatically work with a bindinglist and datagridview. I tried calling update and refresh on myDataGridView and setting datagridview.datasource to nothing and then back to DataList.
Am I missing something?

VB.NET: Fields from a class

I have a class being populated from comma separated rows in a text file.
I am trying to have the name property of each object appear in a listbox, then have the rest of the properties of a selected object show up in text boxes. How do I load the properties of the selected object to the correct textbox?
I'm assuming that the class you fill has a list of the objects and that you have already figured out how to fill the listbox...
Private Sub ListBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ListBox1.SelectedIndexChanged
For Each obj As YourObjectType In YourClass.CollectionOfYourObjects
If obj.Name = ListBox1.SelectedItem.ToString Then
Textbox1.Text = obj.Property1
Textbox2.Text = obj.Property2
End If
Next
End Sub
You have one TextBox for every Property and the number of properties is static, isn't it?
You have to set the DisplayMember to the Property's name that you want to see in the Listbox.
This simplified sample should work:
Public Class ListBox
Private Sub ListBox_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim allFoos As New List(Of FooClass)
For i As Int32 = 1 To 10
Dim foo As New FooClass
foo.Name = "Foo_" & i
foo.Prop1 = "Prop1_" & i
foo.Prop2 = "Prop2_" & i
foo.Prop3 = "Prop3_" & i
allFoos.Add(foo)
Next
Me.ListBox1.DataSource = allFoos
Me.ListBox1.DisplayMember = "Name"
End Sub
Private Sub ListBox1_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles ListBox1.SelectedIndexChanged
Dim foo As FooClass = DirectCast(ListBox1.SelectedItem, FooClass)
Me.TxtName.Text = foo.Name
Me.TxtProp1.Text = foo.Prop1.ToString
Me.TxtProp2.Text = foo.Prop2.ToString
Me.TxtProp3.Text = foo.Prop3.ToString
End Sub
End Class
Class FooClass
Private _name As String
Private _prop1 As Object
Private _prop2 As Object
Private _prop3 As Object
Public Property Name() As String
Get
Return _name
End Get
Set(ByVal value As String)
_name = value
End Set
End Property
Public Property Prop1() As Object
Get
Return _prop1
End Get
Set(ByVal value As Object)
_prop1 = value
End Set
End Property
Public Property Prop2() As Object
Get
Return _prop2
End Get
Set(ByVal value As Object)
_prop2 = value
End Set
End Property
Public Property Prop3() As Object
Get
Return _prop3
End Get
Set(ByVal value As Object)
_prop3 = value
End Set
End Property
End Class