Here's a sample UserControl with some Controls bound to the properties of a public class object (JobDefinition
). The public class is part of the Project classes.
A property of this class is an Enumerator - JobStatusEnum
- used to further test how the public property works when the class object is decorated with a TypeConverter
attribute.
The public JobDefinition
class uses a TypeConverter of type ExpandableObjectConverter, to allow the editing of the UserControl Property of type JobDefinition
.
This class also implements the INotifyPropertyChanged interface, commonly used to notify binding clients that a Property value has changed, raising a PropertyChanged event.
A BindingSource is then used to bind some of the UC's Controls to a Property of the JobDefinition
class, setting the DataSource of the BindingSource to the UserControl's public Job
property.
All the Controls' Bindings are added in the UserControl's OnLoad
method override, calling the BindControls()
method.
Edit:
If you don't want/need to have active bindings when a new instance of the UserControl is created, you can set the BindingSource's DataSource property to the object type that will generate the source of the data, without specifying an instance of that object.
BindingSource.DataSource:
The DataSource property can be set to a number of data sources, including types, objects, and lists of types. The resulting data source will be exposed as a list.
In this case, the initialization procedure of the UserControl can be changed in:
Public Sub New()
InitializeComponent()
m_Source = New BindingSource() With {.DataSource = GetType(JobDefinition)}
End Sub
The UserControl's child controls will show empty at Design-Time and the Job
property, though listed in the Designer's PropertyGrid, will also be empty.
It can set to a new object at any time.
At Design-Time, the UC's JobDefinition
property type can be set to any value. These setting will be preserved when the Form is loaded, since the class is serialized by the Designer.
All bound Controls will react to the Property changes and the new values will be reflected in the UI at Design-Time.
At Run-Time, all properties can of course be set to different values: the UI and the UserControl's Properties will reflect the new values.
The Property of type JobDefinition
can also be set to a new, different object. The BindingSource will take care of the bound Control's DataBindings
, updating the properties when its DataSource is changed.
Private Sub btnJobChangeValue_Click(sender As Object, e As EventArgs) Handles btnJobChangeValue.Click
MyUserControl1.Job.JobName = txtNewJobName.Text
End Sub
Private Sub btnNewJob_Click(sender As Object, e As EventArgs) Handles btnNewJob.Click
Dim newJob = New JobDefinition() With {
.JobID = 5,
.JobName = "New Job",
.JobStatus = JobStatusEnum.Starting
}
MyUserControl1.Job = newJob
End Sub
The sample UserControl:
Imports System.ComponentModel
Imports System.Windows.Forms
Partial Public Class MyUserControl
Inherits UserControl
Private m_Job As JobDefinition = Nothing
Private m_Source As BindingSource = Nothing
Public Sub New()
InitializeComponent()
m_Source = New BindingSource()
Me.Job = New JobDefinition() With {
.JobID = 1,
.JobName = "Initial Job",
.JobStatus = JobStatusEnum.Starting
}
End Sub
Public Property Job As JobDefinition
Get
Return m_Job
End Get
Set(ByVal value As JobDefinition)
m_Job = value
m_Source.DataSource = m_Job
End Set
End Property
Protected Overrides Sub OnLoad(e As EventArgs)
MyBase.OnLoad(e)
BindControls()
End Sub
Friend Sub BindControls()
txtJobID.DataBindings.Add(New Binding("Text", m_Source, "JobID", False, DataSourceUpdateMode.OnPropertyChanged))
txtJobName.DataBindings.Add(New Binding("Text", m_Source, "JobName", False, DataSourceUpdateMode.OnPropertyChanged))
txtJobStatus.DataBindings.Add(New Binding("Text", m_Source, "JobStatus", False, DataSourceUpdateMode.OnPropertyChanged))
End Sub
End Class
JobDefinition
class object:
Imports System.ComponentModel
<TypeConverter(GetType(ExpandableObjectConverter))>
Public Class JobDefinition
Implements INotifyPropertyChanged
Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
Private m_JobID As Integer
Private m_JobName As String
Private m_JobStatus As JobStatusEnum
Public Property JobID As Integer
Get
Return m_JobID
End Get
Set(ByVal value As Integer)
m_JobID = value
OnPropertyChanged(NameOf(Me.JobID))
End Set
End Property
Public Property JobName As String
Get
Return m_JobName
End Get
Set(ByVal value As String)
m_JobName = value
OnPropertyChanged(NameOf(Me.JobName))
End Set
End Property
Public Property JobStatus As JobStatusEnum
Get
Return m_JobStatus
End Get
Set(ByVal value As JobStatusEnum)
m_JobStatus = value
OnPropertyChanged(NameOf(Me.JobStatus))
End Set
End Property
Friend Sub OnPropertyChanged(PropertyName As String)
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(PropertyName))
End Sub
End Class
The JobStatusEnum
enumerator:
Public Enum JobStatusEnum As Integer
Starting
Started
Pending
Stopped
Completed
End Enum
Downloadable Project (Google Drive)
The Obj
folder is empty, so rebuild the Solution before opening the Form or the UserControl in the Form's Designer.