Once again I am surprised at the lack of *working* examples of vb.net code. In this particular case, that may or may not be a completely fair statement because the examples I found (and there were quite a few) could very well have worked, they were just incomplete. Here is a complete example of using an app.config file to define a collection of reports. This will create a parent object with specific configuration information in it, and a collection of child elements which also have custom properties. While no two situations are alike, this should provide you with something that you can modify to suit your own needs. As it turns out, the most complete example I did find was on the msdn site. This is the example that I followed:
ConfigurationElementCollection ClassIn your app.config...
<configsections>
<section name="ServerReports" type="assemblyName.RSPrintSetup, assemblyName" allowdefinition="Everywhere" allowExeDefinition="MachineToApplication" restartOnExternalChanges="true" />
</configsections>
<serverreports name="PrivateLoanLetters" lockallelementsexcept="Reports" servername="http://rijb-sql2/ReportServer/?" tempfolder="C:\Plexus\Private Loans Letters\Private Loans Letters\Temp\">
<reports>
<clear>
<add name="WebApprovals" reporttype=".pdf" runtime="4:00:00" />
<add name="WebDenialsS" reporttype=".pdf" runtime="2:00:00" />
<add name="WebDenialsC" reporttype=".pdf" runtime="2:00:00" />
<add name="WebCertifications" reporttype=".pdf" runtime="4:00:00" />
</reports>
</serverreports>
And the VB.NET Classes...
Imports System
Imports System.Configuration
Imports System.Collections
Imports System.Collections.Generic
Imports System.Collections.Specialized
Imports System.Reflection
Imports System.Text
Public Class RSReport
Inherits ConfigurationElement
' Test flag.
Private Shared _displayIt As Boolean = False
Public Sub New()
End Sub 'New
_
Public Property Name() As String
Get
Return CStr(Me("name"))
End Get
Set(ByVal value As String)
Me("name") = value
End Set
End Property
_
Public Property RunTime() As String
Get
Return CStr(Me("RunTime"))
End Get
Set(ByVal value As String)
Me("RunTime") = value
End Set
End Property
_
Public Property ReportType() As String
Get
Return CStr(Me("ReportType"))
End Get
Set(ByVal value As String)
Me("ReportType") = value
End Set
End Property
Protected Overrides Sub DeserializeElement(ByVal reader As System.Xml.XmlReader, ByVal serializeCollectionKey As Boolean)
MyBase.DeserializeElement(reader, serializeCollectionKey)
' Enter your custom processing code here.
If _displayIt Then
Console.WriteLine( _
"UrlConfigElement.DeserializeElement({0, {1) called", _
IIf(reader Is Nothing, "null", _
reader.ToString()), _
serializeCollectionKey.ToString())
End If
End Sub 'DeserializeElement
Protected Overrides Function SerializeElement(ByVal writer _
As System.Xml.XmlWriter, _
ByVal serializeCollectionKey As Boolean) As Boolean
Dim ret As Boolean = MyBase.SerializeElement(writer, serializeCollectionKey)
' Enter your custom processing code here.
If _displayIt Then
Console.WriteLine( _
"UrlConfigElement.SerializeElement({0, {1) called = {2", _
IIf(writer Is Nothing, "null", _
writer.ToString()), _
serializeCollectionKey.ToString(), _
ret.ToString())
End If
Return ret
End Function 'SerializeElement
Protected Overrides Function IsModified() As Boolean
Dim ret As Boolean = MyBase.IsModified()
' Enter your custom processing code here.
Console.WriteLine("UrlConfigElement.IsModified() called.")
Return ret
End Function 'IsModified
End Class
_
Public Class ReportsCollection
Inherits ConfigurationElementCollection
Public Sub New()
Dim url As RSReport = CType(CreateNewElement(), RSReport)
' Testing: Manually add the element to the collection.
'Add(url)
End Sub 'New
Public Overrides ReadOnly Property CollectionType() _
As ConfigurationElementCollectionType
Get
Return ConfigurationElementCollectionType.AddRemoveClearMap
End Get
End Property
Protected Overloads Overrides Function CreateNewElement() As ConfigurationElement
Return New RSReport()
End Function 'CreateNewElement
Protected Overloads Overrides Function CreateNewElement(ByVal elementName As String) As ConfigurationElement
Return New RSReport(elementName)
End Function 'CreateNewElement
Protected Overrides Function GetElementKey( _
ByVal element As ConfigurationElement) As [Object]
Return CType(element, RSReport).Name
End Function 'GetElementKey
Public Shadows Property AddElementName() As String
Get
Return MyBase.AddElementName
End Get
Set(ByVal value As String)
MyBase.AddElementName = value
End Set
End Property
Public Shadows Property ClearElementName() As String
Get
Return MyBase.ClearElementName
End Get
Set(ByVal value As String)
MyBase.AddElementName = value
End Set
End Property
Public Shadows ReadOnly Property RemoveElementName() As String
Get
Return MyBase.RemoveElementName
End Get
End Property
Public Shadows ReadOnly Property Count() As Integer
Get
Return MyBase.Count
End Get
End Property
Default Public Shadows Property Item( _
ByVal index As Integer) As RSReport
Get
Return CType(BaseGet(index), RSReport)
End Get
Set(ByVal value As RSReport)
If Not (BaseGet(index) Is Nothing) Then
BaseRemoveAt(index)
End If
BaseAdd(index, value)
End Set
End Property
Default Public Shadows ReadOnly Property Item( _
ByVal Name As String) As RSReport
Get
Return CType(BaseGet(Name), RSReport)
End Get
End Property
Public Function IndexOf( _
ByVal rpt As RSReport) As Integer
Return BaseIndexOf(rpt)
End Function 'IndexOf
Public Sub Add(ByVal rpt As RSReport)
BaseAdd(rpt)
' Add custom code here.
End Sub 'Add
Protected Overrides Sub BaseAdd( _
ByVal element As ConfigurationElement)
BaseAdd(element, False)
' Add custom code here.
End Sub 'BaseAdd
Public Overloads Sub Remove( _
ByVal url As RSReport)
If BaseIndexOf(url) >= 0 Then
BaseRemove(url.Name)
End If
End Sub 'Remove
Public Sub RemoveAt(ByVal index As Integer)
BaseRemoveAt(index)
End Sub 'RemoveAt
Public Overloads Sub Remove(ByVal name As String)
BaseRemove(name)
End Sub 'Remove
Public Sub Clear()
BaseClear()
End Sub 'Clear ' Add custom code here.
End Class
Public Class RSPrintSetup
Inherits ConfigurationSection
Public Sub New()
Me.OutputOptions = New List(Of String)
End Sub
_
Public Property Name() As String
Get
Return CStr(Me("name"))
End Get
Set(ByVal value As String)
Me("name") = value
End Set
End Property
_
Public Property TempFolder() As String
Get
Return CStr(Me("TempFolder"))
End Get
Set(ByVal value As String)
Me("TempFolder") = value
End Set
End Property
' Declare a collection element represented
' in the configuration file by the sub-section
'
' Note: the "IsDefaultCollection = false"
' instructs the .NET Framework to build a nested
' section like ....
_
Public ReadOnly Property Reports() _
As ReportsCollection
Get
Dim urlsCollection _
As ReportsCollection = _
CType(Me("Reports"), ReportsCollection)
Return urlsCollection
End Get
End Property
Protected Overrides Sub DeserializeSection( _
ByVal reader As System.Xml.XmlReader)
MyBase.DeserializeSection(reader)
' Enter custom processing code here.
End Sub 'DeserializeSection
Protected Overrides Function SerializeSection( _
ByVal parentElement As ConfigurationElement, _
ByVal name As String, _
ByVal saveMode As ConfigurationSaveMode) As String
Dim s As String = _
MyBase.SerializeSection(parentElement, _
name, saveMode)
' Enter custom processing code here.
Return s
End Function 'SerializeSection
End Class