Spread Windows Forms 12.0 Product Documentation
Factors of Keyboard Map Usage
Spread Windows Forms 12.0 Product Documentation > Developer's Guide > Managing Keyboard Interaction > Factors of Keyboard Map Usage

There are several factors involved with using mappings that should be understood before either changing the default mappings or creating your own mappings. These include:

Focus Location and Operation Mode

Keyboard mapping is dependent on two factors: the focus location and the operation mode. For example, the Enter key has different actions depending if it is pressed when a cell editor has the focus or when the control has the focus. If the cell editor has the focus (the cell is in edit mode), pressing Enter takes the cell out of edit mode. If the control has the focus, and not a child control (such as a cell editor), pressing the Enter key puts the active cell in edit mode. For operation modes, for example, if the sheet is in ReadOnly mode, its map does not have entries for moving the active cell because there is no active cell. Customize the default maps keeping focus locations and operation modes in mind. Each mapping is like a dictionary, defining a meaning (an action) for each keystroke. Just as different dictionaries are needed for different languages, different keyboard maps are needed for different focus locations and operation modes.

The Spread component provides two input maps, WhenFocused and WhenAncestorOfFocused, one for each type of focus location. The WhenFocused map contains keyboard bindings that apply when the Spread component has focus but not when a child control has focus. Placing an entry in the WhenFocused input map is equivalent to overriding the IsInputKey and IsInputChar methods (to return true for the keystroke) and the OnKeyDown, OnKeyPress, and OnKeyUp methods (to process the keystroke). The WhenAncestorOfFocused map contains keyboard bindings that apply when either the Spread component or a child control has focus. Placing an entry in the WhenAncestorOfFocused map is equivalent to overriding the ProcessDialogKey and ProcessDialogChar methods (to process the keystroke).

The first factor is what receives the keystroke or keystroke combination. Keystroke processing in .NET is handled in two phases: a pre-processing phase and a normal-processing phase. Most keystroke processing in Spread is handled during the pre-processing phase, which corresponds to the WhenAncestorOfFocused input map mode (refer to InputMapMode enumeration settings). In the pre-processing phase, keystrokes are handled by the IsInputChar, IsInputKey, ProcessDialogChar, and ProcessDialogKey methods. The normal-processing phase corresponds to the WhenFocused input map mode. In the normal-processing phase, keystrokes are handled by the OnKeyDown, OnKeyPress, and OnKeyUp methods (which raise the KeyDown, KeyPress, and KeyUp events respectively).

For a typical Spread component, most interactions that occur while you are working with the component occur as part of the WhenAncestorOfFocused input map. Actions such as moving the active cell, selecting a range of cells, and others would be part of this map. For example, pressing the Tab key moves the active cell, even if a cell is in edit mode. In contrast, some keys are only mapped when there is not a cell in edit mode (the component has the focus, but not a cell editor). For example, the equals (=) key does not perform an action if pressed when a cell is in edit mode. If no cell is in edit mode, pressing the equals key starts formula editing for the active cell.

Global versus Local

The Spread component provides a parent global input map, which is shared by all Spread components in a project. When you customize the input map for a Spread component, you are customizing a local map for only that component.

The global map allows the Spread component to save memory by sharing a map. The local map lets you customize settings, then clear them later and retain the default settings as listed in Default Keyboard Maps.

Therefore, when working with input maps, you need to be aware of which methods work with the global map and which work with the local map.

The Get method to return input maps searches all input maps, including the global and the local. The Put, Remove, and Clear methods only work with the local map. For example, if you call the Remove method, it removes the custom settings for a local map, but does not change the default settings provided by the global map.

You cannot modify the global map itself, but if you want to do so, you can create a new input map and assign it to be the global map instead of the default one provided.

Parent versus Child Workbook

The keyboard bindings in the parent workbook's input map do not affect the child workbook. The Spread component contains one or more instances of the SpreadView class. In a hierarchy setup, the parent is one instance of the SpreadView class and each child is an instance of the SpreadView class. Each instance of the SpreadView class has its own input map. This gives you the option of having different keyboard behaviors at each level of the hierarchy. If you want a particular keyboard behavior at all levels in the hierarchy then you would need to modify the input map for the parent and each child.

Enter Keystroke Binding Exception

Most of the built-in keystrokes only have a binding in the WhenAncestorOfFocused map and thus only let you override one binding. The Enter keystroke is the exception. In the WhenAncestorOfFocused map, the Enter keystroke is bound to the StopEditing action. In the WhenFocused map, the Enter keystroke is bound to the StartEditing action. Thus, you need to override both bindings. Here is some sample code:

C#
Copy Code
InputMap whenAncestorOfFocusedMap = spread.GetInputMap(InputMapMode.WhenAncestorOfFocused);
InputMap whenFocusedMap = spread.GetInputMap(InputMapMode.WhenFocused);
whenAncestorOfFocusedMap.Put(new Keystroke(Keys.Enter, Keys.None), SpreadActions.MoveToNextRow);
whenFocusedMap.Put(new Keystroke(Keys.Enter, Keys.None), SpreadActions.MoveToNextRow);

Action Called None

The None action is a special action indicating that the keystroke is not processed by the input map.

Placing a None action in an input map is similar to calling the Remove method on the input map. The difference between them is that a None action can override an entry in a parent map whereas the Remove method only affects entries in the specified map. By default, the WhenFocused and WhenAncestorOfFocused maps have no direct entries but do have indirect entries via parent maps. The WhenFocused's parent map contains no binding for the Esc key.

See Also