C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[8]: ESCでDataGridViewのセルEdit中断時の処理


(過去ログ 98 を表示中)

[トピック内 17 記事 (1 - 17 表示)]  << 0 >>

■58259 / inTopicNo.1)  ESCでDataGridViewのセルEdit中断時の処理
  
□投稿者/ イノシシ (1回)-(2011/03/30(Wed) 07:59:36)

分類:[.NET 全般] 

はじめまして、イノシシと申します。

 現在、DataGridViewを使って、簡易スプレッドシート機能を作成しております。
 計算機部分が大体できたので、DataGridViewに組み込んでいるのですが、セルの編集をESCキーで中断した場合の処理がうまくできなくて困っています。

1.普段はセルに計算結果を代入しています。
2.CellBeginEditで、セルの内容を計算式に置き換えています。
3.CellEndEditで、セルの計算式を保存した上で、セルの内容を計算結果に置き換えています。

 しかし、セルの編集をEnter等で終了した場合は、上記3において、セルの内容として式が取得できるのですが、ESCで編集を終了した場合は、式ではなく、編集前の計算結果が取得できてしまいます。
 ESCを押下された場合は、2で代入した計算式が欲しい、または、CellEndEditの処理をスキップしたいのですが、どうすれば実現出来るでしょうか。
(もちろん、他のxxxイベントを使えというご指摘でも結構です。)

よろしくお願いいたします。


コード的には以下のような感じです。

CellBeginEditイベントで

int x = e.ColumnIndex;
int y = e.RowIndex;
if(式のマップ.Contains(y * 10 + x)) // 式が登録済みなら表示
datagridview[x, y] = 式のマップ[y * 10 + x].ToString();

CellEndEditイベントで

int x = e.ColumnIndex;
int y = e.RowIndex;

式 ev =式パーサ(e.Value);
式のマップ[y * 10 + x] = ev;
this[x, y] = ev.get計算結果();



引用返信 編集キー/
■58261 / inTopicNo.2)  Re[1]: ESCでDataGridViewのセルEdit中断時の処理
□投稿者/ じゅらく (1回)-(2011/03/30(Wed) 10:09:38)
>  しかし、セルの編集をEnter等で終了した場合は、上記3において、セルの内容として式が取得できるのですが、ESCで編集を終了した場合は、式ではなく、編集前の計算結果が取得できてしまいます。

ところで、セルの編集を何もしないでEnter終了した場合はどうなりますか?
この場合、Esc終了の状態とは同じでしょうか、異なるでしょうか?
引用返信 編集キー/
■58266 / inTopicNo.3)  Re[2]: ESCでDataGridViewのセルEdit中断時の処理
□投稿者/ イノシシ (2回)-(2011/03/30(Wed) 12:00:14)
> ところで、セルの編集を何もしないでEnter終了した場合はどうなりますか?
> この場合、Esc終了の状態とは同じでしょうか、異なるでしょうか?

Enterの場合、無編集でも式が取れます。
(ESCの場合とは異なります。)

 このため、ESCの場合、e.Valueの値が入力されたのか、編集前の値にロールバックされたのかが判定できません。

引用返信 編集キー/
■58269 / inTopicNo.4)  Re[3]: ESCでDataGridViewのセルEdit中断時の処理
□投稿者/ shu (580回)-(2011/03/30(Wed) 12:30:23)
No58266 (イノシシ さん) に返信

KeyDown イベントでなんとかしちゃうとかどうです?
引用返信 編集キー/
■58306 / inTopicNo.5)  Re[3]: ESCでDataGridViewのセルEdit中断時の処理
□投稿者/ じゅらく (2回)-(2011/03/30(Wed) 19:23:19)
No58266 (イノシシ さん) に返信

まとめると、こういうことでしょうか?
(認識に誤りがあったら指摘ください。)
1.セル編集前
 対象セルには何らかの値が入っている(この値の内容を(1)とする)。
2.セル編集開始
 CellBeginEditイベントで式の文字列がセットされる(この式の文字列を(2)とする)。
3.Escにてセル編集終了
 CellEndEditイベントにて、(2)の内容で計算を行いたいが、取得される値は(1)の内容に戻ってしまうので、
 (1)の内容で計算された結果が表示されてしまう。

上記認識で合っているのであれば、例えば、
1.セル編集前
 上記と同じ
2.セル編集開始
 CellBeginEditイベントで、元々入っていた値(1)を何らかの変数等に退避してから
 対象セルに式の文字列をセットする。
3.Escにてセル編集終了
 CellEndEditイベントにて、もしセルの値が(1)の値と同じ(つまり、あらかじめ退避した値と同じ)であれば
 対象セルにCellBeginEditイベントでセットした値と同じものをセットしなおす。
 その後、その式を使って計算を行う。

という方法はどうでしょう。
もちろん、セル編集で、元々入っていた値(1)と同じものを入力してエンター終了した場合は、Escキーを押したときと
同じような振る舞いになりますが。
引用返信 編集キー/
■58312 / inTopicNo.6)  Re[4]: ESCでDataGridViewのセルEdit中断時の処理
□投稿者/ イノシシ (3回)-(2011/03/30(Wed) 21:21:24)
> もちろん、セル編集で、元々入っていた値(1)と同じものを入力してエンター終了した場合は、Escキーを押したときと
> 同じような振る舞いになりますが。

そうなんです、

1."6"が表示されている。(式は"=1+2+3")
2.CellBeginEditで"=1+2+3"を表示する。
3.CellEndEditで"6"が入ってくるが、"6"なのか、無編集なのかが判断できない。

他のセルの参照もサポートするので、計算結果を元に定数に置き換えられると不味いので、正攻法で解決するしかない状況です。



引用返信 編集キー/
■58313 / inTopicNo.7)  Re[4]: ESCでDataGridViewのセルEdit中断時の処理
□投稿者/ イノシシ (4回)-(2011/03/30(Wed) 21:23:11)
> KeyDown イベントでなんとかしちゃうとかどうです?

 実は、KeyDownも調べていたのですが、イベントをうまく拾えなくて他の方法を模索していました。
 この方法で逃げれれば、なんとか解決できそうではあるのですが・・・ orz

引用返信 編集キー/
■58315 / inTopicNo.8)  Re[5]: ESCでDataGridViewのセルEdit中断時の処理
□投稿者/ イノシシ (5回)-(2011/03/30(Wed) 22:00:14)
>  実は、KeyDownも調べていたのですが、イベントをうまく拾えなくて他の方法を模索していました。
>  この方法で逃げれれば、なんとか解決できそうではあるのですが・・・ orz

DataGridViewのEditModeはEditOnKeystrokeOrF2なのですが、
EditingControlShowingで、編集中のDataGridViewTextBoxEditingControlを取得して、
KeyDownをイベントを取得してみましたが、セル内でのキーイベントは取れるのですが、
ESCキーの押下イベントは取れずに悩んでいます。

今、試してみたコード

private void NumberdDataGridView_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
if (e.Control is DataGridViewTextBoxEditingControl){
DataGridView dgv = (DataGridView)sender;

//編集のために表示されているコントロールを取得
DataGridViewTextBoxEditingControl tb = (DataGridViewTextBoxEditingControl)e.Control;

//イベントハンドラの多重登録防止
tb.KeyDown -= new System.Windows.Forms.KeyEventHandler(this.dataGridViewTextBox_KeyDown);
//イベントハンドラを追加
tb.KeyDown += new System.Windows.Forms.KeyEventHandler(this.dataGridViewTextBox_KeyDown);

}
}

//DataGridViewに表示されているテキストボックスのKeyPressイベントハンドラ
private void dataGridViewTextBox_KeyDown(object sender, KeyEventArgs e)
{
//ESCを検出
if (e.KeyCode == Keys.Escape)
Console.WriteLine("ESC");
}

引用返信 編集キー/
■58317 / inTopicNo.9)  Re[5]: ESCでDataGridViewのセルEdit中断時の処理
□投稿者/ shu (586回)-(2011/03/30(Wed) 22:30:07)
No58312 (イノシシ さん) に返信

使えるか分かりませんがFormにbutton配置して(このbuttonはtabstopで止まらないようにしてどこか見えないとこに配置するといいかも)それを
CancelButtonに割り当てるとこっちが優先されるようです。これでまだ問題があるようならウィンドウズメッセージ処理に
なってしまいそうです。
引用返信 編集キー/
■58318 / inTopicNo.10)  Re[6]: ESCでDataGridViewのセルEdit中断時の処理
□投稿者/ じゅらく (3回)-(2011/03/30(Wed) 22:36:43)
No58315 (イノシシ さん) に返信
KeyDownの代わりにKeyPressでもESCキーは反応しませんか?
http://dobon.net/vb/dotnet/datagridview/textboxevent.html に記載されているコードと似ているので、
もしかして、これもお試し済みだったりして。。。
引用返信 編集キー/
■58319 / inTopicNo.11)  Re[6]: ESCでDataGridViewのセルEdit中断時の処理
□投稿者/ じゅらく (4回)-(2011/03/30(Wed) 22:51:30)
2011/03/30(Wed) 22:53:30 編集(投稿者)

No58315 (イノシシ さん) に返信
逆に、Enter等の編集を確定するキーはKeyDownで取れますか?
もしこれがCellEndEditイベント前に取れるのであれば、Escが押されていないと判断できそうですが。。。
引用返信 編集キー/
■58380 / inTopicNo.12)  Re[7]: ESCでDataGridViewのセルEdit中断時の処理
□投稿者/ イノシシ (6回)-(2011/03/31(Thu) 18:44:47)
> KeyDownの代わりにKeyPressでもESCキーは反応しませんか?
> http://dobon.net/vb/dotnet/datagridview/textboxevent.html に記載されているコードと似ているので、
> もしかして、これもお試し済みだったりして。。。

実は、そのページもチェックしていました。 (^_^;)

 KeyPressでESCの押下を検出することはできるのですが・・・・
イベントの発生タイミングが、CellEndEditの後なんです。

 EnterはKeyDownもKeyPressも発生しなかったので、
この方法だけでは、編集の確定・キャンセルの判断には使えなさそうです。 orz


引用返信 編集キー/
■58381 / inTopicNo.13)  Re[6]: ESCでDataGridViewのセルEdit中断時の処理
□投稿者/ イノシシ (7回)-(2011/03/31(Thu) 18:50:06)
> CancelButtonに割り当てる

ボタンなら、フォーム上にたくさん配置しているので、使いたい放題なのですが、
「CancelButtonに割り当てる」とはどうやるのでしょうか?

基本的なことを聞いて申し訳ないです。

引用返信 編集キー/
■58382 / inTopicNo.14)  Re[7]: ESCでDataGridViewのセルEdit中断時の処理
□投稿者/ じゅらく (5回)-(2011/03/31(Thu) 19:44:44)
2011/03/31(Thu) 20:10:13 編集(投稿者)

No58381 (イノシシ さん) に返信

VB2008でしか試していないので、試してほしいのですが、セル編集を行った時、イベントは
CellValueChanged→CellEndEditの順で発生するようです。
また、Escで編集を中断したときには、CellValueChangedは発生せず、CellEndEditのみ発生するようです。
これを利用すればいけそうな気がします。

※セル入力内容退避用変数について追記しました。
例えば、親フォーム内のスコープのフラグ変数1,2およびセル入力内容退避用変数を用意しておきます。
(フラグ変数1はセルが編集中かどうかのフラグ、フラグ変数2はセルが入力によって編集されたかどうかのフラグです。)
・通常時はフラグ変数1=False, フラグ変数2=False
・CellBeginEditイベントが発生したときに、CellBeginEditイベントハンドラ内で、
 セル入力内容退避用変数に元のセルの内容を退避し、式の文字列を設定してからフラグ変数1をTrueにする。
・CellValueChangedイベントが発生した場合、このイベントハンドラ内で
 フラグ変数1=Trueの時だけフラグ変数2をTrueにする。
・CellEndEditイベントが発生した時、フラグ変数2=Trueまたはセルの内容がセル入力内容退避用変数と異なれば編集あり、
 それ以外は編集なし(Esc)と判断する。
 最後にフラグ変数1=False, フラグ変数2=Falseとして初期化する。

これは単なる思い付きですので、どうでしょうか。

なお、shuさんの

> CancelButtonに割り当てる

について代わりに解説すると、フォームのCancelButtonプロパティに任意のボタンを設定すると、
Escキーを押すことによってそのボタンがクリックされることと同じ働きをします。
セル編集中にEscキーを押すと、Escキーの効果はセル編集中断には使用されず、CancelButtonに
設定されたボタンのクリックが行われます。
(この時セルの内容は編集中の内容で確定されます)
この方法は、すでにフォームのCancelButtonプロパティに何らかのボタン(例えばキャンセルボタン)を
割り当てている場合にはこの方法は使用できませんし、そのボタンが容易にクリックできる場所にあると
問題ありそうです。
引用返信 編集キー/
■58383 / inTopicNo.15)  Re[8]: ESCでDataGridViewのセルEdit中断時の処理
□投稿者/ イノシシ (8回)-(2011/03/31(Thu) 20:11:49)
> VB2008でしか試していないので、試してほしいのですが、セル編集を行った時、イベントは
> CellValueChanged→CellEndEditの順で発生するようです。
> また、Escで編集を中断したときには、CellValueChangedは発生せず、CellEndEditのみ発生するようです。
> これを利用すればいけそうな気がします。

ありがとうございます。

先程試してみたところ、C#においても、
「編集時はCellBeginEdit→CellValueChanged→CellEndEdit」、
「キャンセル時はCellBeginEdit→CellEndEdit」であることを
利用して、フラグ(カウンター)で対応できそうです。
(CellBeginEditで値を入れたことで、必ず一回はCellValueChangedが走るので、CellValueChangedが1回か2回かで判定します。)

ありがとうございました。

まとめ、

DataGridViewの編集がEnterキーなどで確定されたか、ESCキーでキャンセルされたか判断する方法はないか?

「編集時はCellBeginEdit→CellValueChanged→CellEndEdit」、
「キャンセル時はCellBeginEdit→CellEndEdit」の順番でイベントが発生することを利用して
CellBeginEditイベントで立てたフラグを、CellValueChangedイベントの発生時に倒すようにする。
CellEndEditイベント発生時に、フラグの状態を見ることで、確定かキャンセルかを判断する。
※ただし、CellBeginEditでセルの値をいじった場合は「CellBeginEdit→CellValueChanged→CellValueChanged→CellEndEdit」または「CellBeginEdit→CellValueChanged→CellEndEdit」なので注意。



解決済み
引用返信 編集キー/
■58384 / inTopicNo.16)  Re[9]: ESCでDataGridViewのセルEdit中断時の処理
□投稿者/ じゅらく (6回)-(2011/03/31(Thu) 20:16:33)
2011/03/31(Thu) 20:40:56 編集(投稿者)

No58383 (イノシシ さん) に返信
一応、方向性が出せて良かったです。
念のため、No58382のロジック部分を修正しましたので、参考にしてみてください。
(これで良さそうな気がします。)

とおもったけど、イノシシさん考案のカウンターの方法の方がもっとシンプルで良さそうですね。
良かったです。
解決済み
引用返信 編集キー/
■58385 / inTopicNo.17)  Re[8]: ESCでDataGridViewのセルEdit中断時の処理
□投稿者/ shu (594回)-(2011/03/31(Thu) 21:37:06)
No58382 (じゅらく さん) に返信

キャンセルボタンの件、フォローありがとうございました。

ESCキーにこだわらず処理が可能なようでよかったです。 > イノシシさん
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -