从WPF应用程序打开Web弹出窗口并使用javascript关闭它

时间:2011-02-18 17:14:03

标签: javascript wpf popup .net-3.5

我有一个与某些第三方服务器通信的WPF应用程序。

用户在WPF工具中完成某项任务后,我需要在弹出窗口中显示服务器中的特定网站。必须使用站点上的其中一个按钮关闭弹出窗口(这将确认另一个任务)。但是当javascript想要关闭该窗口时,Internet Explorer通常会打开一个对话框并要求用户确认关闭弹出窗口。

我正在寻找一个简单的解决方案来禁用此对话框。我无法改变服务器的行为,所以我需要解决它。

我使用恼人的确认对话框的旧方法是使用弹出窗口URL作为参数运行iexplore.exe(通过System.Diagnostics.Process)。

我的新方法是隐藏的<Frame x:Name="PopupFrame" />元素。当弹出窗口应该打开时,我将PopupFrame的Source属性设置为打开弹出窗口的页面。因此弹出窗口有一个基本窗口,javascript可以在没有确认对话框的情况下关闭它。但是这不适用于多个系统(可能是因为某些安全设置),它涉及另一个执行重定向/弹出窗口的页面。

有更简单的方法吗?

1 个答案:

答案 0 :(得分:1)

更新:好的,我刚刚意识到你无法控制网页,我只能想到向网页注入一些javascript,为WebBrowser的LoadCompleted事件添加一个事件处理程序,在那里注入javascript,这应该照顾它,而不是要求你修改原始网页:

// Add a reference to Microsoft.mshtml
using mshtml;

// inside the window constructor after you set 
// the webBrowser's ObjectForScripting property
this.webBrowser.LoadCompleted += this.webBrowser_LoadCompleted;

void webBrowser_LoadCompleted(object sender, NavigationEventArgs e)
{
    var doc = (HTMLDocument)webBrowser.Document;
    var head = doc.getElementsByTagName("head").Cast<HTMLHeadElement>().First();
    var script = (IHTMLScriptElement)doc.createElement("script");
    script.text = 
        "javascript:window.onbeforeunload = function () { window.external.Close(); }";
    head.appendChild((IHTMLDOMNode)script);
}

听起来您拥有自己正在打开的网页,所以您可以这样做:

1.-向窗口添加一个Popup控件并向其添加一个WebBrowser控件,您将使用它来导航到您的页面:

<Button Content="Button" Click="button1_Click" />
<Popup x:Name="PopUp" Width="300" Height="300">
        <WebBrowser x:Name="webBrowser">
        </WebBrowser>
</Popup>

2.-创建一个新类并为其添加[ComVisible(true)]属性。它应该包含Popup控件对象的引用。向隐藏Popup控件的新类添加一个公共方法。

using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Controls.Primitives;

[ComVisible(true)]
public class ScriptHandler
{
    private Popup popup;
    public ScriptHandler(Popup popup)
    {
        this.popup = popup;
    }

    public void Close()
    {
        this.popup.IsOpen = false;
    }
}

3.-将WebBrowser控件的ObjectForScripting属性设置为新类的实例。

public partial class MainWindow : Window
{
    private ScriptHandler scriptHandler;
    public MainWindow()
    {
        InitializeComponent();
        this.scriptHandler = new ScriptHandler(this.PopUp);
        this.webBrowser.ObjectForScripting = this.scriptHandler;
    }

    // Shows the pop up and navigates to your page
    private void button1_Click(object sender, RoutedEventArgs e)
    {
        this.webBrowser.Navigate("http://localhost:56977/PopUp.htm");
        this.PopUp.IsOpen = true;
    }
}

4.-由于您使用WebBrowser控件注册了ScriptHandler对象,因此可以从javascript访问此类中的所有公共方法,向您的页面添加javascript方法(您可能需要验证我正在执行的'undefined'验证)调用ComVisible类中的Close方法:

<script type="text/javascript">
    function CloseMe()
    {
        if(window.external != null && window.external.CloseMe != 'undefined')
        {
            window.external.Close();
        }
    }
</script>

5.-添加一个调用javascript CloseMe方法的链接到您的页面:

<a href='javascript:CloseMe()'>Close Me</a>

正如您可能已经意识到,此解决方案不仅适用于Popup控件,您还可以实例化一个新窗口并关闭它,处理您的WeBrowser控件等,或者只显示/隐藏不同类型的控件。