When I am writing a winform in an MVP style, I often wonder how far to go with the separation. Say I have the following situation:
A small form which should display a list of messages, and allow the user to select which ones they want processed. It processes each message in turn. If a message has more than one attachment, a dialog is shown to ask the user to select which attachment should be used for that message.
Now while this is fairly simple, my interface for the message dialog looks like this:
Public Interface IMessageSelector
Event Submit()
Event Cancel()
WriteOnly Property Messages() As IList(Of MessageData)
ReadOnly Property Selected() As IList(Of String)
ReadOnly Property AttachmentView() As IAttachmentScreen
Sub ShowScreen()
Sub CloseScreen()
Sub DisplayWarning(ByVal text As String)
End Interface
In the form I have (roughly) the following:
Public Class frmMessages
Implements IMessageSelector
'...'
Public WriteOnly Property Messages() As IList(Of MessageData) Implements IMessageSelector.Messages
Set(ByVal value As IList(Of MessageData))
For Each d As MessageData In value
Dim r As Grid.Row = grid.Rows.Add
r("id") = d.ID
r("subject") = d.Subject
r("from") = d.Sender
r("received") = d.SendDate
Next
flx.AutoSizeCols()
End Set
End Property
Public ReadOnly Property Selected() As IList(Of String) Implements IMessageSelector.Selected
Get
Dim result As New List(Of String)
For i As Integer = 1 To grid.Rows.Count - 1
If Convert.ToBoolean(grid(i, "selected")) Then
result.Add(grid(i, "id").ToString)
End If
Next
Return result
End Get
End Property
End Class
Now I think that this is ok. There is not logic as such in the population property, and the Selected property just determines which rows have had their checkboxes ticked.
However it has been requested that I add a ‘Select All/None’ checkbox to the form. Where do I add the code for this? As they want a checkbox to tick or detick its not as trivial as it could be. If it were separate buttons, I could just use a for loop in each setting the values to True or False. A checkbox however has some uncertainties:
- Checking the master checkbox should make all rows checked. Fine.
- DeChecking the master checkbox should make all rows unchecked. Also fine.
- Checking one row when none are checked should do what to the master checkbox?
- DeChecking one row when all are checked should do what to the master checkbox?
- 25%/50%/75% of rows are checked, what does the master checkbox look like?
- Some rows are checked. What happens when the checkbox is clicked?
So many questions for such a simple looking feature. With so many possibilities for it maybe it should go into the presenter/interface? At least it’s testable then. Maybe a separate controller for it as it’s not really anything to do with the purpose of the form?
If anyone knows of answers to this I would be very interested to hear them.