ドキュメントのプロパティが変更されたときに、WPF WebBrowser コントロールがデザイン モードにならない
-
21-09-2019 - |
質問
イライラする問題があります。私がやっていることの簡略版は次のとおりです。
C# の UserControl には、ツールバーと埋め込み WebBrowser オブジェクトが含まれています。ツールバーには「編集」ボタンがあり、クリックするとウェブブラウザ コントロールがデザイン モードに設定されます。もう 1 つのボタン「キャンセル」は、デザイン モードをオフにします。
疑似コード (非常に簡略化):
public void SetDesignMode(bool dm) {
IHTMLDocument2 doc = webBrowser.Document as IHTMLDocument2;
if (dm) doc.designMode = "On";
else doc.designMode = "Off";
_designMode = dm;
ReloadDocument(); // setting designmode clears the document element, so it must be reloaded
}
public void OnLoadCompleted() {
IHTMLDocument2 doc = webBrowser.Document as IHTMLDocument2;
if (!_documentLoaded) {
if (_designMode) doc.designMode = "On";
else doc.designMode = "Off";
ReloadDocument();
_documentLoaded = true;
}
}
public void ReloadDocument() {
_documentLoaded = false;
// code that navigates to the document
}
問題:表示されたWebページをクリックして「編集」ボタンをクリックしても、WebBrowserコントロールが編集可能になりません。画像やリンクの上にマウスを置くと、編集用のマウス ポインターではなく、Web ブラウザーのナビゲーション マウス ポインターが表示されます。テキスト内をクリックしてもキャレットが表示されません。
デバッグすると、この状況ではドキュメントの designMode プロパティが実際には "On" に設定されているが、コントロールは "Off" に設定されているかのように動作していることがわかります。
もし私が しないでください 「編集」ボタンをクリックする前にWebページ内をクリックしてください。 すべてが期待どおりに機能します.
詳細:コントロールがデザイン モードのときに [キャンセル] ボタンをクリックすると、ドキュメントがクリックインされていると、対応する (誤った) 動作が発生します。
「編集」、「キャンセル」、「編集」などをクリックするだけです。ドキュメント内をクリックしなくても正常に動作します (マウスオーバー テストでは適切なマウス ポインタが表示され、表示されたドキュメント内のリンクをクリックすると、デザイン モードに応じてリンク ナビゲーションまたは編集が行われます)。
designMode プロパティを変更する前に、別のコントロールが確実にフォーカスを取得できるようにさまざまな手法を試しましたが、違いはありません。MSDN と既知のインターネットの半分を検索しましたが、この種の問題に関する言及は見つかりませんでした。このように designMode プロパティを反転することは非常に珍しいようです。
もう 1 つちょっとした情報:ユーザーコントロールによって実装されたシンクをドキュメントに通知することで、ドキュメントイベントを設定しています。これが問題に関係があるとは思えませんが、完全を期すためにここに含めました。 アップデート: これを無効にしても、問題に関しては何も変わりません。
この問題を認識している人はいますか?
アップデート:SetDesignMode() で Web ブラウザ コントロールを再作成することで、この問題を回避しました。これは醜い解決策ですが、機能し、実際には問題ないようです。ただし、この問題に関するフィードバックには非常に興味があります。MSHTML のバグだと思います。
解決
私たちもまったく同じ問題を抱えていたかどうかはわかりませんが、私の解決策はあなたにとっても同様に機能するはずです。
基本的な問題は、に記載されているように、x64 が designMode 属性をリセットすることのようです。 この記事. 。私の場合、Webブラウザをインスタンス化した後に「On」に設定しましたが、DocumentCompletedイベントでは再び「Inherit」になってしまいました。DocumentCompleted でこれを「オン」に戻すと編集可能になりますが、ドキュメントはクリアされます。DocumentText を再度設定すると、破滅ループ全体が再開されます。
そこで私が見つけた解決策の 1 つは、DocumentText の設定を控え、代わりに空のドキュメントを作成し、本文の (この時点では null ではなくなっている) InnerHtml プロパティを設定することでした。
doc.designMode = "On"; // enable editing
// designMode change resets the document, create it anew
webBrowser1.Document.Write("<html><body></body></html>")
webBrowser1.Document.Body.InnerHtml = "myDocumentText"
明らかに、これはテキストの準備ができている場合にのみ機能し、URL に移動している場合には機能しません。ただし、私にとってうまくいった別の解決策があり、それはより簡単で安全だと思われます。で見つけました この答え ラフィングジョン著。最初の行はアプリケーションによって異なると思いますが、webBrowser1.Document に直接 IHTMLDocument がありました。
doc = webBrowser1.Document.DomDocument as IHTMLDocument2;
if (doc != null && doc.body != null)
((HtmlBody)doc.body).contentEditable = "true";
他のヒント
WebBrowser
は、あなたがそれをクリックしたときにフォーカスを取得し、何とかそれに上保持しているように、それは私に聞こえます。あなたは、ボタンをクリックすることができるかどうかを確認後、WebBrowser
をクリックし、その後、キーボードのTabキーを押す(<全角>はのはずWebBrowser
オフフォーカスを移動)と
あなたは、その後、プログラムでボタンを集中することでButton.MouseEnter
イベントとコール((Button)sender).Foucs()
にハンドラをアタッチしようとすることができます。