Click here to Skip to main content
15,174,684 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
To all professionals I am still stuck, need help from you to come out of the problem. I mentioned earlier also that I am trying to create an user control which is very similar to ConboBox Control. But I don't want to inherit CBox. My User Control is having a Property Items() As ItemsCollection. ItemsColletion is a Collection Class. Given below,

VB.NET
Imports System.ComponentModel

Public Class ItemsCollection
    Inherits System.Collections.ObjectModel.ObservableCollection(Of String)
    Implements INotifyPropertyChanged, IEnumerable, IEnumerator

    Public ReadOnly Property Current() As Object Implements System.Collections.IEnumerator.Current
        Get
            Return Nothing
        End Get
    End Property

    Public Function MoveNext() As Boolean Implements System.Collections.IEnumerator.MoveNext

    End Function

    Public Sub Reset() Implements System.Collections.IEnumerator.Reset
        Return
    End Sub

    Private Sub ItemsCollection_PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Handles Me.PropertyChanged
        If e.PropertyName.ToString = "Count" Then
            MsgBox("Count at P = " & Me.Count.ToString)
        End If
    End Sub
End Class

My User Control is fixed size and having Nine Label Controls covering the total user control. Each Label's Text will be the item. Items Count is now limited to nine. Name of the User Control is "ITrial"

I placed this user control on a Form and added few items in the design time of the form

All the above items are loaded during the load event of the user Control. See below
VB
Private Sub ITrial_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        For I As Integer = 0 To Me.Items.Count - 1
            Select Case I
                Case Is = 0
                    Me.Label1.Text = Me.Items.Item(0)
                Case Is = 1
                    Me.Label2.Text = Me.Items.Item(1)
                Case Is = 2
                    Me.Label3.Text = Me.Items.Item(2)
                Case Is = 3
                    Me.Label4.Text = Me.Items.Item(3)
                Case Is = 4
                    Me.Label5.Text = Me.Items.Item(4)
                Case Is = 5
                    Me.Label6.Text = Me.Items.Item(5)
                Case Is = 6
                    Me.Label7.Text = Me.Items.Item(6)
                Case Is = 7
                    Me.Label8.Text = Me.Items.Item(7)
                Case Is = 8
                    Me.Label9.Text = Me.Items.Item(8)
            End Select
        Next

    End Sub

Running the application it shows like below

The Form7 is having Two buttons. Button1 is having code behind.
VB
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        MsgBox("Count = " & Me.ITrial1.Items.Count.ToString)
        Me.ITrial1.Items.Clear()
        MsgBox("Count = " & Me.ITrial1.Items.Count.ToString)
    End Sub

On Clicking the Button1 MsgBox shows 'Count = 6' next MsgBox shows 'Count = 0'. So far perfect. Here is the problem when Count = 0, I want to remove all the items. Basically dynamically update the labels' Texts. How do I do this. There is a interface INotifyPropertyChanged, where to implement this ? in the collection class I implemented it and PropertyChanged event is available in the collection class. How to get this event in User Control ? Or I have to implement this interface in User control and write some code in Set End Set Part of the Items property. Please suggest what to do. Thanks.

What I have tried:

Mentioned above.
ITrial Designer.vb

VB.NET
<global.microsoft.visualbasic.compilerservices.designergenerated()> _
Partial Class ITrial
    Inherits System.Windows.Forms.UserControl

    'UserControl1 overrides dispose to clean up the component list.
    <system.diagnostics.debuggernonusercode()> _
    Protected Overrides Sub Dispose(ByVal disposing As Boolean)
        Try
            If disposing AndAlso components IsNot Nothing Then
                components.Dispose()
            End If
        Finally
            MyBase.Dispose(disposing)
        End Try
    End Sub

    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer

    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.  
    'Do not modify it using the code editor.
    <system.diagnostics.debuggerstepthrough()> _
    Private Sub InitializeComponent()
        Me.Label1 = New System.Windows.Forms.Label
        Me.Label2 = New System.Windows.Forms.Label
        Me.Label3 = New System.Windows.Forms.Label
        Me.Label4 = New System.Windows.Forms.Label
        Me.Label5 = New System.Windows.Forms.Label
        Me.Label6 = New System.Windows.Forms.Label
        Me.Label7 = New System.Windows.Forms.Label
        Me.Label8 = New System.Windows.Forms.Label
        Me.Label9 = New System.Windows.Forms.Label
        Me.SuspendLayout()
        '
        'Label1
        '
        Me.Label1.BackColor = System.Drawing.Color.FromArgb(CType(CType(255, Byte), Integer), CType(CType(192, Byte), Integer), CType(CType(255, Byte), Integer))
        Me.Label1.Location = New System.Drawing.Point(1, 1)
        Me.Label1.Name = "Label1"
        Me.Label1.Size = New System.Drawing.Size(207, 14)
        Me.Label1.TabIndex = 0
        Me.Label1.Text = "Label1"
        '
        'Label2
        '
        Me.Label2.BackColor = System.Drawing.Color.FromArgb(CType(CType(192, Byte), Integer), CType(CType(192, Byte), Integer), CType(CType(255, Byte), Integer))
        Me.Label2.Location = New System.Drawing.Point(1, 17)
        Me.Label2.Name = "Label2"
        Me.Label2.Size = New System.Drawing.Size(207, 14)
        Me.Label2.TabIndex = 1
        '
        'Label3
        '
        Me.Label3.BackColor = System.Drawing.Color.FromArgb(CType(CType(192, Byte), Integer), CType(CType(255, Byte), Integer), CType(CType(255, Byte), Integer))
        Me.Label3.Location = New System.Drawing.Point(1, 33)
        Me.Label3.Name = "Label3"
        Me.Label3.Size = New System.Drawing.Size(207, 14)
        Me.Label3.TabIndex = 2
        '
        'Label4
        '
        Me.Label4.BackColor = System.Drawing.Color.FromArgb(CType(CType(192, Byte), Integer), CType(CType(255, Byte), Integer), CType(CType(192, Byte), Integer))
        Me.Label4.Location = New System.Drawing.Point(1, 49)
        Me.Label4.Name = "Label4"
        Me.Label4.Size = New System.Drawing.Size(207, 14)
        Me.Label4.TabIndex = 3
        '
        'Label5
        '
        Me.Label5.BackColor = System.Drawing.Color.FromArgb(CType(CType(255, Byte), Integer), CType(CType(255, Byte), Integer), CType(CType(192, Byte), Integer))
        Me.Label5.Location = New System.Drawing.Point(1, 65)
        Me.Label5.Name = "Label5"
        Me.Label5.Size = New System.Drawing.Size(207, 14)
        Me.Label5.TabIndex = 4
        '
        'Label6
        '
        Me.Label6.BackColor = System.Drawing.Color.FromArgb(CType(CType(255, Byte), Integer), CType(CType(224, Byte), Integer), CType(CType(192, Byte), Integer))
        Me.Label6.Location = New System.Drawing.Point(1, 81)
        Me.Label6.Name = "Label6"
        Me.Label6.Size = New System.Drawing.Size(207, 14)
        Me.Label6.TabIndex = 5
        '
        'Label7
        '
        Me.Label7.BackColor = System.Drawing.Color.FromArgb(CType(CType(255, Byte), Integer), CType(CType(192, Byte), Integer), CType(CType(192, Byte), Integer))
        Me.Label7.Location = New System.Drawing.Point(1, 97)
        Me.Label7.Name = "Label7"
        Me.Label7.Size = New System.Drawing.Size(207, 14)
        Me.Label7.TabIndex = 6
        '
        'Label8
        '
        Me.Label8.BackColor = System.Drawing.Color.White
        Me.Label8.Location = New System.Drawing.Point(1, 113)
        Me.Label8.Name = "Label8"
        Me.Label8.Size = New System.Drawing.Size(207, 14)
        Me.Label8.TabIndex = 7
        '
        'Label9
        '
        Me.Label9.BackColor = System.Drawing.Color.FromArgb(CType(CType(255, Byte), Integer), CType(CType(128, Byte), Integer), CType(CType(255, Byte), Integer))
        Me.Label9.Location = New System.Drawing.Point(1, 129)
        Me.Label9.Name = "Label9"
        Me.Label9.Size = New System.Drawing.Size(207, 14)
        Me.Label9.TabIndex = 8
        Me.Label9.Text = "Label9"
        '
        'ITrial
        '
        Me.AutoScaleDimensions = New System.Drawing.SizeF(96.0!, 96.0!)
        Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi
        Me.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle
        Me.Controls.Add(Me.Label9)
        Me.Controls.Add(Me.Label8)
        Me.Controls.Add(Me.Label7)
        Me.Controls.Add(Me.Label6)
        Me.Controls.Add(Me.Label5)
        Me.Controls.Add(Me.Label4)
        Me.Controls.Add(Me.Label3)
        Me.Controls.Add(Me.Label2)
        Me.Controls.Add(Me.Label1)
        Me.Font = New System.Drawing.Font("Verdana", 9.0!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
        Me.Name = "ITrial"
        Me.Size = New System.Drawing.Size(209, 145)
        Me.ResumeLayout(False)

    End Sub

    Friend WithEvents Label1 As System.Windows.Forms.Label
    Friend WithEvents Label2 As System.Windows.Forms.Label
    Friend WithEvents Label3 As System.Windows.Forms.Label
    Friend WithEvents Label4 As System.Windows.Forms.Label
    Friend WithEvents Label5 As System.Windows.Forms.Label
    Friend WithEvents Label6 As System.Windows.Forms.Label
    Friend WithEvents Label7 As System.Windows.Forms.Label
    Friend WithEvents Label8 As System.Windows.Forms.Label
    Friend WithEvents Label9 As System.Windows.Forms.Label

    Public Sub New()

        ' This call is required by the Windows Form Designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.

    End Sub
        

End Class

Form7 Designer.vb

<global.microsoft.visualbasic.compilerservices.designergenerated()> _
Partial Class Form7
    Inherits System.Windows.Forms.Form

    'Form overrides dispose to clean up the component list.
    <system.diagnostics.debuggernonusercode()> _
    Protected Overrides Sub Dispose(ByVal disposing As Boolean)
        Try
            If disposing AndAlso components IsNot Nothing Then
                components.Dispose()
            End If
        Finally
            MyBase.Dispose(disposing)
        End Try
    End Sub

    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer

    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.  
    'Do not modify it using the code editor.
    <system.diagnostics.debuggerstepthrough()> _
    Private Sub InitializeComponent()
        Me.Button1 = New System.Windows.Forms.Button
        Me.ITrial1 = New ITrial.ITrial
        Me.Button2 = New System.Windows.Forms.Button
        Me.SuspendLayout()
        '
        'Button1
        '
        Me.Button1.Location = New System.Drawing.Point(11, 215)
        Me.Button1.Name = "Button1"
        Me.Button1.Size = New System.Drawing.Size(53, 36)
        Me.Button1.TabIndex = 1
        Me.Button1.Text = "Button1"
        Me.Button1.UseVisualStyleBackColor = True
        '
        'ITrial1
        '
        Me.ITrial1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle
        Me.ITrial1.Font = New System.Drawing.Font("Verdana", 9.0!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
        Me.ITrial1.Items.Add("Kanoj")
        Me.ITrial1.Items.Add("Kumar")
        Me.ITrial1.Items.Add("Barman")
        Me.ITrial1.Items.Add("Kaushik")
        Me.ITrial1.Items.Add("Kaustav")
        Me.ITrial1.Items.Add("Rita")
        Me.ITrial1.Location = New System.Drawing.Point(11, 12)
        Me.ITrial1.Name = "ITrial1"
        Me.ITrial1.Size = New System.Drawing.Size(211, 147)
        Me.ITrial1.TabIndex = 2
        '
        'Button2
        '
        Me.Button2.Location = New System.Drawing.Point(70, 214)
        Me.Button2.Name = "Button2"
        Me.Button2.Size = New System.Drawing.Size(53, 36)
        Me.Button2.TabIndex = 3
        Me.Button2.Text = "Button2"
        Me.Button2.UseVisualStyleBackColor = True
        '
        'Form7
        '
        Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
        Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
        Me.ClientSize = New System.Drawing.Size(236, 261)
        Me.Controls.Add(Me.Button2)
        Me.Controls.Add(Me.ITrial1)
        Me.Controls.Add(Me.Button1)
        Me.Name = "Form7"
        Me.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen
        Me.Text = "Form7"
        Me.ResumeLayout(False)

    End Sub

    Friend WithEvents Button1 As System.Windows.Forms.Button
    Friend WithEvents ITrial1 As ITrial.ITrial
    Friend WithEvents Button2 As System.Windows.Forms.Button
End Class
Posted
Updated 2-Feb-21 23:53pm
v2

1 solution

Don't use INotifyPropertyChanged - which ObservableCollection(Of T) already implements, so you don't need to implement it again.

Instead, use the CollectionChanged event:
ObservableCollection<T>.CollectionChanged Event (System.Collections.ObjectModel) | Microsoft Docs[^]
   
Comments
Member 11700078 3-Feb-21 11:06am
   
Thanks a lot Mr. Richard Deeming,
As per your suggestion I remove the implementation of INotifyPropertyChnaged. I am still getting the Event. But with this my problem is not solved. I used this collection class in my User control's Items Property. I need, need to transfer this event in user control level so that the Labels' texts are update as per Items.Count.
Suggest me how do I get the Event in User Control level. Or if I implement INotifyPropertyChanged in User Control level, and any change in user control's 'Items property', will it trigger the event. Suggest what shall I do. Thanks. Regards.
Richard Deeming 3-Feb-21 11:20am
   
It's not clear from your question where your ItemsCollection instance lives, or where you're wanting to display the items. But essentially, you want to subscribe to the CollectionChanged event and update your labels whenever it fires.
Member 11700078 3-Feb-21 13:49pm
   
ItemsCollection instance means New ItemsCollection and that is in my user control level. I mentioned earlier that my User Control is having a Property Called 'Items' As ItemsCollection. Codes are like this <designerserializationvisibility(designerserializationvisibility.content), category("data"),="" description("items="" in="" the="" combo="" box.")=""> _
<editor("system.windows.forms.design.stringcollectioneditor, system.design",="" "system.drawing.design.uitypeeditor,="" system.drawing")=""> _
Public ReadOnly Property Items() As ItemsCollection 'System.Collections.Specialized.StringCollection
Get
Return P1Value
End Get
End Property
Dim P1Value As New ItemsCollection. So I think ItemsCollection instance is in the user control level. if Items' Count property changes or items are cleared accordingly clear all the Labels Texts or if Items Count become 1 only first label will be texted. I think, it doesn't make any difference, collectionChanged or PropertyChanged as long as my user control gets the value of count property of Items property. A ComboBox is best example, during run time if I Execute Me.ComboBox1.Items.Clear(), it removes all the entries of the ComboBox. Same thing I want to do. Thanks and Regards.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900