Reputation: 1432
I'm using a WebBrowser
control in design mode.
webBrowser1.DocumentText = "<html><body></body></html>";
doc = webBrowser1.Document.DomDocument as IHTMLDocument2;
doc.designMode = "On";
I have a save button that I would like to enable or disable depending on whether the contents of the control have changed.
I also need to know when the contents of the control have changed as I need to stop the user from navigating away from the control without accepting a confirmation message box stating that their changes will be lost.
I can't find any events that would let me know that the contents have changed.
Upvotes: 5
Views: 6652
Reputation: 3753
This seems to work - QueryInterface()
for IPersistFile interface and use IPersistFile::IsDirty method with the return value of S_OK
(if dirty or if the design mode document has been modified).
You don't need to use IPersistFile::Load
to load the contents into the web browser, WebBrowser->Navigate()
will also work fine.
Note - there is a same IsDirty()
method also in IPersistStream and IPersistStreamInit interfaces
I don't use C# but it should be relatively easy to rewrite.
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;
}
Upvotes: 0
Reputation: 15281
QueryInterface()
the document for IMarkupContainer2
, then call IMarkupContainer2::RegisterForDirtyRange
with your own implementation of IHTMLChangeSink
. Your IHTMLChangeSink::Notify
implementation will be called when a change is made.
Note: Do this after you set the design mode. The document gets reloaded and event hook get lost, if you toggle the design mode.
Upvotes: 3
Reputation: 1543
another solution, if you implement IDocHostUIHandler
, you can use its method UpdateUI
Upvotes: 0
Reputation: 2272
There is no such event since DocumentText is a simple string. I would create a string variable storing the last saved text and check it at each KeyDown / MouseDown / Navigating event.
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
}
}
Upvotes: 3