トップ回答者
標準のDataGridで、Enterによる横移動を行う方法

質問
-
こんにちは。
標準のDataGridでEnterによるセルの横移動が、簡単に実装できないかと探っています。
しかし、簡単にENTERをTABに変えるような方法は見つかっていません。今までのところ
1)押されたキーコードを変えてしまう方法
見つけられなかった。2)カレントセルの位置をコントロールする方法
DataGridのKeyUpイベントでカレントセルの位置から計算して新しい位置を指定する方法
この方法は簡単ですが、既にフォーカスが移動しているため、一瞬選択状態が移動する事になり、見た目に問題があります。
(ただし、セルの編集開始状態をコントロールしなければならない。)3)DataGridTemplateColumn に配置したコントロールでイベントを拾って処理
配置したTextBoxでイベントを拾いなんとかできないかなと模索
EnterのKeyUpイベントを拾わないので断念
TABは拾うのですが…という感じです。
また、ENTERでの移動は、ENTERの意味が「編集確定」?のせいか、編集状態が維持されないので、ENTERキーそのものでの移動に意味があるのか?という疑問は残るのですが・・・編集状態の制御も別途実装しないとだめみたいですし。
結局、ENTERキーとTABキーの入力をすり替える方法が無ければ、簡単にENTERでの横移動を実現できないと思うのです。
3rdParty製品やDataGrid(もどき)を0から実装すると可能な事は解っていますが、標準のDataGrid でENTERキーによる横移動を実装する方法はあるのでしょうか?
K.Oumi2010年3月18日 1:37
回答
-
標準のDataGridで、という前提なので微妙ですが自前でDataGridを継承したCustomDataGridを定義してOnKeyDownをオーバーライドしてEnterKeyが押された時に処理を乗っとるようにすれば2)の方法での見た目の問題は回避できるような気がします。最後の列でEnter押した時に次の行、とかいう動きまで自力で再現する必要がありますけど…参考までにコードです
public class CustomDataGrid : DataGrid { public CustomDataGrid() : base() { } protected override void OnKeyDown(KeyEventArgs e) { if (e.Key == Key.Enter) { this.MoveNextCell(); e.Handled = true; }; base.OnKeyDown(e); } private void MoveNextCell() { DataGridColumn currentcol = this.CurrentColumn; // 現在のカラムが最大かどうか bool isLastCol = (currentcol.DisplayIndex == this.Columns.Count - 1); if (!isLastCol) { // 編集を終了して次へ this.CommitEdit(); this.CurrentColumn = this.Columns[currentcol.DisplayIndex + 1]; this.BeginEdit(); }; } }
2010年3月18日 5:52
すべての返信
-
標準のDataGridで、という前提なので微妙ですが自前でDataGridを継承したCustomDataGridを定義してOnKeyDownをオーバーライドしてEnterKeyが押された時に処理を乗っとるようにすれば2)の方法での見た目の問題は回避できるような気がします。最後の列でEnter押した時に次の行、とかいう動きまで自力で再現する必要がありますけど…参考までにコードです
public class CustomDataGrid : DataGrid { public CustomDataGrid() : base() { } protected override void OnKeyDown(KeyEventArgs e) { if (e.Key == Key.Enter) { this.MoveNextCell(); e.Handled = true; }; base.OnKeyDown(e); } private void MoveNextCell() { DataGridColumn currentcol = this.CurrentColumn; // 現在のカラムが最大かどうか bool isLastCol = (currentcol.DisplayIndex == this.Columns.Count - 1); if (!isLastCol) { // 編集を終了して次へ this.CommitEdit(); this.CurrentColumn = this.Columns[currentcol.DisplayIndex + 1]; this.BeginEdit(); }; } }
2010年3月18日 5:52 -
nk9k さん ありがとうございます。
でもなぁ、これと同じ事やってうまくいかなかったんだよなぁ(TT) なんて、良く見ると
e.Handled = true;
ぐは・・・・
やられた orz
MSDNより・・・KeyEventArgs Hendled プロパティ
ルーティング イベントを処理済みとマークし、イベント ルート上の他のハンドラーによって、同じイベントが繰り返し処理されるのを防ぐかどうかを示す値を取得または設定します。
これってそういう意味だったのか・・・
結局、継承して作ったって、KeyDownイベントでフォーカス移動するのはかわんないんだ。なんでかわからんけどしょうがない・・・なんて諦めていたのですが。
うわー、これが無かったせいで自分のカスタムコントロールは、だめだったんだ(TT)
助かりました。ありがとうございます。
ちなみに、さくっと動いたもので「えー!」と慌てて MoveNextCellメソッドを本気でMSDNで探したという・・・(^^;なんというお馬鹿。
DataGridのKeyDownイベントの説明も
継承元へのメモ : OnKeyDown をオーバーライドする場合は、Handled を true に設定すると、登録されているデリゲートがイベントを受け取らないようにできます。 ルーティング イベントと KeyDown プロパティの詳細については、「Silverlight のイベントの概要」を参照してください。
う~ん読んだつもりだったのに、全然気がつかなかった・・・なんだかなぁ・・・
K.Oumi2010年3月18日 7:14