C#实现多选项卡的浏览器控件
本文详细为大家分享了c#多选项卡的浏览器控件的设计与实现,供大家参考,具体内容如下
1. 为什么我们需要多选项卡的浏览器控件
项目中需要使用winform应用程序来包装bs应用程序的浏览器外壳,在.net的webbrowser中没有多选项卡浏览的自带配置属性,我们需要实现多选项卡的浏览器控件来实现包装bs应用程序的目的,而不会弹出ie浏览器窗口。
2. 我们需要了解哪些知识点
2.1. webbrowser控件
webbrowser 控件为 webbrowser activex 控件提供了托管包装。托管包装使您可以在 windows 窗体客户端应用程序中显示网页。使用 webbrowser 控件,可以复制应用程序中的 internet explorer web 浏览功能,还可以禁用默认的 internet explorer 功能,并将该控件用作简单的 html 文档查看器。
l 如何:使用 webbrowser 控件定位到 url
this.webbrowser1.navigate("http://www.microsoft.com");
l webbrowser的 createsink 方法和detachsink 方法
createsink方法使基础 activex 控件与可以处理控件事件的客户端相关联。
detachsink方法使从基础 activex 控件中释放附加在 createsink 方法中的事件处理客户端。
下面的代码示例演示如何在派生自 webbrowser 的类中使用此方法,该方法使用 ole dwebbrowserevents2 接口中的 navigateerror 事件对常规 webbrowser 事件进行补充。
using system; using system.windows.forms; using system.runtime.interopservices; using system.security.permissions; namespace webbrowserextensibility { [permissionsetattribute(securityaction.demand, name="fulltrust")] public class form1 : form { [stathread] public static void main() { application.run(new form1()); } private webbrowser2 wb = new webbrowser2(); public form1() { wb.dock = dockstyle.fill; wb.navigateerror += new webbrowsernavigateerroreventhandler(wb_navigateerror); controls.add(wb); wb.navigate("www.widgets.microsoft.com"); } private void wb_navigateerror( object sender, webbrowsernavigateerroreventargs e) { // display an error message to the user. messagebox.show("cannot navigate to " + e.url); } } public class webbrowser2 : webbrowser { axhost.connectionpointcookie cookie; webbrowser2eventhelper helper; [permissionsetattribute(securityaction.linkdemand, name="fulltrust")] protected override void createsink() { base.createsink(); helper = new webbrowser2eventhelper(this); cookie = new axhost.connectionpointcookie( this.activexinstance, helper, typeof(dwebbrowserevents2)); } [permissionsetattribute(securityaction.linkdemand, name="fulltrust")] protected override void detachsink() { if (cookie != null) { cookie.disconnect(); cookie = null; } base.detachsink(); } public event webbrowsernavigateerroreventhandler navigateerror; protected virtual void onnavigateerror( webbrowsernavigateerroreventargs e) { if (this.navigateerror != null) { this.navigateerror(this, e); } } private class webbrowser2eventhelper : standardolemarshalobject, dwebbrowserevents2 { private webbrowser2 parent; public webbrowser2eventhelper(webbrowser2 parent) { this.parent = parent; } public void navigateerror(object pdisp, ref object url, ref object frame, ref object statuscode, ref bool cancel) { // raise the navigateerror event. this.parent.onnavigateerror( new webbrowsernavigateerroreventargs( (string)url, (string)frame, (int32)statuscode, cancel)); } } } public delegate void webbrowsernavigateerroreventhandler(object sender, webbrowsernavigateerroreventargs e); public class webbrowsernavigateerroreventargs : eventargs { private string urlvalue; private string framevalue; private int32 statuscodevalue; private boolean cancelvalue; public webbrowsernavigateerroreventargs( string url, string frame, int32 statuscode, boolean cancel) { urlvalue = url; framevalue = frame; statuscodevalue = statuscode; cancelvalue = cancel; } public string url { get { return urlvalue; } set { urlvalue = value; } } public string frame { get { return framevalue; } set { framevalue = value; } } public int32 statuscode { get { return statuscodevalue; } set { statuscodevalue = value; } } public boolean cancel { get { return cancelvalue; } set { cancelvalue = value; } } } [comimport, guid("34a715a0-6587-11d0-924a-0020afc7ac4d"), interfacetype(cominterfacetype.interfaceisidispatch), typelibtype(typelibtypeflags.fhidden)] public interface dwebbrowserevents2 { [dispid(271)] void navigateerror( [in, marshalas(unmanagedtype.idispatch)] object pdisp, [in] ref object url, [in] ref object frame, [in] ref object statuscode, [in, out] ref bool cancel); } }
l webbrowser. documentcompleted 事件
在 webbrowser 控件完成加载文档时发生。
处理 documentcompleted 事件,在新文档完成加载时接收通知。如果 documentcompleted 事件发生,则新文档已完全加载,这意味着可以通过 document、documenttext 或 documentstream 属性访问该文档的内容。
2.2. tabcontrol控件
tabcontrol 控件是windows 窗体多个选项卡控件,这些选项卡类似于笔记本中的分隔卡和档案柜文件夹中的标签。选项卡中可包含图片和其他控件。您可以使用该选项卡控件来生成多页对话框,这种对话框在 windows 操作系统中的许多地方(例如控制面板的“显示”属性中)都可以找到。
l 如何:将控件添加到选项卡页
tabpage1.controls.add(new button());
l 如何:使用 windows 窗体 tabcontrol 添加和移除选项卡
添加选项卡
string title = "tabpage " + (tabcontrol1.tabcount + 1).tostring(); tabpage mytabpage = new tabpage(title); tabcontrol1.tabpages.add(mytabpage);
移除选项卡
tabcontrol1.tabpages.remove(tabcontrol1.selectedtab);
l tabcontrol.drawitem 事件
如果将 drawmode 属性设置为 ownerdrawfixed,则每当 tabcontrol 需要绘制它的一个选项卡时,它就会引发 drawitem 事件。若要自定义选项卡的外观,请在用于 drawitem 事件的处理程序中提供自己的绘制代码。
下面的代码示例创建一个包含一个 tabpage 的 tabcontrol。本示例声明一个事件处理程序,并用来在 tabpage1 的选项卡上绘制字符串和 rectangle。该事件处理程序绑定到 drawitem 事件。
using system.drawing; using system.windows.forms; public class form1 : form { private rectangle tabarea; private rectanglef tabtextarea; public form1() { tabcontrol tabcontrol1 = new tabcontrol(); tabpage tabpage1 = new tabpage(); tabcontrol1.drawmode = tabdrawmode.ownerdrawfixed; tabcontrol1.sizemode = tabsizemode.fixed; tabcontrol1.controls.add(tabpage1); tabcontrol1.itemsize = new size(80, 30); tabcontrol1.location = new point(25, 25); tabcontrol1.size = new size(250, 250); tabpage1.tabindex = 0; clientsize = new size(300, 300); controls.add(tabcontrol1); tabarea = tabcontrol1.gettabrect(0); tabtextarea = (rectanglef)tabcontrol1.gettabrect(0); tabcontrol1.drawitem += new drawitemeventhandler(drawontab); } private void drawontab(object sender, drawitemeventargs e) { graphics g = e.graphics; pen p = new pen(color.blue); font font = new font("arial", 10.0f); solidbrush brush = new solidbrush(color.red); g.drawrectangle(p, tabarea); g.drawstring("tabpage1", font, brush, tabtextarea); } static void main() { application.run(new form1()); } }
3. 我们怎么设计多选项卡的浏览器控件
需要实现的功能特性:
l 实现打开bs应用程序的链接或窗口跳转到选项卡中而不是新窗口。
l 实现选项卡的关闭和新建,注意只有一个选项卡得时候不可以选项卡不可以出现关闭图片按钮。
我们主要采用tabcontrol和webbrowser来实现多选项卡浏览器控件开发。
现介绍主要控件实现代码。
u 新建选项卡页面代码实现如下:
public void createnewtabpage(string url) { extendedwebbrowser web = new extendedwebbrowser(); web.name = "webbroswer" + _webbrowserlists.count.tostring(); web.dock = dockstyle.fill; web.margin = new padding(0, 0, 0, 0); web.documentcompleted += new webbrowserdocumentcompletedeventhandler(webbrowser1_documentcompleted); web.beforenewwindow += new eventhandler(webbrowser1_beforenewwindow); web.navigate(url); _webbrowserlists.add(web); tabpage tbp = new tabpage(); tbp.name = "tabpage" + tabcontrol1.tabcount.tostring(); tbp.text = "空白页"; tbp.padding = new padding(0, 3, 0, 0); tbp.margin = new padding(0, 3, 0, 0); tbp.imageindex = 0; tbp.controls.add(web); this.tabcontrol1.controls.add(tbp); this.tabcontrol1.selectedtab = tbp; } u 把网页标题及图片关闭按钮的绘制选项卡中代码实现如下: private void tabcontrol1_drawitem(object sender, drawitemeventargs e) { try { graphics g = e.graphics; rectangle tabrectangle = this.tabcontrol1.gettabrect(e.index); //先添加tabpage属性 g.drawstring(this.tabcontrol1.tabpages[e.index].text , this.font, systembrushes.controltext, tabrectangle.x + 3, tabrectangle.y + 3); if (tabcontrol1.tabcount > 1) { //再画一个矩形框 using (pen p = new pen(systemcolors.control)) { tabrectangle.offset(tabrectangle.width - (close_size + 3), 2); tabrectangle.width = close_size; tabrectangle.height = close_size; g.drawrectangle(p, tabrectangle); } g.drawimage(e.state == drawitemstate.selected ? imagelist1.images["closeselected"] : imagelist1.images["close"], new point(tabrectangle.x, tabrectangle.y)); } g.dispose(); } catch (exception ex) { throw (ex); } }
u webbrowser控件完成时及webbrowser控件新建窗口时代码实现如下:
private void webbrowser1_documentcompleted(object sender, webbrowserdocumentcompletedeventargs e) { extendedwebbrowser web = (extendedwebbrowser)(sender); string title = web.document.title.trim(); tabpage tb = (tabpage)web.parent; tb.text = title.length > 6 ? title.substring(0, 6) + "..." : title; if (tabcontrol1.selectedtab == tb) { this.text = title; } } private void webbrowser1_beforenewwindow(object sender, system.eventargs e) { webbrowserextendednavigatingeventargs eventargs = e as webbrowserextendednavigatingeventargs; createnewtabpage(eventargs.url); eventargs.cancel = true; }
以上就是本文的全部内容,希望对大家的学习有所帮助。