如何检测WebBrowser控件的内容何时发生更改(在设计模式下)?

时间:2012-06-21 09:57:22

标签: c# webbrowser-control

我在设计模式中使用WebBrowser控件。

webBrowser1.DocumentText = "<html><body></body></html>";
doc = webBrowser1.Document.DomDocument as IHTMLDocument2;
doc.designMode = "On";

我有一个保存按钮,我想启用或禁用,具体取决于控件的内容是否已更改。

我还需要知道控件的内容何时发生了变化,因为我需要阻止用户离开控件而不接受确认消息框,说明他们的更改将会丢失。

我找不到任何让我知道内容已经发生变化的事件。

4 个答案:

答案 0 :(得分:3)

由于DocumentText是一个简单的字符串,因此没有此类事件。 我将创建一个存储最后保存文本的字符串变量,并在每个KeyDown / MouseDown / Navigating事件中检查它。

string lastSaved;

private void Form_Load(object sender, System.EventArgs e)
{
   // Load the form then save WebBrowser text
   this.lastSaved = this.webBrowser1.DocumentText;
}

private void webBrowser1_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
{
    // Check if it changed
    if (this.lastSaved != this.webBrowser1.DocumentText)
    {
        // TODO: changed, enable save button
        this.lastSaved = this.webBrowser1.DocumentText;
    }
}

private void webBrowser1_Navigating(object sender, WebBrowserNavigatingEventArgs e)
{
    // Check if it changed
    if (this.lastSaved != this.webBrowser1.DocumentText)
    {
        // TODO: ask user if he wants to save
        // You can set e.Cancel = true to cancel loading the next page
    }
}

答案 1 :(得分:3)

QI IMarkupContainer2的文档,然后使用您自己的IHTMLChangeSink实现调用IMarkupContainer2 :: RegisterForDirtyRange。进行更改时将调用您的IHTMLChangeSink :: Notify实现。

注意在设置设计模式后执行此操作。如果您设计模式,则会重新加载文档并导致事件挂钩丢失。

答案 2 :(得分:0)

另一种解决方案,如果实现IDocHostUIHandler,则可以使用其方法UpdateUI

答案 3 :(得分:0)

这似乎有效 - QueryInterface() 用于 IPersistFile 接口并使用 IPersistFile::IsDirty 方法和 S_OK 的返回值(如果脏或设计模式文档已被修改).

您不需要使用 IPersistFile::Load 将内容加载到网络浏览器中,WebBrowser->Navigate() 也可以正常工作。

注意 - IPersistStreamIPersistStreamInit 接口中也有相同的 IsDirty() 方法

我不使用 C#,但它应该相对容易重写。

bool IsEditorDirty(WebBrowser* WB)
    {
    // beware, if it fails to get Document and IPersistFile it will not register as dirty
    bool isdirty = false;

    IHTMLDocument2* pDoc2 = WB->Document;

    if (pDoc2) {
        IPersistFile* pPFile;

        if (pDoc2->QueryInterface(IID_IPersistFile, (void**)&diPFile) == S_OK) {
            isdirty = (pPFile->IsDirty() == S_OK);
            pPFile->Release();
            }
    
        pDoc2->Release();
        }

    return isdirty;
    }