質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.31%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

2回答

4769閲覧

DataGridViewの編集中セルでEnterを押した時にセルが下の行に移動するのを制御したい

ohno1011

総合スコア14

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

0クリップ

投稿2023/06/27 08:55

編集2023/06/28 00:42

実現したいこと

DataGridViewで入力用の列があり、常に編集モードにしています。
通常はEnterで下の行に移動していいのですが、
一番下の行でEnterした時に入力中のDataGridViewの表示データを変えて
次のデータの一番上の行の入力から始められるようにしたいと思っています。

(例)
[№]、[名称]、[入力項目] の3列がある

データAを表示中
A-001、名称、入力項目
A-002、名称、入力項目
A-003、名称、入力項目 ←ここの入力項目でEnterを押したら

データ表示を切り替え

B-001、名称、入力項目 ←ここにフォーカスを当てたい
B-002、名称、入力項目
B-003、名称、入力項目

質問

DataGridviewのPreviewKeyDownイベントで入力行が最終行だったら次のデータ表示への切り替えを呼び出し、
DataGridView.CurrentCell = DataGridView[2,0] として一番上の行を選択していますが、

PreviewKeyDownのEnterで下の行に移動する標準の処理があるため
データ表示が切り替わるときに一番上のセルを指定してもその後に1行下のセルにフォーカスが移動してしまいます。

PreviewKeyDownのEnter時にセルが移動する処理を止める方法、
またはEnterでのセル移動より後にセル指定をできるイベントがあれば知りたいです。

(DataGridViewのEditModeプロパティをEditOnEnterにして常に編集モードにしているため、
KeyDownイベントは使用しておりませんが、KeyDownイベントを使う方法でも希望の動作ができれば大丈夫です。)

よろしくお願いします。

6/28追記

極端な話をすると、データ表示の切替関係なく、

C#

1private void dataGridView2_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e) 2{ 3   dataGridView2.CurrentCell = dataGridView2[2,0] 4 e.IsInputKey = true; 5}

この処理でもフォーカスが2行目に渡されてしまいます。
e.IsInputKey = true; でセル移動がキャンセルできていないようです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

YAmaGNZ

2023/06/27 11:03

PreviewKeyDownイベントで判断すればいいのではないですか?
ohno1011

2023/06/28 00:13

AIの自動生成回答のソースを試してみても、 e.IsInputKey = true; を書いてもEnterでの移動がキャンセルできません。
guest

回答2

0

ベストアンサー

C#

1public class DataGridViewEX : DataGridView 2{ 3 public event EventHandler<CancelEventArgs> PressEnter; 4 5 [System.Security.Permissions.UIPermission(System.Security.Permissions.SecurityAction.Demand, Window = System.Security.Permissions.UIPermissionWindow.AllWindows)] 6 protected override bool ProcessDialogKey(Keys keyData) 7 { 8 //Enterキーが押された時は、PressEnterイベントを起こす 9 if ((keyData & Keys.KeyCode) == Keys.Enter) 10 { 11 if (!OnPressEnter()) 12 { 13 return base.ProcessDialogKey(keyData); 14 } 15 else 16 { 17 // キャンセルされた時は処理済みとする 18 return true; 19 } 20 } 21 return base.ProcessDialogKey(keyData); 22 } 23 24 [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand, Flags = System.Security.Permissions.SecurityPermissionFlag.UnmanagedCode)] 25 protected override bool ProcessDataGridViewKey(KeyEventArgs e) 26 { 27 //Enterキーが押された時は、PressEnterイベントを起こす 28 if (e.KeyCode == Keys.Enter) 29 { 30 if (!OnPressEnter()) 31 { 32 return base.ProcessDataGridViewKey(e); 33 } 34 else 35 { 36 // キャンセルされた時は処理済みとする 37 return true; 38 } 39 } 40 return base.ProcessDataGridViewKey(e); 41 } 42 43 private bool OnPressEnter() 44 { 45 if (PressEnter != null) { 46 CancelEventArgs e = new CancelEventArgs(); 47 PressEnter(this,e); 48 49 return e.Cancel; 50 } 51 return false; 52 } 53} 54

このようにDataGridViewを継承したコントロールを作成し、Enterキーが押された時にキャンセル可能なPressEnterというイベントを起こすようにします。

使用するフォーム側は

C#

1// dataGridView1は上で作成したDataGridViewEXとする 2 3 private void dataGridView1_PressEnter(object sender, CancelEventArgs e) 4 { 5 if(dataGridView1.CurrentCell.RowIndex == (dataGridView1.RowCount - 1)) 6 { 7 e.Cancel= true; 8 // データの変更 9 dataGridView1.CurrentCell = dataGridView1[2,0]; 10 } 11 }

と最終行の時はデータ処理を行いキャンセルフラグをtrueにするようにすればいいのではないでしょうか。

投稿2023/06/28 01:45

YAmaGNZ

総合スコア10542

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ohno1011

2023/06/28 07:02

回答ありがとうございます。 標準の機能ではやはり無理みたいですね。 提示頂いたソースを参考にしてカスタムコントロールで制御することができました。 数日悩んでいましたが無事解決できました。 本当にありがとうございました。
guest

0

この回答はGPT-4による自動生成回答です

以下の方法で実現できると思います。

  1. DataGridViewPreviewKeyDownイベントでEnterキーが押されたかどうかを判断します。
  2. 現在のセルが最後の行であるかどうかを確認します。
  3. 最後の行であれば、次のデータ表示に切り替え、フォーカスを最初の行に設定し、e.IsInputKey = true;を設定してEnterキーによるセル移動をキャンセルします。

以下にサンプルコードを示します。

csharp

1private void dataGridView1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e) 2{ 3 if (e.KeyCode == Keys.Enter) 4 { 5 DataGridView dgv = (DataGridView)sender; 6 int currentRowIndex = dgv.CurrentCell.RowIndex; 7 int lastRowIndex = dgv.Rows.Count - 1; 8 9 if (currentRowIndex == lastRowIndex) 10 { 11 // 次のデータ表示に切り替える処理を実行 12 SwitchToNextData(); 13 14 // フォーカスを最初の行に設定 15 dgv.CurrentCell = dgv[2, 0]; 16 17 // Enterキーによるセル移動をキャンセル 18 e.IsInputKey = true; 19 } 20 } 21} 22 23private void SwitchToNextData() 24{ 25 // 次のデータ表示に切り替える処理を実装 26}

この方法で、最後の行でEnterキーを押すと次のデータ表示に切り替わり、最初の行にフォーカスが移動するようになります。

投稿2023/06/27 08:56

teratail-ai

Powered by GPT-4

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.31%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問