CodeFirst写界面——自己写客户端UI库
何谓CBS程序
何谓WUI
第一步:WUI库中的主窗口
|
一个WinForm程序必然有一个主窗口
我们把这个主窗口封装到WUI库中
|
|
|
|
这个主窗口里面有一个WebBrowser,(这对于最终的用户来说是不可见的,最终使用者不会操作这个WebBrowser)
|
|
|
第二步:基础的UI资源
|
我们在WUI库中添加了一些基础的UI资源,注意这些资源都会被复制到输出目录中,以后会考虑把这些内容做到Resource 中
|
|
|
|
Index.html代码中有两点需要说明:
第一点:<meta http-equiv="X-UA-Compatible" content="IE=9" />
这是让我们使用的WebBrowser,以IE9的模式来渲染界面,这一行代码很重要,没有这一行代码,就算你装了IE11,那么WebBrowser可能仍旧不会表现成你想象的那样;
第二点:window.external.WUIPageLoaded();
这行代码会触发WUI库的内部事件,告诉最终用户基础的界面渲染已经完成了,用户可以在这个事件触发后,添加自己的界面元素。
这里涉及到JS和C#通讯,待会儿再说。
|
|
|
第三步:CodeFirst创建UI
|
我们的WUI.Demo程序是一个WinForm程序集,但是我把IDE默认生成的那个窗口(Form1)删掉了,而且修改了一下Program.cs程序
|
|
|
|
在入口函数(Main)中,Application.Run了我们在WUI库中创建的窗体(对于一个基于WUI库创建的程序来说,只有这么一个窗口),我们知道这个窗口的WebBrowser中没有任何东西,然而我们给WUIMain的属性PanelMain赋值了,这就是我们要添加的东西了
|
|
|
第四步:一个特殊的Panel
| 在上面的代码中,我们给PanelMain属性赋值为Main的实例,那么我们看一下Main是一个什么样的类型 首先:这个类继承自PanelMain类,PanelMain类是WUI库提供的一个基类 其次:这个基类中有一个事件叫OnRender,刚刚我们看到的JS方法中window.external.WUIPageLoaded();这行代码就会触发这个事件。 |
|
|
| 我们知道,一个用户界面上,有很多界面元素,这些界面元素装在一个容器中 我们的Main类型就是最上层的容器,最上层的容器是一个特殊的容器,他的类型是PanelMain;(你们可能看到了,我们在OnRender事件中又添加了一个Panel,这个Panel就不是特殊的容器了,但这篇文章我们不讲这里) 到此为止,我们有一个疑问, 第一:什么时候触发的OnRender事件呢? 这个时候我们就去看PanelMain的代码 |
|
|
|
看完PanelMain的代码我们疑问更多了:
第一:什么时候调用的Loaded方法呢?
第二:什么时候执行的ToJs方法呢?
|
第五步:C#与JS通信的开端
|
我们知道,我们在Program.cs中把Main类的实例交给了WUIMain窗口,那么这个窗口拿Main类的实例做了什么呢?让我们来看看WUIMain的代码
|
|
|
| (说明一下WB就是我们的浏览器控件了) 首先:我们让浏览器加载了那个主页文档(以后我们会做成动态的路径) 第二:我们创建了一个RenderContext类的实例,并且把Main的实例交给类这个类型的构造函数 第三:我们把浏览器的DomWindow赋值给了这个实例的IHTMLWin属性 第四:我们把这个实例赋值给了浏览器的ObjectForScripting属性 |
|
这里有一点需要说明:要想使用IHTMLWindow2这个类型,必须要引用Mirosoft.mshtml这个扩展库(注意,要在“扩展”里去找),引用了这个扩展库之后,在名称空间那里加上这一行using mshtml;就可以使用IHTMLWindow2这个类型了
|
|
|
第六步:C#与JS通信的高潮
|
然而我们的疑问还是没有解决,那么只能继续看RenderContext的代码
首先:我们在这个类型的构造函数中得到了Main的实例
其次:我们把这个类型设置成了ComVisible
(注意,要想设置一个类型为ComVisible,必须要使用System.Runtime.InteropServices;名称空间)
|
|
|
|
大家注意到了,这个类型里有一个公开的WUIPageLoaded方法,这个方法名是不是很眼熟呢?对了,就是我们在JS中调用的方法window.external.WUIPageLoaded();
需要注意的有两点:
第一:一定要用window.external调用这个方法
第二:如果这个类型不设置成ComVisible就调用不到
第三:在WUIPageLoaded方法中,我们让浏览器执行了一段脚本,就是PanelMain的ToJs方法里的脚本了,这个时候就把这个控件渲染到浏览器中去了
第四:我们调用了PanelMain实例的Loaded方法,在那个方法里,我们触发了OnRender事件,这样我们的用户就知道什么时候他该接管接下去的工作了
|
|
注意:
在这里我们用C#让浏览器执行了脚本
浏览器用JS代码让我们的C#也做了工作
这就是C#和JS的通信了呢!
|
第七步:尾声
|
我们的程序看起来像这个样子
我当然知道这不是你想要看到的结果
那么,请您对这篇文章点个赞吧------------------------->>
您的支持是我写下一篇的动力!!!
|
|
|
CodeFirst写界面——自己写客户端UI库的更多相关文章
- 自己动手写客户端UI库——事件机制(设计思路大放送)
在上一篇文章中我们创建了一个Button控件,并把这个控件显示在界面上, 在这一篇文章中,我们将为这个控件增加一个事件和一个方法 一:怎么绑定事件的问题 在Winform中,我们对一个按钮绑定事件的方 ...
- 自己动手写客户端UI库——创建第一个控件
在上一篇文章中我们主要讲了C#如何和JS通信, 这一篇文章中,我们将创建一个最基础的Button控件 WUI库中控件的继承机制 我们先解释最简单的继承机制,以后WUI库的继承机制会比这个复杂的多 ...
- 用C++写UI库最本质的思想就是不用C++写UI(如何用 C++ 从零编写 GUI?内含多个开源UI作者的回复,非常精彩)
作者:Bingo链接:https://www.zhihu.com/question/24462113/answer/83371803来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请 ...
- 利用epoll写一个"迷你"的网络事件库
epoll是linux下高性能的IO复用技术,是Linux下多路复用IO接口select/poll的增强版本,它能显著提高程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率.另一点原因就是获取 ...
- 一个用C++写的Json解析与处理库
什么是Json?这个库能做什么? JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is e ...
- [MFC美化] MFC界面UI库总结
稍微说下自己用过的感受: 1.SkinMagic 动态库DLL使用,(有VC6版本的静态链接库,没能成功调用).对控件:菜单和下拉框(下拉滚动条)有问题.不能自由设置颜色背景 皮肤格式:.smf,可使 ...
- java源码——对文件内容的查找和替换(开始写界面咯)
问题是:"键盘输入文件的路径.查找内容和替换内容,对指定路径的文件的内容进行查找和替换." 好久没写界面了,今天熟悉一下界面的书写和监听器操作. 这个问题的本身不是很难,重点应该是 ...
- Webix JavaScript UI 库可以帮你构建跨平台的HTML5 和 CSS3 程序
XB 软件公司最近发布了JavaScript UI 库Webix ,其中包含的组件超过45个,用这些组件可以构建跟HTML5 和 CSS3 兼容的程序,这些程序不仅能在个人电脑上运行,还能用在iOS. ...
- 微信小程序开发04-打造自己的UI库
前言 github地址:https://github.com/yexiaochai/wxdemo 接上文继续,我们前面学习了小程序的生命周期.小程序的标签.小程序的样式,后面我们写了一个简单的load ...
随机推荐
- 命令行启动win7系统操作部分功能
control.exe /name microsoft.folderoptions 启动资源管理器的 文件夹属性 选项卡 control.exe /name Microsoft.AddHardware ...
- pcm跟.wav文件的关系
PCM(Pulse Code Modulation----脉码调制录音).所谓PCM录音就是将声音等模拟信号变成符号化的脉冲列,再予以记录.PCM信号是由[1].[0]等符号构成的数字信号,而未经过任 ...
- Shape comparison language
形状比较语言, 九交模型 In this topic About shape comparison language Dimensionality Extensions to the CBM SC ...
- 循序渐进Python3(六) -- 初识内置变量、反射、递归
#python用下划线作为变量前缀和后缀指定特殊变量.稍后我们会发现, #对于程序来说,其中的有些变量是非常有用的,而其他的则是未知或者无用的. #我们总结一下Python中下划线的特殊用法 ...
- ORACLE 分析函数整理汇总
1. 聚合分析函数 SUM MIN MAX AVG COUNT 这类聚合类分析函数可以在窗口中分组
- Android菜鸟成长记3-activity类
Activity 一.什么是activity Activity 是用户接口程序,原则上它会提供给用户一个交互式的接口功能.它是 android 应用程序的基本功能单元.Activity 本身是没有界面 ...
- __iter__
[__iter__] 如果一个类想被用于for ... in循环,类似list或tuple那样,就必须实现一个__iter__()方法,该方法返回一个迭代对象,然后,Python的for循环就会不断调 ...
- Remoting创建远程对象的一个实例:
private static Lazy<IChannelManager> channelManager=new Lazy<IChannelManager>(() => ...
- HTML5和CSS3基础教程(第8版)-读书笔记(3)
第11章 用CSS 进行布局 网站设计主要有两大类型:固定宽度和响应式. 对于固定(fixed)布局,整个页面和每一栏都有基于像素的宽度.顾名思义,无论是使用移动电话和平板电脑等较小的设备查看页面,还 ...
- iOS页面间传值的方式(Delegate/NSNotification/Block/NSUserDefault/单例)
iOS页面间传值实现方法:1.通过设置属性,实现页面间传值:2.委托delegate方式:3.通知notification方式:4.block方式:5.UserDefault或者文件方式:6.单例模式 ...