更改文档属性时,WPF WebBrowser控件不会进入设计模式

时间:2009-11-19 19:53:57

标签: c# wpf webbrowser-control mshtml

我有一个令人沮丧的问题。这是我正在做的简化版本:

c#中的UserControl包含工具栏和嵌入式WebBrowser对象。工具栏包含一个“编辑”按钮,单击该按钮可在设计模式下设置Web浏览器控件。另一个按钮“取消”关闭了设计模式。

伪代码(非常简化):

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
}

问题: 如果单击显示的网页,然后单击“编辑”按钮,WebBrowser控件将不会变为可编辑状态。在图片/链接上方移动时的鼠标指针显示Web浏览器导航鼠标指针,而不是编辑指针。如果我单击文本,则不会显示插入符号。

调试显示在这种情况下文档上的designMode属性实际上设置为“On”,但控件的行为就像设置为“Off”一样。

如果我点击网页,然后点击“修改”按钮,一切都按预期工作

精化: 如果在控件处于设计模式时单击“取消”按钮,如果单击了文档,则会得到相应的(错误)行为。

只需单击“编辑”,然后“取消”,然后“编辑”等,无需单击文档就可以正常工作(鼠标悬停测试显示正确的鼠标指针,我会根据设计获得链接导航或编辑模式,如果我单击显示的文档中的链接。)

我尝试了各种技术来确保在更改designMode属性之前另一个控件获得焦点,但它没有任何区别。我搜索过MSDN和已知互联网的一半,并没有发现任何关于这类问题的提及。像这样翻转designMode属性似乎很不寻常。

还有一小撮信息:我通过使用usercontrol实现的接收器建议文档来设置文档事件。我怀疑这应该对这个问题有任何影响,但为了完整起见,我把它包含在这里。 更新:禁用此功能不会改变有关此问题的任何内容。

有人认出这个问题吗?

更新 我通过在SetDesignMode()中重新创建Web浏览器控件来解决这个问题。这是一个丑陋的解决方案,但它的工作原理确实看起来不错。不过,我对这个问题的任何反馈都很感兴趣。我相信这是MSHTML中的一个错误。

2 个答案:

答案 0 :(得分:8)

我不太确定我们是否有完全相同的问题,但我想我的解决方案也适合你。

基本问题似乎是x64重置了designMode属性,如this article中所述。就我而言,我把它设置为" On"在实例化webbrowser之后,但是在DocumentCompleted事件中,它是"继承"再次。将其设置回"开"在DocumentCompleted中使其可编辑,但清除文档。再次设置DocumentText会重新启动整个doom循环。

所以我找到的一个解决方案是不要设置DocumentText,而是创建一个空文档,然后设置body(此时不再为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时。但是,还有另一种解决方案对我有用,看起来更容易,更安全。我在LaughingJohn的this answer找到了它。我想第一行取决于你的应用程序,你直接在webBrowser1.Document中有IHTMLDocument。

doc = webBrowser1.Document.DomDocument as IHTMLDocument2;
if (doc != null && doc.body != null)
    ((HtmlBody)doc.body).contentEditable = "true";

答案 1 :(得分:0)

听起来像WebBrowser当你点击它并以某种方式坚持它时获得焦点。试试这个:点击WebBrowser,然后按键盘上的Tab键(应该将焦点从WebBrowser移开),然后看看你是否可以点击你的的按钮。

如果可以,请尝试将处理程序附加到Button.MouseEnter事件并调用其中的((Button)sender).Foucs()以便以编程方式对焦按钮。