• 用WebBrowser承载视图,html编写页面,c#编写后端代码;用js调用后端代码,传入function参数作为回调;


    最近在尝试一种有意思的桌面应用的写法:使用HTML+JS+CSS来做视图的展示,而不用winform的控件。效果还不错。

    1.新建一个窗体Form。

    2.在Form里添加一个WebBrowser控件。

            public static WebBrowser CreateWebBrower(Object objectForScripting)
            {
                WebBrowser webBrowser1 = new WebBrowser();
                webBrowser1.ScrollBarsEnabled = false;
                webBrowser1.AllowWebBrowserDrop = false;//将 WebBrowser 控件的 AllowWebBrowserDrop 属性设置为 false,以防止 WebBrowser 控件打开拖放到其上的文件。
                webBrowser1.IsWebBrowserContextMenuEnabled = false;//将该控件的 IsWebBrowserContextMenuEnabled 属性设置为 false,以防止 WebBrowser 控件在用户右击它时显示其快捷菜单.
                webBrowser1.WebBrowserShortcutsEnabled = false;//将该控件的 WebBrowserShortcutsEnabled 属性设置为 false,以防止 WebBrowser 控件响应快捷键。
                webBrowser1.ScriptErrorsSuppressed = true;//将该控件的 ScriptErrorsSuppressed 属性设置为 true,以防止 WebBrowser 控件显示脚本代码问题的错误信息。
                if (objectForScripting != null)
                {
                    webBrowser1.ObjectForScripting = objectForScripting;
                }
                return webBrowser1;
            }

    3.使用html编写页面的视图展示,比用winform control灵活多了。

    4.指定WebBrowser1.url 为刚刚第3步做的页面。

        WebBrowser1.Url = new Uri("file://" + Path.Combine(Application.StartupPath, "web/index.htm"));

    5.指定WebBrowser1.ObjectForScripting为刚刚新建立的窗体对象,并且在窗体类上声明"com可见性“。这么做:

        [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
        [System.Runtime.InteropServices.ComVisibleAttribute(true)]
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
    }
    

    6.在窗体里写个方法,必须是public的。这种方法,我们先叫“后台方法”

            public void Run2()
            {
            }

    7.这样我们就可用在html里调用这个run2方法了

     window.external.Run2();

    上面我们就完成了一个基本结构,在这个结构里,我们可以使用html编写页面,并在winform窗体里展示,并且可以在html页面里用js调用c#编写的方法。当然方法里是可以传参数的,可以传基本数据的参数,比如string,int,float 等。

    --------------------

    不过,我们要指定js是事件驱动的。我们调用一个方法后,如果方法执行事件过长,阻塞在那里可不好,于是我们就要考虑回调的方法实现。

    如下:

    在html页里,我需要调用一个后台方法(假设为:method1,这里指按照上面的步骤用c#写的方法),当方法method1完成后,调用回调方法,以使得在html里能收到回调的数据。

    我们分步骤看看如何实现它。

    1.我们在js里这么调用我们的后台方法,仔细看下面的方法fn4,在这个方法里,调用了后台方法Run2,并传入了一个参数“fn4_callback”,这个参数其实是个方法(function).我们想执行一个长时间的后台方法(run2),当run2方法执行完毕后,回调执行我们的fn4_callback方法。

            function fn4() {
                window.external.Run2(fn4_callback);
            }
            function fn4_callback(no,str) {
                alert(no);
                alert(str);
            }

    2.我们看看后台方法里,如何写run2。

    public void Run2(object str)
            {
            //dosomethind 长时间的
                Type t = str.GetType();
                t.InvokeMember("", System.Reflection.BindingFlags.InvokeMethod, null, str, new object[]{1,"xx"});
            }

    注意这里的参数是object类型,使用getType()方法查看的话是个“System.__ComObject”类型。我们使用的反射的方式来调用它。比较给力的就是
    t.InvokdeMember方法了。

    这样我们就完成了整个回调的实现。非常的爽。

    代码下载:http://yunpan.cn/Qe3yByINkUW52

    ---------
    参考:http://www.pcreview.co.uk/forums/handling-javascript-functions-and-closures-passed-into-c-function-t3106028.html

  • 相关阅读:
    学习嵌入式规划
    函数指针与指针函数
    css3
    css
    file upload使用iframe
    上传图片,文件
    table td里面的内容多的话出...
    html5 新标签
    html element
    css/html规范
  • 原文地址:https://www.cnblogs.com/vir56k/p/3131365.html
Copyright © 2020-2023  润新知