So you wanna use WinForms (e.g. natively or in a Word Add-In) in C# / VB? Great, there’s good support for databinding controls to objects. And it’s fucked until it works, then it’s great.
General rules
- Don’t trust the designer blindly
Data Source Setup
- Make some public classes, such as below.
- Note we inherit from BindingList
Public Class GlobalSettings
Public Property Name As String
Public Property Disciplines As New DisciplineList
Public Class DisciplineList
Inherits BindingList(Of Discipline)
End Class
Public Class Discipline
Public Property Name As String
Public Sub New()
End Sub
Public Sub New(name As String)
Me.Name = name
End Sub
Public Overrides Function ToString() As String
Return Me.Name
End Function
' optional, for searching
Public Overrides Function Equals(ByVal obj As Object) As Boolean
Dim temp = TryCast(obj, Discipline)
If temp IsNot Nothing Then
Return Me.Name = temp.Name
Else
Return False
End If
End Function
Public Shared Operator =(ByVal o1 As Discipline, ByVal o2 As Discipline) As Boolean
Return o1.Equals(o2)
End Operator '
Public Shared Operator <>(ByVal o1 As Discipline,
ByVal o2 As Discipline) As Boolean
Return Not (o1 = o2)
End Operator
End Class
Form Bindings
- Add a Data Source->Object
- Drag it into the form (or pull a control in directly. note you can change default type)
- IMPORTANT! Manually add a record to the top-most datasource. “sub” datasources, such as a property (e.g. list) of the top-most datasource work without changes.
Me.GlobalSettingsBindingSource.Clear()
Me.GlobalSettingsBindingSource.Add(ThisAddIn.AddinGlobalSettings)
- For simple text, you can bind directly and it’s done in theory. The “DataSource” and “DisplayMember” (which control the list to choose from) seem to stick well. The In practice I find I sometimes need to manually add the (DataBindings) as follows:
Me.txtDefaultAuthor.DataBindings.Clear()
Me.txtDefaultAuthor.DataBindings.Add(New System.Windows.Forms.Binding("Text", My.Settings.Default, "DefaultAuthor", True, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged))
- For combobox values, load and write the selected value manual. This should probably work bound to a single value, but I run into problems. Instead, do it manually:
' Load Form:
If Me.cbDefaultDiscipline.FindStringExact(My.Settings.DefaultDiscipline) > -1 Then
Me.cbDefaultDiscipline.SelectedIndex = Me.cbDefaultDiscipline.FindStringExact(My.Settings.DefaultDiscipline)
End If
' OK Button
My.Settings.DefaultDiscipline = Me.cbDefaultDiscipline.SelectedValue.name