対象: Spread 19 for Windows Forms (Mescius社)
所要時間: 約1分
ごあいさつ
こんにちは、「様子見駆動開発技師フジワラ」です
SPREAD(メシウス社)を使ったVB6からC#のマイグレーション作業で気になった点を書きためてます…今回はキーボード操作まわりです。
SPREAD内セルをEnterキーで移動させたい
業務アプリあるある、「Enterキーで次のセルに進みたい」というやつです。
デフォルトの SPREAD は Enterキーで行確定するだけで、セルは移動しません。さらに行末を超えたら次のコントロール(保存ボタンなど)にフォーカスを移したい、という要件もよくあります。
ActiveX 版 SPREAD 7.0 では…
ActiveX 版では Enter キーの動作もデザイナのプロパティで設定できました。シンプルでした。
WinForms 版では該当プロパティが見当たらず、コードで制御する必要があります。
あ、行末を超えたら次のコントロールへ移動はもともとなかったですね。
解決策:2ステップで実装する
Step 1:SPREADのEnterキーデフォルト動作を無効化する
まずSPREAD組み込みの Enter キー処理を無効化します。初期化時に1回呼べばOKです。
private void DisableEnterKey(FpSpread spread)
{
var im = spread.GetInputMap(InputMapMode.WhenAncestorOfFocused);
im.Put(new Keystroke(Keys.Enter, Keys.None), SpreadActions.None);
}
Step 2:KeyDownイベントで独自のセル移動処理を呼ぶ
KeyDownイベントで Enter を拾い、セル移動ロジックを呼び出します。
Shift+Enter で逆順移動、最後のセルを抜けたら次のコントロール(保存ボタン等)へフォーカスが移ります。
private void FpSpread1_KeyDown(object? sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Return)
SetFocusNextCell(fpSpread1, btnSave);
}
private void SetFocusNextCell(FpSpread spread, Control nextControl)
{
var sheet = spread.Sheets[0];
for (int row = sheet.ActiveRowIndex; row < sheet.RowCount; row++)
{
int startCol = (row == sheet.ActiveRowIndex) ? sheet.ActiveColumnIndex + 1 : 0;
// col方向にボタン、チェックボックス、フォーカス不可、非表示を除くセルにフォーカス移動
// 行末で次行先頭へ移動する
for (int col = startCol; col < sheet.ColumnCount; col++)
{
var cellType = sheet.Columns[col].CellType;
if (cellType is not FarPoint.Win.Spread.CellType.ButtonCellType
&& cellType is not FarPoint.Win.Spread.CellType.CheckBoxCellType
&& sheet.Columns[col].CanFocus
&& sheet.Columns[col].Visible)
{
sheet.SetActiveCell(row, col);
return;
}
}
}
nextControl?.Focus();
}
今回、移動対象から除外しているのは、ボタン・チェックボックス・フォーカス不可・非表示列 です。実際の仕様に合わせて調整してください。
また、shift+Enterで前のセルに移動は要否判断してこのコード参照して実装してみてください。
ポイントまとめ
-
InputMapで Enter キーのデフォルト動作を無効化するのが先決 - セル移動ロジックは
KeyDownイベントで自前実装する - 自前実装なのでスキップするセル(ボタン・チェックボックスなど)を自由に制御できる
- 最終セルを超えたら
nextControl?.Focus()で次のコントロールへ渡せる
おわりに
「Enterで次のセルに移動」はシンプルな要件なのに、意外とコード量が必要ですよね。
この記事にたどりついたみなさんの作業効率が少しでもあがることを願います。