我希望你们能在这里帮助我。
我有一个用C#编写的应用程序,它使用WebBrowser控件编辑HTML文件(在屏幕截图上用2标记),这里是初始化它的代码:
htmlEditor.DocumentText = "";
doc = htmlEditor.Document.DomDocument as IHTMLDocument2;
doc.designMode = "On";
htmlEditor.Url = new Uri(Properties.Main.Default.tempDir + "\\section-1.html");
我还有一个listview控件,它显示了HTML文件列表(在屏幕截图中标记为1)。每次用户单击列表项时,都会触发一个事件,webbrowser控件会加载一个不同的HTML文件,这里是代码:
private void sectionsTree_SelectedNodeChanged(object sender, RadTreeViewEventArgs e)
{
Sections.fileCheck();
if (sectionsTree.SelectedNode != null)
{
emDataSet.dtSectionsDataTable sectionsDT = new emDataSet.dtSectionsDataTable();
sectionsDT.ReadXml(Properties.Main.Default.tempDir + "\\sections.xml");
for (int i = 0; i < sectionsDT.Rows.Count; i++)
{
if (sectionsTree.SelectedNode.Text == sectionsDT.Rows[i][2].ToString())
{
htmlEditor.Url = new Uri(Properties.Main.Default.tempDir + "\\" + sectionsDT.Rows[i][1].ToString());
}
}
}
}
现在我的问题出现了:因为webbrowser控件中加载的HTML页面是可编辑的,每次我在列表中选择一个新项目时(在加载新的HTML文件之前),都会出现一个Save对话框(标记为3 on截图)。我有自己的代码来保存由“更改”事件触发的已更改的HTML文件,如果有某种方法可以绕过,禁止,跳过或只是隐藏此“保存”对话框,那将是很好的,因此用户赢了每次他想要转到另一个文件时都需要点击它。这是变化的事件:
private void sectionsTree_SelectedNodeChanging(object sender, RadTreeViewCancelEventArgs e)
{
Sections.fileCheck();
if (sectionsTree.SelectedNode != null)
{
emDataSet.dtSectionsDataTable sectionsDT = new emDataSet.dtSectionsDataTable();
sectionsDT.ReadXml(Properties.Main.Default.tempDir + "\\sections.xml");
for (int i = 0; i < sectionsDT.Rows.Count; i++)
{
if (sectionsTree.SelectedNode.Text == sectionsDT.Rows[i][2].ToString())
{
File.WriteAllText(Properties.Main.Default.tempDir + "\\" + sectionsDT.Rows[i][1].ToString(), htmlEditor.DocumentText);
}
}
}
}
我的观点是上面的代码没问题,与我的问题无关,因为我的理解是问题来自WebBrowser控件的内置功能,但是,也许,它可能是在检查文件是否已更改之前拦截WebBrowser控件的解决方案,并将其保存,因此在检查时它不会触发“保存”对话框,但我还没弄清楚如何执行此操作。 / p>
我期待着你的所有答案,随时可以提出任何问题。
谢谢, Aemeth
答案 0 :(得分:0)
你可以使用这个
WebBrowser1.Document.ExecCommand(“Refresh”,False,“”)
在此http://www.spheregen.com/disable-save-dialog-in-webbrowser-editing/
处找到希望为你工作
答案 1 :(得分:0)
我最近遇到过这种情况,并且从未使用所述的Document.ExecCommand("Refresh")
成功。
对我有用的是使用Windows API调用将WM_CLOSE
消息发送到对话框,允许我禁止对话但仍然在后台处理文件保存/重新加载。
回答:Setting up Hook on Windows messages有助于设置所有内容,但它的一般要点是获取对话框类(#32770
),然后确保对话框的标题包含我的临时filename,然后获取该对话框的句柄并发送它WM_CLOSE
。
SetWinEventHook
的委托函数正文如下,希望这有一些帮助。
GetClassName(hWnd, ClassName, ClassName.Capacity);
GetWindowText(hWnd, DialogTitle, DialogTitle.Capacity);
DialogHandle = FindWindow(DIALOG_CLASS, DialogTitle.ToString());
if (ClassName.ToString() == DIALOG_CLASS && DialogTitle.ToString().Contains(TempFilename))
{
ReturnValue = SendMessage(DialogHandle, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
}
ClassName
和DialogTitle
属于StringBuilder
类型,ReturnValue
和DialogHandle
属于IntPtr
类型。 TempFilename
是一个包含由Path.GetTempFileName()
您需要对SetWinEventHook
,UnhookWinEvent
,GetClassName
,GetWindowText
,FindWindow
和SendMessage
进行API调用 - PInvoke.net应该能够帮助那些。你还需要设置一些常量--PInvoke可以提供帮助。
这不是最优雅的解决方案,但它确实有效!
编辑添加 - 如果您想要实际与对话框进行交互,而不是随意关闭它,您可以使用PInvoke中的代码:http://www.pinvoke.net/default.aspx/user32.enumchildwindows然后在代码中传递DialogHandle
上面的GetChildWindows()
函数并遍历返回的IntPtr
对象列表,在每个项目上调用GetWindowText()
,直到找到与“&Yes
”匹配的值(对于是按钮),“&No
”(对于“否”按钮)或“Cancel
”(对于取消按钮)。
获得按钮的句柄后,向其发送BM_CLICK
消息(0x00F5),您可以取消对话而不会失去其功能。
由于您只是遍历目标对话框而不是每个窗口,这是一个非常快速的操作(测试时需要2ms),所以不应该导致任何减速。
代码更改为以下内容:
GetClassName(hWnd, ClassName, ClassName.Capacity);
GetWindowText(hWnd, DialogTitle, DialogTitle.Capacity);
DialogHandle = FindWindow(DIALOG_CLASS, DialogTitle.ToString());
if (ClassName.ToString() == DIALOG_CLASS && DialogTitle.ToString().Contains(TempFilename))
{
foreach (IntPtr ChildWindow in GetChildWindows(hWnd))
{
StringBuilder ChildCaption = new StringBuilder(100);
GetWindowText(ChildWindow, ChildCaption, ChildCaption.Capacity);
if (ChildCaption.ToString() == @"&Yes")
{
SendMessage(ChildWindow, BM_CLICK, IntPtr.Zero, IntPtr.Zero);
}
}
}