Reputation: 887
I created this property in order to add more than one attachment:
Private ReadOnly Index As Integer
Private mAttachments(1 To 10) As String
Private ReadOnly NewAttachment As String
Public Property AddAttachment() As String
Get
If Index >= 1 And Index <= UBound(mAttachments) Then
AddAttachment = mAttachments(Index)
End If
Return mAttachments(Index)
End Get
Set
If Index >= 1 And Index <= UBound(mAttachments) Then
mAttachments(Index) = NewAttachment
Else
MessageBox.Show("Error")
End If
End Set
End Property
To test it the call I used this two files, but I am receiving emails without the attachments. Can't understand what I might be doing wrong.
mAttachments(0) = "C:\teste.txt"
mAttachments(1) = "C:\teste2.txt"
Upvotes: 0
Views: 149
Reputation: 32248
You should probably have a dedicated class to handle the Attachments list.
Option 1:
If you want to keep the array, you make this work overloading an indexed Property.
The non-indexed Property returns a copy of the array to force the consumers to use your property to change values in the array (since a copy is returned, any change will only apply to the copy, not the original array which handles errors).
The m_MaxAttachments
Field is not strictly necessary. You can use the Array.Length
.
You cannot directly replace the Array with a List(Of String)
with this setup.
Private ReadOnly m_MaxAttachments As Integer = 10
Private ReadOnly m_Attachments(m_MaxAttachments - 1) As String
Public ReadOnly Property MaxAttachments As Integer = m_MaxAttachments
Public ReadOnly Property Attachments As String()
Get
Return m_Attachments.Select(Function(s) s).ToArray()
End Get
End Property
Public Property Attachments(index As Integer) As String
Get
If index < 0 OrElse index >= m_MaxAttachments Then
AttachmentError(index)
Return String.Empty
End If
Return m_Attachments(index)
End Get
Set
If index >= 0 AndAlso index < m_MaxAttachments Then
m_Attachments(index) = Value
Else
AttachmentError(index)
End If
End Set
End Property
Private Sub AttachmentError(value As Integer)
MessageBox.Show($"Index out of range: {value} Valid range: [0, {m_MaxAttachments - 1}]")
End Sub
Now you can use the indexer to Get/Set a value from/to the underlying Array of strings or iterate a copy of the collection using the non-indexed Property. E.g.:
Attachments(0) = "[Some Path]"
Attachments(1) = "[Other Path]"
Attachments(10) = "[10th Path]" '<- A MessageBox informs that the index is out of range
Option 2:
Use a Class object to handle a List(Of String)
and let the Public Property just act as a mediator.
The class exposes methods that allow to add/remove/iterate (this last is left to you, to implement if needed; the overloaded indexed Property, moved to the class, only returns a ReadonlyCollection
or an indexed value).
Imports System.Collections.ObjectModel
Private ReadOnly Property m_Attachments As MyAttachments = New MyAttachments()
Public ReadOnly Property Attachments As MyAttachments
Get
Return m_Attachments
End Get
End Property
Public Property Attachments(index As Integer) As String
Get
Return m_Attachments.Values(index)
End Get
Set
If index >= 0 AndAlso index < MyAttachments.MaxAttachments Then
m_Attachments.Values(index) = Value
End If
End Set
End Property
So you can write:
Attachments.Add("Some Path 1")
Attachments.Add("Some Path 2")
Attachments.Add("Some Path 3")
Attachments.Clear()
Attachments.Add("New Path")
' If you add more items than the max Capacity, it will return
' the number of strings added to the List
Dim Items Added = Attachments.AddRange([Some IEnumerable(Of String)])
Attachments.Remove("New Path")
Attachments.RemoveAt(0)
and so on.
Handler Class:
Public Class MyAttachments
Private Shared ReadOnly m_MaxCount As Integer = 10
Private ReadOnly m_Values As New List(Of String)(m_MaxCount)
Public Shared ReadOnly Property MaxAttachments As Integer = m_MaxCount
Public ReadOnly Property Values As ReadOnlyCollection(Of String)
Get
Return m_Values.AsReadOnly()
End Get
End Property
Public Property Values(index As Integer) As String
Get
Return m_Values(index)
End Get
Set
If index >= 0 AndAlso index < MaxAttachments Then
m_Values(index) = Value
End If
End Set
End Property
Public Sub Add(value As String)
If m_Values.Count < m_Values.Capacity Then
m_Values.Add(value)
End If
End Sub
Public Function AddRange(values As IEnumerable(Of String)) As Integer
Dim startItemsCount = m_Values.Count
Dim indexer = startItemsCount
For Each value As String In values
If indexer >= m_MaxCount Then Exit For
Add(value)
indexer += 1
Next
Return indexer - startItemsCount
End Function
Public Sub Remove(value As String)
m_Values.Remove(value)
End Sub
Public Sub RemoveAt(index As Integer)
If index >= 0 AndAlso index < m_Values.Count Then
m_Values.RemoveAt(index)
End If
End Sub
Public Sub RemoveRange(indexes As Integer())
For Each index As Integer In indexes
RemoveAt(index)
Next
End Sub
Public Sub RemoveRange(values As String())
For Each value As String In values
Remove(value)
Next
End Sub
Public Sub Clear()
m_Values.Clear()
End Sub
Public ReadOnly Property Count As Integer
Get
Return m_Values.Count
End Get
End Property
End Class
Upvotes: 1