# Using Input Maps with Action Maps

Learn how to effectively use Input Maps and Action Maps in Spread.NET to process keystrokes and map specific keys to specific actions.

## Content

Internally, the **SpreadView** object uses an input map paired with an action map to process a keystroke. An input map ([InputMap](/spreadnet/api/latest/online-win/FarPoint.Win.Spread/FarPoint.Win.Spread.InputMap.html) object) is used to convert a key stroke ([KeyStroke](/spreadnet/api/latest/online-win/FarPoint.Win.Spread/FarPoint.Win.Spread.Keystroke.html) object) to an object that identifies the action. An action map ([ActionMap](/spreadnet/api/latest/online-win/FarPoint.Win.Spread/FarPoint.Win.Spread.ActionMap.html) object) is used to convert the object to an action.

## Using Code

1. Create a new [InputMap](/spreadnet/api/latest/online-win/FarPoint.Win.Spread/FarPoint.Win.Spread.InputMap.html) object for which to map keys and actions.
2. Set an existing input map equal to the [InputMap](/spreadnet/api/latest/online-win/FarPoint.Win.Spread/FarPoint.Win.Spread.InputMap.html) object you created.
3. Use the [InputMap](/spreadnet/api/latest/online-win/FarPoint.Win.Spread/FarPoint.Win.Spread.InputMap.html) class **Put** method to map specific keys to specific actions.

## Example

For example, the internal code that handles KeyDown events looks something like this:

```csharp
object actionMapKey = GetInputMap(InputMapMode.WhenFocused).Get(new Keystroke(e.KeyCode, e.Modifiers));
if (actionMapKey != null)
{
    Action action = GetActionMap().Get(actionMapKey);
    if (action != null)
    {
        action.PerformAction(this);
        e.Handled = true;
    }
}
```

```vbnet
Dim actionMapKey As Object = GetInputMap(InputMapMode.WhenFocused).Get(New Keystroke(e.KeyCode, e.Modifiers))
If Not (actionMapKey Is Nothing) Then
    Dim action As Action = GetActionMap().Get(actionMapKey)
    If Not (action Is Nothing) Then
        action.PerformAction(Me)
        e.Handled = True
    End If
End If
```

Excel uses Ctl+9 and Ctl+Shift+9 to hide and unhide rows. Suppose you want to implement this feature in Spread. You could create the following classes to define the hide and unhide actions.

```csharp
private class HideRowAction : Action
{
    public override void PerformAction(object source)
    {
        if (source is SpreadView)
        {
            SpreadView spread = (SpreadView)source;
            SheetView sheet = spread.Sheets[spread.ActiveSheetIndex];
            if (sheet.SelectionCount > 0)
            {
                for (int i = 0; i < sheet.SelectionCount; i++)
                {
                CellRange range = sheet.GetSelection(i);
                if (range.Row == -1)
                 sheet.Rows[0, sheet.RowCount - 1].Visible = false;
                else
                sheet.Rows[range.Row, range.Row + range.RowCount - 1].Visible = false;
   
         }
      }
      else
      {
            sheet.Rows[sheet.ActiveRowIndex].Visible = false;
         }
       }
   }
}
   
private class UnhideRowAction : Action
{
   public override void PerformAction(object source)
   {
      if (source is SpreadView)
      {
         SpreadView spread = (SpreadView)source;
         SheetView sheet = spread.Sheets[spread.ActiveSheetIndex];
         if (sheet.SelectionCount > 0)
         {
            for (int i = 0; i < sheet.SelectionCount; i++)
            {
               CellRange range = sheet.GetSelection(i);
               if (range.Row == -1)
                  sheet.Rows[0, sheet.RowCount - 1].Visible = true;
               else
                  sheet.Rows[range.Row, range.Row + range.RowCount - 1].Visible = true;
            }
         }
         else
         {
            sheet.Rows[sheet.ActiveRowIndex].Visible = true;
         }
      }
   }
}
```

```vbnet
Private Class HideRowAction
    Inherits Action
    
    Public Overrides Sub PerformAction([source] As Object)
     If TypeOf [source] Is SpreadView Then
      Dim spread As SpreadView = CType([source], SpreadView)
      Dim sheet As SheetView = spread.Sheets(spread.ActiveSheetIndex)
      If sheet.SelectionCount > 0 Then
        Dim i As Integer
        For i = 0 To sheet.SelectionCount - 1
            Dim range As CellRange = sheet.GetSelection(i)
            If range.Row = - 1 Then
                sheet.Rows(0, sheet.RowCount - 1).Visible = False
            Else
                sheet.Rows(range.Row, range.Row + range.RowCount - 1).Visible = False    
            End If
        Next i
      Else
            sheet.Rows(sheet.ActiveRowIndex).Visible = False
      End If
     End If
    End Sub 'PerformAction
End Class 'HideRowAction
    
Private Class UnhideRowAction
    Inherits Action
    
    Public Overrides Sub PerformAction([source] As Object)
     If TypeOf [source] Is SpreadView Then
      Dim spread As SpreadView = CType([source], SpreadView)
      Dim sheet As SheetView = spread.Sheets(spread.ActiveSheetIndex)
        If sheet.SelectionCount > 0 Then
          Dim i As Integer
          For i = 0 To sheet.SelectionCount - 1
            Dim range As CellRange = sheet.GetSelection(i)
            If range.Row = - 1 Then
                sheet.Rows(0, sheet.RowCount - 1).Visible = True
            Else
                sheet.Rows(range.Row, range.Row + range.RowCount - 1).Visible = True
            End If
        Next i
     Else
        sheet.Rows(sheet.ActiveRowIndex).Visible = True
     End If
    End If
   End Sub 'PerformAction
End Class 'UnhideRowAction
```

You could then add the keystrokes and actions to the maps as follows.

```csharp
InputMap im = spread.GetInputMap(InputMapMode.WhenFocused);
ActionMap am = spread.GetActionMap();
im.Put(new Keystroke(Keys.D9, Keys.Control), "HideRow");
im.Put(new Keystroke(Keys.D9, Keys.Control | Keys.Shift), "UnhideRow");
am.Put("HideRow", new HideRowAction());
am.Put("UnhideRow", new UnhideRowAction());
```

```vbnet
Dim im As InputMap = spread.GetInputMap(InputMapMode.WhenFocused)
Dim am As ActionMap = spread.GetActionMap()
im.Put(New Keystroke(Keys.D9, Keys.Control), "HideRow")
im.Put(New Keystroke(Keys.D9, Keys.Control Or Keys.Shift), "UnhideRow")
am.Put("HideRow", New HideRowAction())
am.Put("UnhideRow", New UnhideRowAction())
```

For more information, refer to the methods in [ActionMap](/spreadnet/api/latest/online-win/FarPoint.Win.Spread/FarPoint.Win.Spread.ActionMap.html) and [InputMap](/spreadnet/api/latest/online-win/FarPoint.Win.Spread/FarPoint.Win.Spread.InputMap.html) classes.

```csharp
public class FpSpread : ...{   ...
   public ActionMap GetActionMap();
   public void SetActionMap(ActionMap value);
}
   
public class SpreadView : ...
{
   ...
   public ActionMap GetActionMap();
   public void SetActionMap(ActionMap value);
}
   
public class ActionMap{   
public ActionMap();   
public object[] AllKeys();   
public object[] Keys();   
public ActionMap Parent { get; set; }   
public int Size { get; }   
public void Clear();   
public Action Get(object key);   
public void Put(object key, Action action);   
public void Remove(object key);}   
public abstract class Action{   public abstract void PerformAction(object source);}
```

```vbnet
Public Class FpSpread ...
...
Public Function GetActionMap() As ActionMap

Public Sub SetActionMap(value As ActionMap)

End Class 'FpSpread

Public Class SpreadView ...
...
Public Function GetActionMap() As ActionMap

Public Sub SetActionMap(value As ActionMap)

End Class 'SpreadView

Public Class ActionMap

Public Sub ActionMap()
Public object AllKeys()
Public object Keys()
Public ActionMap Parent
Public Size As Integer
Public Sub Clear()
Public Action Get(By key As object)
Public Sub Put(By key As object, By action As Action)
Public Sub Remove(By key As object)
}

Public MustOverride Class Action
{
Public Sub PerformAction(By source As object)
}
```

## See Also

[Keyboard Interaction](/spreadnet/docs/latest/online-win/overview/spwin-devguide/spwin-mappingkeys)
[Underlying Keystroke Processing](/spreadnet/docs/latest/online-win/overview/spwin-devguide/spwin-mappingkeys/spwin-maps-keysyswin)
[Factors of Keyboard Map Usage](/spreadnet/docs/latest/online-win/overview/spwin-devguide/spwin-mappingkeys/spwin-maps-factors)
[Default Keyboard Navigation](/spreadnet/docs/latest/online-win/overview/spwin-devguide/spwin-mappingkeys/spwin-maps-keybdnav)
[Default Keyboard Maps](/spreadnet/docs/latest/online-win/overview/spwin-devguide/spwin-mappingkeys/spwin-maps-defaultmaps)
[Deactivating the Default Keyboard Map](/spreadnet/docs/latest/online-win/overview/spwin-devguide/spwin-mappingkeys/spwin-maps-defaultoff)
[Changing the Default Keyboard Map](/spreadnet/docs/latest/online-win/overview/spwin-devguide/spwin-mappingkeys/spwin-maps-defaultnew)
[Customizing the Input Maps](/spreadnet/docs/latest/online-win/overview/spwin-devguide/spwin-mappingkeys/spwin-maps-custominput)
[Changing an Input Map for a Child View](/spreadnet/docs/latest/online-win/overview/spwin-devguide/spwin-mappingkeys/spwin-maps-child)
[Saving and Loading Map Files](/spreadnet/docs/latest/online-win/overview/spwin-devguide/spwin-mappingkeys/spwin-maps-load)
[Using the Excel Compatibility Input Maps](/spreadnet/docs/latest/online-win/overview/spwin-devguide/spwin-mappingkeys/spwin-maps-using)