Working with the mmMoverControl
The mmMoverControl provides standard mover box functionality for your Windows Forms applications. This control is used in MM .NET's mmUsersForm as shown here:

To implement an instance of mmMoverControl in your application, read the information outlined below. The mover control on the Users form is used as an example throughout these steps to give you ideas on how to implement the control in your applications.
Adding a Mover Control to a Form
To add an instance of mmMoverControl to a form, simply drag an mmMoverControl from the Visual Studio Toolbox and drop it on your form:
Setting the Binding Properties
There are two main sets of properties on the mover control. One set pertains to the "Available" list:- AvailableLabelText
- AvailableListBindingFlag
- AvailableListBindingSource
- AvailableListBindingSourceDisplayMember
- AvailableListBindingSourceValueMember
- AvailableListBindingValueSource
- AvailableListBindingValueSourceMember
And the other pertains to the "Selected" list.
- SelectedLabelText
- SelectedListBindingFlag
- SelectedListBindingSource
- SelectedListBindingSourceDisplayMember
- SelectedListBindingSourceValueMember
- SelectedListBindingValueSource
- SelectedListBindingValueSourceMember
The AvailableLabelText and SelectedLabelText properties specify the text for the Available list and the Selected list labels.
All other properties correspond to the standard binding properties for list controls. For details on how to set these properties, see the Help topic Data Binding Windows Forms List Controls.
In mmUsersForm, data views from a single mmRole business object (created in the mmRole object's HookPostGetData method) are used to fill both the Available and Selected lists (the settings are in the format DataTable.DataView.Column). The mmMoverControl properties are set to the following values:
- AvailableListBindingFlag = True
- AvailableListBindingSource = mmRole
- AvailableListBindingSourceDisplayMember = NonMembership.dvNonMembership.Description
- AvailableListBindingSourceValueMember = NonMembership.dvNonMembership.RolePK
- AvailableListBindingValueSource = ""
- AvailableListBindingValueSourceMember = ""
- SelectedListBindingFlag = True
- SelectedListBindingSource = mmRole
- SelectedListBindingSourceDisplayMember = Roles.dvRoles.Description
- SelectedListBindingSourceValueMember = Roles.dvRoles.RolePK
- SelectedListBindingValueSource = ""
- SelectedListBindingValueSourceMember = ""
Specifying a Parent Business Object
You can specify a parent business object for the mover control. Whenever this parent business object does something "interesting", the mover control can respond accordingly. For example, in the Framework's Users Form, the mmUser business object is specified as the parent business object. So whenever the user business object navigates to a different user, the mover control responds by displaying roles for the current user.To specify a parent business object, select the mover control in design mode, then go to the Properties Window and select the ParentBusinessObject property. Click the ellipses button next to the property to launch the Binding Source Selection dialog:

Select the desired business object in the list and click OK.
Plugging into Mover Control Events
mmMoverControl has a few events you can plug into that allow you to execute custom code when important events occur in the control.- RefreshLists
- Delete
- Save
- ParentStateChange
The RefreshLists Event
The RefreshLists event is automatically raised when:- When the Added, Bind, Canceled, Navigated, and Retrieved events are raised on its parent business object
- After the Save event of the mover control is fired
Here is the code in the event handler of the Roles mover control in the Users form:
protected virtual void mvrRoles_RefreshLists(OakLeaf.MM.Main.Business.mmBusinessObject bizObj, OakLeaf.MM.Main.Business.mmBusinessStateChangeEventArgs e)
{
this.oRole.GetUserRoles(e.PrimaryKeyValue);
this.oRole.GetUserNonMemberRoles(e.PrimaryKeyValue);
}The call to GetUserRoles retrieves all roles to which the user belongs. When these are retrieved, the Framework's automatic data binding displays these roles in the Selected list. The call to GetUserNonMemberRoles retrieves all roles the user does NOT belong to. When these are retrieved, they are automatically displayed in the Available list by means of MM .NET automatic data binding.
The Delete Event The Delete event is automatically raised when the mover control's parent business object raises a Deleted event (indicating a parent business object row has been deleted)
Here is the code in the event handler of the Roles mover control in the Users form:
protected virtual void mvrRoles_Delete(OakLeaf.MM.Main.Business.mmBusinessObject bizObj, OakLeaf.MM.Main.Business.mmBusinessStateChangeEventArgs e)
{
this.oRole.DeleteUserRoles(e.PrimaryKeyValue);
}The call to DeleteUserRoles deletes all roles for the user record being deleted in the parent business object.
The Save Event The Save event is automatically raised when the parent business object raises a Saved event.
Here is the code in the event handler of the Roles mover control in the Users form:
protected virtual void mvrRoles_Save(OakLeaf.MM.Main.Business.mmBusinessObject bizObj, OakLeaf.MM.Main.Business.mmBusinessStateChangeEventArgs e)
{
// Update from the current DataSet
DataTable dtSelected = this.mvrRoles.GetSelectedTable();
this.oRole.UpdateUserRoles(e.PrimaryKeyValue, dtSelected);
}This code retrieves the DataTable that fills the Selected list. It then calls the UpdateUserRoles method, passing a reference to the current user and the Selected data table. This method cycles through the data table and adds any new roles and deletes any roles that previously existed for the user but are not in the new list.
The ParentStateChange Event The ParentStateChange event is fired whenever the parent business object raises a state change event.
The following code exists in the mmMoverControl class at the Framework level, responding to parent business object changes:
private void mmMoverControl_ParentStateChange(OakLeaf.MM.Main.Business.mmBusinessObject bizObj, OakLeaf.MM.Main.Business.mmBusinessStateChangeEventArgs e)
{
switch (e.State)
{
case mmBusinessState.Saved:
// Raise the Save event
this.OnSave(bizObj, e);
break;
case mmBusinessState.Deleting:
// Raise the Delete event
this.OnDelete(bizObj, e);
break;
case mmBusinessState.Added:
case mmBusinessState.Bind:
case mmBusinessState.Canceled:
case mmBusinessState.Navigated :
case mmBusinessState.Retrieved:
// Raise the Refresh event
this.OnRefreshLists(bizObj, e);
break;
}
}As you can see in this code, if the parent business object raises a Saved event, the mover's Save event is automatically fired. If the parent business object raises a Deleting event, the mover's Delete event is raised. And if the parent business object raises an Added, Bind, Canceled, Navigated, or Retrieved event, the mover's Refresh event is fired.
© (c) 2026 Oak Leaf Enterprises, Inc., 1996-2026 • Updated: 04/27/18
Comment or report problem with topic
