トップ回答者
ListView SelectionChangedでのフォーカス移動

質問
-
WPFのListViewに一覧を表示し、クリックにて選択されたデータを編集する画面を作成しています。
SelectionChangedで編集用のテキストボックスに値をセットした後、リストボックス外にあるテキストボックスに
フォーカス移動したいのですが、フォーカスが移動しません。
private void deltailList_SelectionChanged(object sender, SelectionChangedEventArgs e) { var selectedData = (DetailData)deltailList.SelectedItem; itemIdTextBox.Text = selectedData .ItemId.ToString(); itemNameTextBlock.Text = selectedData .ItemName; itemIdTextBox.Focus(); ←フォーカスが移動しない }
ListViewがフォーカスを持ったままとなっています。
PageやWindowsオブジェクトからたどって処理しないとダメなのでしょうか?
対応方法を教えていただけますでしょうか。
回答
-
外にあるテキストボックスにフォーカスは移動していますが、SelectionChangedを抜けた後にフォーカスが戻されてしまうのでBeginInvokeでフォーカス移動を遅らせてみる
private void deltailList_SelectionChanged(object sender, SelectionChangedEventArgs e) { var lv = (ListView)sender; var selectedData = (DetailData)deltailList.SelectedItem; itemIdTextBox.Text = selectedData.ItemId.ToString(); itemNameTextBlock.Text = selectedData.ItemName; System.Windows.Threading.Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() => { itemIdTextBox.Focus(); })); }
個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)
-
文中では「BeginInvoke」と書いていますが、コード中は「Invoke」と誤っているために起きているのかもしれません。(このケースの場合、Invoke はその場で実行し、BeginInvoke は少し後で実行されるはず)
CurrentDispatcher.Invoke の部分を CurrentDispatcher.BeginInvoke に変えてもダメですか?- 編集済み AzuleanMVP, Moderator 2017年3月20日 2:28
- 回答としてマーク まさどん 2017年3月20日 3:43
すべての返信
-
今、検証できる環境におらず申し訳ありませんが、FocusManagerを使ってみたらいかがでしょうか?
(参考)
WPF/XAML : Window 起動時のフォーカスを設定する / コードからフォーカスを設定する
http://increment.hatenablog.com/entry/2015/07/28/231445★良い回答には回答済みマークを付けよう! MVP - .NET http://d.hatena.ne.jp/trapemiya/
-
外にあるテキストボックスにフォーカスは移動していますが、SelectionChangedを抜けた後にフォーカスが戻されてしまうのでBeginInvokeでフォーカス移動を遅らせてみる
private void deltailList_SelectionChanged(object sender, SelectionChangedEventArgs e) { var lv = (ListView)sender; var selectedData = (DetailData)deltailList.SelectedItem; itemIdTextBox.Text = selectedData.ItemId.ToString(); itemNameTextBlock.Text = selectedData.ItemName; System.Windows.Threading.Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() => { itemIdTextBox.Focus(); })); }
個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)
-
ご指摘の通り、いったんTextBoxにフォーカス移動してまた。
Invokeでもまた、ListViewにフォーカスが戻ってしまいましたので、少々カッコ悪いですが
フラグを設けて、ListViewからのフォーカス移動の場合、TextBoxからのフォーカス移動をキャンセルするようにしました。
以下、ソースでうまく動作しました。
ご回答ありがとうございました!
/// <summary> /// 明細選択フラグ /// </summary> private bool isSelectingDetailRow = false; private void deltailList_SelectionChanged(object sender, SelectionChangedEventArgs e) { var selectData = (MainPageDetailViewModel)deltailList.SelectedItem; itemIdTextBox.Text = selectData.ItemId.ToString(); itemNameTextBlock.Text = selectData.ItemName; //明細選択フラグOn isSelectingDetailRow = true; itemIdTextBox.Focus(); } //テキストボックスのフォーカスロスト時にフラグを判定しフォーカスが移動しないよう制御した。 private void itemIdTextBox_PreviewLostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e) { if(isSelectingDetailRow) { e.Handled = true; isSelectingDetailRow = false; } }
-
文中では「BeginInvoke」と書いていますが、コード中は「Invoke」と誤っているために起きているのかもしれません。(このケースの場合、Invoke はその場で実行し、BeginInvoke は少し後で実行されるはず)
CurrentDispatcher.Invoke の部分を CurrentDispatcher.BeginInvoke に変えてもダメですか?- 編集済み AzuleanMVP, Moderator 2017年3月20日 2:28
- 回答としてマーク まさどん 2017年3月20日 3:43