In the project that I have been working on, we wanted to be able to have a drop down box that allowed multiple selections from a list and another that allowed multiple selections from a tree structure. The default behaviour of the Flex combo box is to allow the selection of one item. As soon as an item is selected, the drop down closes and the selected value is displayed in the combo box. In order to determine what the selected item is, the programmer has to interrogate the combo box or use an event handler to capture the selection. This behaviour presented some problems when endeavouring to implement an application using a model-view-presenter style of programming. It was even more difficult to follow when requiring multiple selections.
Examining solutions to multiple selection showed that many programmers had worked out ways of programming around the combo boxes behaviour. We also originally took this path but could never quite get the box to behave the way we wanted. It either closed unexpectedly or didn't reflect the current selections. It was time to rethink the fundamental design of the combo box.
What did we anticipate as the behaviour for our multiple selection control. We wanted a button control that looked like a combo box that when clicked displayed a drop down of either a list of values or a tree of values. We didn't just want the drop down to display the selected items highlighted, we wanted a check box that would show the selected items. For the tree, we wanted to go one step further and have a node and its branch selected when the node was selected. The button should indicate the number of items selected and a tool tip should show a list of the items selected. We were seeking some fundamental changes to the operation of the combo box.
To address our behavioural requirements, we decided that we needed at least three components. The base button, the drop down control, and a data model that reflected the state of the control. The next issue was to assign behaviours and here I will admit that we didn't always make the best decisions. However, programming is about learning so we have learnt and adapted our design. What I describe here is more of a proposal for the next iteration in the design.
The button has responsibility for opening the drop down and reporting the state of the selections. It makes no attempt to retain the selection state or dictate the closing of the drop down or the selection process. In some respects, it is a fairly simple button. It depends on the drop down and the model to find out the current state of the selections and the drop down control.
The drop down and the model are closely related. If a tree control is used for the drop down then the data model needs to reflect the tree structure (OK, in Flex, the data model doesn't need to be a tree if you implement a descriptor that will make the model appear as a tree but that is another issue). In our case, we implemented a selectable collection and a selectable tree data structure. These not only held the data but also reflected the selection status of the items. The data model also returned a count of the selected items and a text list of the selected items. The model is responsible for maintaining the state of the control's component parts.
The drop down looks after knowing how it should be opened and how and when it should be closed. It also knows how to interpret the underlying data model to produce the appropriate selection states on the screen. The drop down control is concerned with how to present the data and not with how to manage the state of the data.
To make the control components more flexible, they should be implemented to a standard interface. That way, the button component can use a factory object to build the drop down and not be concerned as to the type of the drop down or the behaviour of the drop down. A similar principle applies to the data model. This way, the programmer can extend the model to new applications without having to redevelop from scratch.
There is another issue that I am still working through. Should the data model provided to the control conform to the controls requirements or should there be a factory object that can build the data model required by the control? Using a factory would mean that the control could be reused in a wider range of applications without enforcing the programmer to know how to prepare the data. For more complex data structures, the programmer may need to provide mechanisms for interpretation but that isn't really a major issue.
So far we have versions of these controls for a list and for a tree but I see the next being for selection from a grid of icons. As time permits once we settle in the UK, I may look at developing these controls for the open source market. My primary concern is that as many of the components making up the controls are reusable and reflect a flexibility of design.