![[C# Webbrowser] BackSpaceキーによる戻る機能を制御](https://rihirostyle.com/wp-content/uploads/2016/09/Webbrowser.png)
C#でWebbrowserコントロールを使ったアプリ制作は色々とハマるポイントがあります。
今回は、BackSpaceキーによる「戻る」機能を制御(抑制)する方法を紹介します。
制御のポイントは以下のとおりです。
- ・Webbrowserコントロールで画面遷移をキャンセルしてもダメ
- → JavaScriptで制御すればOK
- ・input、textareaタグ上では制御しない
- → 入力エリアのBackSpaceキーは使えるように
目次
BackSpaceキーの制御方法
スポンサーリンク
- BackSpaceキーを制御するための、JavaScriptを用意
- 画面読み込み時にJavaScriptを埋め込む
BackSpaceキーを制御するための、JavaScriptを用意
まずは、BackSpaceキーを制御するための、JavaScriptを用意します。
直接JavaScriptのコードを埋め込みたかったのですが、色々調べた結果、外部ファイルにしないとダメとの事。
ここでは、backspaceControle.jsとします。
内容としては、body要素のkeydownイベントを拾い、入力エリア以外でBackSpaceキーが押されたら、イベントをキャンセルするというものです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
function KeyDownFunc(event) { if ((event.keyCode == 8) && (event.srcElement.tagName != "INPUT") && event.srcElement.tagName != "TEXTAREA") { // inpuy、textareaタグ以外でBackSpaceキーを押した場合は無効にする event.preventDefault(); } } if (document.body.addEventListener) { // イベントリスナーに対応している // キーボードを押したときに実行されるイベント document.body.addEventListener("keydown", KeyDownFunc); } else if (document.body.attachEvent) { // アタッチイベントに対応している // キーボードを押したときに実行されるイベント document.body.attachEvent("onkeydown", KeyDownFunc); } |
画面読み込み時にJavaScriptを埋め込む
つぎに、Webbrowserが画面を読み込んだ際に、先程のJavaScriptを埋め込みます。
画面読み込み完了時(DocumentCompleted)に、JavaScriptを埋め込むのですが、サイトによっては、DocumentCompletedイベントが何度も走ります。
Navigated → DocumentCompleted → DocumentCompleted という感じです。
何度もJavaScriptを埋め込むのはマズいので、初回だけ埋め込むよう、isFirstで制御しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
private bool isFirst; private void webBrowser_Navigated(object sender, WebBrowserNavigatedEventArgs e) { // 初回読み込み this.isFirst = true; } private void webBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) { if (!this.isFirst) { // 初回読み込みの場合のみ処理する // 外部JavaScriptを埋め込む HtmlDocument doc = webbrowser.Document; HtmlElement jsElem = doc.CreateElement("SCRIPT"); jsElem.SetAttribute("language", @"JavaScript"); jsElem.SetAttribute("type", @"text/JavaScript"); jsElem.SetAttribute("src", "{パス}/backspaceControle.js"); doc.Body.InsertAdjacentElement(HtmlElementInsertionOrientation.BeforeEnd, jsElem); this.isFirst = false; } } |
ちなみに、ハイブリットアプリで、自前のページにしかアクセスしないのであれば、わざわざWebbrowser側でJavaScriptを埋め込まなくても、html側だけで対応可能かと思います。
スポンサーリンク
ダメだった方法
BackSpaceキー制御を実装するにあたり、海外サイトで対応方法を模索したところ、WebbrowserコントロールのPreviewKeyDownイベントを使う方法が紹介されてました。
流れ
- PreviewKeyDownイベントでBackSpaceキーを検知
- Navigatingイベントで画面遷移をキャンセル
という流れなんですが、この方法には一つ落とし穴が。
落とし穴
2で画面遷移をキャンセルする訳ですが、キャンセルしたにも関わらず、Webbrowserの履歴上から「もどる」べきURL情報が消えてしまいます。(戻った事になる)
一見、BackSpaceキーによる「もどる」動作はキャンセルできても、WebbrowserコントロールのGoBack()を使って、「もどる」ことができませんでした。
試したコードは以下のとおりです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
private bool isPressBackKey; private void webBrowser_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e) { this.isPressBackKey = false; if (e.KeyCode == Keys.Back) { string activeTag = this.webBrowser.Document.ActiveElement.TagName.ToLower(); if (activeTag != "input" && activeTag != "textarea") { // 入力エリア以外でBackSpaceキーが押された場合 this.isPressBackKey = true; } } } private void webBrowser_Navigating(object sender, WebBrowserNavigatingEventArgs e) { if (this.isPressBackKey) { // BackSpaceキーでの遷移をキャンセル e.Cancel = true; this.isPressBackKey = false; } } |
この方法で実現したければ、履歴操作を自前でやる必要がありそうですね。
うーん。。Webbrowserコントロールは便利だけど、色々大変ですね。