[转载]常用图表控件总汇

mikel阅读(1555)

[转载]常用图表控件总汇 – Eric_ – 博客园.

数据可视化,图形化显示是当前工业领域、商业领域、金融领域等不可或缺的元素,通常采用图表进行数据可视化展示,直观地显示数据、对比数据、分析数据,很多项目开发中都会需求到图表控件,这里简单介绍下各个开发平台下的常用图表控件。

Flash类的图表:

该类图表主要使用Flash Player作为载体,使用XML作为数据输入,优点是可以跨平台、跨浏览器,支持多种开发语言,快速上手且使用简单,支持多种类型的图表、仪表和地图,具备交互功能且可连接多种数据库

1. AnyChart图表控件

AnyChart控件是一款当前流行的数据可视化解决方案,使客户可以创建交互地、生动的图表和仪表、地图。该控件提供极好的视觉外观和配色方案能 够使客户根据不同的需求设计图表,AnyChart是一款跨浏览器的工具,可以被用于Web、Desktop和Mobile应用程序,AnyChart可 运行于当前PC和Mac上所有主流的浏览器,如:Chrome, Safari, Firefox, Internet Explorer和Opera,并且可用于所有移动平台(Android (2.2+) 和 iOS (iPhone, iPad, iPod Touch). )上的主流浏览器,全面支持HTML5和SVG

具体介绍和在线事例请查看>>

2. FusionCharts图表控件

FusionCharts帮助开发人员创建动态的和交互式的图表应用程序,可用于PCs, Macs, iPads, iPhones和其他主流的移动驱动,控件使用Flash和JavaScript(HTML5)来创建图表,使用XML或者JSON作为数据输入,支持 ASP, ASP.NET, PHP, JSP, ColdFusion, Ruby on Rails等脚本语言和多种数据库,支持多种图表类型、仪表和地图。

具体介绍和在线事例请查看>>>>

.NET类图表

该 类图表主要是针对.NET平台设计,并不需要Flash Player等作为载体,可直接在WebForm和WinForm窗体上显示,控件提供了直连数据源接口,不需使用XML作为数据输入,可直接绑定各种数 据源到控件,同样支持多种图表、仪表类型,具备各种交互功能,实时数据显示

1. TeeChart for .NET

TeeChart for .NET是Steema软件公司的一款老牌图表控件,历经15年,已经被全球多个领域广泛使用,支持WPF, Silverlight,ASP.NET, Winform, SQL Reporting Services, Compact Framework 和Windows Phone 7等多种平台。提供了多种流行的2D和3D图表类型和仪表以及地图,内置多种金融和统计函数,完全的中文图表设计器,是当前.NET开发人员创建图表应用 程序的首选。

具体介绍和在线事例请查看>>>>

2.  Visifire

Visifire是 一款强大的数据可视化图表控件,提供多种功能的图表和仪表,图表和仪表实时显示和更新,滚动和放大缩小,可以用于Silverlight和WPF平台下, 支持 .Net 3.5 SP1以及4.0,全面兼容Windows Phone7,利用该控件开发人员可以在几分钟内就设计出强大的图表应用程序

3. ComponentArt Gauges for Silverlight and WPF

该控件是一款功能强大的交互性的仪表控件,包含了多种数字仪表控件,容易地进行KPI绑定,自定义指针,比列以及刻度,灵活的布局和动画显示,包含 了圆型仪表、线性仪表、数字仪表、圆柱图、BulletGraphs、半饼图、温度计、组合仪表等,全面支持Visual Studio 2010设计时设计和Silverlight 4以及WPF4

该控件具体介绍和试用版下载请查看>>

4. Chart FX

Chart FX是一款.NET平台下功能强大的图表控件,完全整合于Visual Studio 2005、2008、2010,可同时用于WinForm和WebForm平台,控件提供了超过20多种的图表类型,多种交互功能和数据分析功能,强大的 图表设计器和最终用户自定义功能,该控件被全球多家500强企业所使用,受到业界一致好评。

该控件具体介绍和试用版下载请查看>>

Activex和COM类型:该类图表控件主要是运用于VC++和VB等开发平台

1. TeeChart Pro ActiveX

该 控件也是Steema公司下的一款老牌的图表控件,可完全满足你的商业,科学,工程学及金融图表需求。它提供了多种2D及3D图表类型,33种数据及统计 学函数供您选择,图表同时提供无限数量的坐标轴和17个常用图表工具控件。控件提供的图表编辑器可以帮助开发人员快速地创建图表,图表提供的数据接口可以 直接绑定多种数据源。

该控件具体介绍和试用版下载请查看>>

2. ProEssentials

ProEssentials 图表控件可以为您的程序添加金融、科学、工程、商业图表,提供了多种2维和三维图表类型,可用于WinForm和WebForm,提供了大量接口,同时支 持多种开发平台:Visual Studio. NET, VB6, VC6, ASP, Delphi等

该控件具体介绍和试用版下载请查看>>

VCL和CLX类型的图表:该类图表主要是用于Delphi和C++ Builder 平台的

1. TeeChart Pro VCL/CLX

TeeChart Pro VCL/CLX 是一款功能强大的图表制作控件,提供了上百种2D和3D图表类型,43种数学的、统计的、金融的函数,以及不限数量的坐标轴和22种调色板控件。并且还提供完整的源代码和丰富的帮助文档以及大量的事例

该控件具体介绍和试用版下载请查看>>

JAVA类的图表控件:该类图表主要用于JAVA平台下

1. Chart FX 7 for Java Server

Chart FX 7 for Java Server是一款基于Java 1.5+构建的图表控件,支持多种图表类型,该控件使用框架独立的、基于AJAX的运行时UI,可对图表图像进行多种交互功能操作,当数据改变时自动更新 图表而不需要整个页面刷新,支持JSF技术。控件提供的图表设计器可快速设计图表,增强最终用户界面,使最终用户利用控件提供的菜单、工具条对图表进行操 作以及打印等。


该控件具体介绍和试用版下载请查看>>

2. Chart FX 7 for Java Desktop

Chart FX 7 for Java Desktop是 一款适用于Swing应用程序的图表控件,完全整合于NetBeans 和所有Eclipse-Based IDEs,可直接拖拉控件到开发环境里进行设计时配置,同样最终用户也可以根据控件运行时提供的菜单和工具条进行很多图表的自定义操作。控件提供了超过 20+的图表类型,可通过API直接绑定图表到多种数据集

[转载]Jquery 中的CheckBox RadioButton DropDownList的取值赋值

mikel阅读(1104)

[转载]Jquery 中的CheckBox RadioButton DropDownList的取值赋值 – 朱梅梅 – 博客园.

随着JQuery的作用越来越大,使用的朋友也越来越多。在Web中,由于CheckBox Radiobutton DropDownList等控件使用的频率比较高,就关系到这些控件在JQuery中的操作问题。由于JQuery的版本更新很快,代码的写法也改变了许多,以下jQuery代码适query1.4版本以上。

Radio

1.获取选中值,三种方法都可以:

$(‘input:radio:checked’).val()

$(“input[type=’radio’]:checked”).val();

$(“input[name=’rd’]:checked”).val();

2.设置第一个Radio为选中值:

$(‘input:radio:first’).attr(‘checked’, ‘checked’);

或者

$(‘input:radio:first’).attr(‘checked’, ‘true’);

注: attr(“checked”,’checked’)= attr(“checked”, ‘true’)= attr(“checked”, true)

3.设置最后一个Radio为选中值:

$(‘input:radio:last’).attr(‘checked’, ‘checked’);

或者

$(‘input:radio:last’).attr(‘checked’, ‘true’);

4.根据索引值设置任意一个radio为选中值:

$(‘input:radio’).eq(索引值).attr(‘checked’, ‘true’);索引值=0,1,2….

或者

$(‘input:radio’).slice(1,2).attr(‘checked’, ‘true’);

5.根据Value值设置Radio为选中值

$(“input:radio[value=’rd2′]”).attr(‘checked’,’true’);

或者

$(“input[value=’rd2′]”).attr(‘checked’,’true’);

6.删除Value值为rd2Radio

$(“input:radio[value=’rd2′]”).remove();

7.删除第几个Radio

$(“input:radio”).eq(索引值).remove();索引值=0,1,2….

如删除第3Radio:$(“input:radio”).eq(2).remove();

8.遍历Radio

$(‘input:radio’).each(function(index,domEle){

//写入代码

});

DropDownList

1. 获取选中项:

获取选中项的Value值:

$(‘select#sel option:selected’).val();

或者

$(‘select#sel’).find(‘option:selected’).val();

获取选中项的Text值:

$(‘select#seloption:selected’).text();

或者

$(‘select#sel’).find(‘option:selected’).text();

2. 获取当前选中项的索引值:

$(‘select#sel’).get(0).selectedIndex;

3. 获取当前option的最大索引值:

$(‘select#sel option:last’).attr(“index”)

4. 获取DropdownList的长度:

$(‘select#sel’)[0].options.length;

或者

$(‘select#sel’).get(0).options.length;

5. 设置第一个option为选中值:

$(‘select#sel option:first’).attr(‘selected’,’true’)

或者

$(‘select#sel’)[0].selectedIndex = 0;

6. 设置最后一个option为选中值:

$(‘select#sel option:last).attr(‘selected’,’true’)

7. 根据索引值设置任意一个option为选中值:

$(‘select#sel’)[0].selectedIndex =索引值;索引值=0,1,2….

8. 设置Value=4 option为选中值:

$(‘select#sel’).attr(‘value’,’4′);

或者

$(“select#sel option[value=’4′]”).attr(‘selected’, ‘true’);

9. 删除Value=3option

$(“select#sel option[value=’3′]”).remove();

10.删除第几个option

$(” select#sel option “).eq(索引值).remove();索引值=0,1,2….

如删除第3Radio:

$(” select#sel option “).eq(2).remove();

11.删除第一个option

$(” select#sel option “).eq(0).remove();

或者

$(“select#sel option:first”).remove();

12. 删除最后一个option

$(“select#sel option:last”).remove();

13. 删除dropdownlist:

$(“select#sel”).remove();

14.select后面添加一个option:

$(“select#sel”).append(“<option value=’6′>f</option>”);

15. select前面添加一个option:

$(“select#sel”).prepend(“<option value=’0′>0</option>”);

16. 遍历option:

$(‘ select#sel option ‘).each(function (index, domEle) {

//写入代码
});

CheckBox

1. 获取单个checkbox选中项(三种写法)

$(“input:checkbox:checked”).val()

或者

$(“input:[type=’checkbox’]:checked”).val();

或者

$(“input:[name=’ck’]:checked”).val();

2. 获取多个checkbox选中项:

$(‘input:checkbox’).each(function() {

if ($(this).attr(‘checked’) ==true) {

alert($(this).val());

}

});

3. 设置第一个checkbox 为选中值:

$(‘input:checkbox:first’).attr(“checked”,’checked’);

或者

$(‘input:checkbox’).eq(0).attr(“checked”,’true’);

4. 设置最后一个checkbox为选中值:

$(‘input:radio:last’).attr(‘checked’, ‘checked’);

或者

$(‘input:radio:last’).attr(‘checked’, ‘true’);

5. 根据索引值设置任意一个checkbox为选中值:

$(‘input:checkbox).eq(索引值).attr(‘checked’, ‘true’);索引值=0,1,2….

或者

$(‘input:radio’).slice(1,2).attr(‘checked’, ‘true’);

6. 选中多个checkbox

同时选中第1个和第2个的checkbox

$(‘input:radio’).slice(0,2).attr(‘checked’,’true’);

7. 根据Value值设置checkbox为选中值:

$(“input:checkbox[value=’1′]”).attr(‘checked’,’true’);

8. 删除Value=1checkbox:

$(“input:checkbox[value=’1′]”).remove();

9. 删除第几个checkbox:

$(“input:checkbox”).eq(索引值).remove();索引值=0,1,2….

如删除第3checkbox:

$(“input:checkbox”).eq(2).remove();

10.遍历checkbox:

$(‘input:checkbox’).each(function (index, domEle) {

//写入代码
});

11.全部选中

$(‘input:checkbox’).each(function() {

$(this).attr(‘checked’, true);

});

12.全部取消选择:

$(‘input:checkbox’).each(function () {

$(this).attr(‘checked’,false);

});

[转载]Jquery 插件:一个小巧的jquery 三级联动多选插件

mikel阅读(1135)

[转载]【Jquery 插件】一个小巧的jquery 三级联动多选插件 – 学-无-止-境 – 博客园.

今天做了一个小巧的JQuery 三级联动多选插件,时间仓促,没有做太多的优化和更多的通用性设计。

希望以此来接受园子里朋友的指正,完善这个插件。

先上图:

91家装 电子书点搜

用法:

1.在页面添加元素:

<ul id=”selected”></ul>
<div id=”selecter”></div>

当然也可以自定义

2.引用脚本库和css

<link href=”JQuery.selecter.css” type=”text/css” rel=”Stylesheet” />
<script type=”text/JavaScript” src=”jQuery-1.6.2.min.js”></script>
<script type=”text/JavaScript” src=”jQuery.selecter.js”></script>

3.使用jQuery.selecter的默认方法:

$(‘#selecter’).selecter();

4.高级用法:

$(‘#selecter’).selecter({ handler: “/handler/handler.ashx”, data: “action=getSiteCategory&id=”,parentId:”0″ });

下载地址:

/Files/andylaufzf/jquery.selecter.rar

[转载]利用Linq写简洁代码

mikel阅读(1062)

[转载]利用Linq写简洁代码 – 老衲爱封装 – 博客园.

1.xml读写

d盘下有Demo.xml,内容如下

<?xml version="1.0" encoding="utf-8" ?>
<Earthworm>
  <Demo>
    <Aspect name="">
      <Advice type="before" assembly="" className="">
        <MethodName>asd</MethodName>
        <MethodName>kll</MethodName>
      </Advice>
      <Advice type="stop" assembly="" className="">
        <MethodName></MethodName>
        <MethodName></MethodName>
      </Advice>
      <Advice type="after" assembly="" className="">
        <MethodName></MethodName>
        <MethodName></MethodName>
      </Advice>
    </Aspect>
  </Demo>
</Earthworm>

现在想获取type为before的所有MethodName的节点值

普通读取方法

XmlDocument xmldoc = new XmlDocument();
 xmldoc.Load(@"d:\demo.xml");
 XmlNodeList nodelist = xmldoc.SelectNodes("Earthworm/Demo/Aspect/Advice[@type='before']/MethodName");
 foreach (XmlNode node in nodelist)
 {
 Console.WriteLine(node.InnerText); 
}

Linq To Xml 读取方法

var dname = from k in  (from m in XDocument.Load("d:\\zhongming.xml").Descendants("Advice") 
             where m.Attribute("type").Value == "before"  select m).Descendants("MethodName") select k.Value;//一句话搞定,很给力
            foreach (var a in dname)
            {
                Console.WriteLine(a);
            }

2.查找普通对象

有如下数组:

int[] data = new int[] {12,23,445,666,777,90,33,2,0,-89 };

想查找大于50的对象

普通方法

var findObjects = new List<int>();
            foreach (int i in data)
            {
                if (i > 50)
                {
                    findObjects.Add(i);
                }
            }

Linq方法

 var findObjects=from d in data where d>50 select d;//同样是一句话


3.查找动态对象

     class People
        {
            /// <summary>
            /// 姓名
            /// </summary>
            public string Name{get;set;}
            /// <summary>
            /// 年龄
            /// </summary>
            public int Age{get;set;}
            /// <summary>
            /// 性别
            /// </summary>
            public bool Gender { get; set; }
        }

有如下数据

People[] data = new People[] { new People{Name="西门吹雪",Gender=true,Age=1200},
                                                               new People{Name="令狐冲",Gender=true,Age=999},
                                                               new People{Name="任盈盈",Gender=false,Age=456},
                                                               new People{Name="欧阳锋",Gender=true,Age=9999},
                                                               new People{Name="黄药师",Gender=true,Age=670},
                                                               new People{Name="吴世龙",Gender=true,Age=25}};

想查找所有的People的姓名和年龄

普通方法

必须建造一个结构体或类,用来存储姓名和年龄,结构体如下

struct DynamicObject
        {
            public string Name;
            public int   Age;
        }

然后查找

List<DynamicObject> objs = new List<DynamicObject>();
            foreach (People p in data)
            {
                objs.Add(new DynamicObject { Name = p.Name, Age = p.Age });
            }

linq方法

var objects = from d in data select new { d.Name, d.Age };

还有更牛的是优化过程

比如那个读xml的你是这样写的

var doc = XDocument.Load(@"d:\demo.xml");
            var list=from m in doc.Descendants("Advice") where m.Attribute("type").Value == "before"  select m;
            var datas=from k in  list.Descendants("MethodName") select k.Value;
            foreach (var a in datas)
            {
                Console.WriteLine(a);
            }

编译完成之后,拿一Reflector看,是这个样子的

  IEnumerable<string> datas = from k in (from m in XDocument.Load(@"d:\demo.xml").Descendants("Advice")
            where m.Attribute("type").Value == "before"
            select m).Descendants<XElement>("MethodName") select k.Value;//变成一句了哦
        foreach (string a in datas)
        {
            Console.WriteLine(a);
        }

就讲这么多,其他的一起探索吧

[转载]通过VS2010性能分析来查找代码中那些地方最损耗资源

mikel阅读(1015)

[转载]通过VS2010性能分析来查找代码中那些地方最损耗资源 – smark – 博客园.

在编写完成一个程序后,大家都比较关心程序的性能如何,想把程序优化得更好。很多时候凭个人直觉来优化程序是件非常不靠普的事情,即使你是一个优秀的开人员也很难准确地判断程序中那些出现问题。VS2010提供了性能分析工具就能轻松地帮我们解决这一事情。

  • 假设现在写了一个组件,很想知道组件和代码的性能情况。这个可以简单地写一个测试程序。
View Code

    class Program
    {
        static List<Expression> mExpressions = new List<Expression>();
        static Random mRan = new Random();
        static void Main(string[] args)
        {
            try
            {
                string dbpath = @"Data Source=d:\\northwind.db;Pooling=true;FailIfMissing=false;";
                DBContext.SetConnectionDriver<SqliteDriver>(ConnectionType.Context1);
                DBContext.SetConnectionString(ConnectionType.Context1, dbpath);
                mExpressions.Add(Order.shipCountry == "Switzerland");
                mExpressions.Add(Order.shipRegion == "RJ");
                mExpressions.Add(Order.customerID.In(Customer.customerID, Customer.country == "UK"));
                mExpressions.Add(Order.customerID.In(Customer.customerID, Customer.country == "Germany"));
                mExpressions.Add(Order.orderDate > "1997-8-5");
                mExpressions.Add(Order.orderDate < "1997-12-1");
                mExpressions.Add(Order.orderDate > "1997-5-1" & Order.orderDate<"1997-11-5");
                System.Threading.Thread thread;
                for (int i = 0; i < 10; i++)
                {
                    thread = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(Test
                        ));
                    thread.Start();
                }
                
            }
            catch (Exception e_)
            {
                Console.WriteLine(e_.Message);
            }
           
        }
        static void Test(object obj)
        {
            while (true)
            {
                Expression exp = mExpressions[mRan.Next(mExpressions.Count - 1)];
                Console.WriteLine(exp.Count<Order>());
                System.Threading.Thread.Sleep(mRan.Next(50, 5000));
            }
        }
      
    }
  • 测试程序写好后可以通过VS2010分析菜单里选择启用性能向导

  • 选择CPU采样后就选择需要分析的项目

  • 测试项目选择完成后就可以运行分析,结束分析后VS2010会提供个详细报告文档

  • 从分析结果来看GetConnection这个方法占用的比例是最严重的,我们可以点击进去看下这函数倒做了些什么,那些代码损耗得最利害。

  • 从上面结果来看损耗最利害的是创建ConnectionContext对象,这个时候我们可以进一步点击进去看个究竟

  • 这个方法还没发现真正的原因,我们继续往下走

到了这里发现原来是connection.Open方法占用了大部分资源,这个时候就想到这个测试程序跑这么久为什么连接打开这么损耗资源,是不是连接池没有开启导致每次操作都进行数据库连接操作呢?

其实VS2010给我们提供的分析工具真得很轻松就可以让我们了解到程序代码状况,从而优化程序的代码。如果有这烦脑的朋友不防试下:)

[转载]C#简单实现office转pdf、pdf转图片

mikel阅读(1247)

[转载]C#简单实现office转pdf、pdf转图片 – 小宝LOVE继艾斯 – 博客园.

国庆放假前,公司有个项目里要用到office、pdf以及图片的互转,自己以前没有接触过,所以整理了网上林林总总的办法,也算是总结出了最简单有效的办法:office -> pdf 应用Adobe Acrobat 8 Pro的一个PDFMakerAPI.dll程序集;pdf -> png(jpg,gif…)应用Ghostscript。下面详述说明:

一、准备工作:

1.安装Adobe Acrobat 8 Pro,本人安装的是8.1.2版本,在你的安装目录下(例如我自己的:C:\Program Files\Adobe\Acrobat 8.0\PDFMaker\Common\)common目录中找到PDFMakerAPI.dll程序集,拷贝出到项目中放DLL的文件夹(此文件夹为用户保存DLL文件的文件夹,名称以自己项目为准),并在项目里对其添加引用。

2.安装Ghostscript,本人安装的是8.63版本,需要用的的其他DLL:FontBox-0.1.0-dev.dllIKVM.GNU.Classpath.dllIKVM.Runtime.dllPDFBox-0.7.3.dll其中IKVM.GNU.Classpath.dllPDFBox-0.7.3.dll在项目里对其添加引用,其他两个(4个dll均放到)放到DLL文件夹里即可。

3.Ghostscript配置Web.config:

<appSettings>
<add key=”GhostScriptView” value=”C:/Program Files/gs/gs8.63/bin“/>
<add key=”GhostScriptArguments” value=”-dSAFER -dBATCH -dNOPAUSE -r150 -sDEVICE=jpeg -dGraphicsAlphaBits=4″/>
</appSettings>

找到自己对应的Ghostscript安装目录,自行修改。

二、应用:

1.office -> pdf

引用命名空间:using PDFMAKERAPILib;关键代码如下:

1 ///
2 ///参数:docfile,源office文件绝对路径及文件名(C:\office\myDoc.doc);printpath,pdf文件保存路径(D:\myPdf);printFileName,保
3 ///存pdf文件的文件名(myNewPdf.pdf)
4 ///
5
6 objectmissing = System.Type.Missing;
7 PDFMakerAppapp = new PDFMakerApp();
8 app.CreatePDF(docfile, printpath + printFileName, PDFMakerSettings.kConvertAllPages, false, true, true, missing);

2.pdf-> 图片

引用命名空间:using org.pdfbox.pdmodel;关键代码如下:

01 ///
02 /// <param name="pdfFile">PDF文档物理路径</param>
03 /// <param name="imgPath">转换成的图片文件的存放物理路径</param>
04 ///
05 public static void PdfToImages(string pdfFile, string imgPath)
06 {
07 PDDocument doc = PDDocument.load(pdfFile);
08 int pageCount = doc.getDocumentCatalog().getAllPages().size();//计算pdf文档的总页数
09
10 string pdfFileName = Path.GetFileName(pdfFile);
11 int index = pdfFileName.LastIndexOf('.');
12 if (index != -1)
13 pdfFileName = pdfFileName.Substring(0, index);
14
15 string imgFile = Path.Combine(imgPath, pdfFileName);//转换成的图片文件
16
17 if (pageCount == 0) return;
18 if (pageCount == 1)
19 {
20 imgFile += ".png";
21 if (File.Exists(imgFile))
22 {
23 File.Delete(imgFile);
24 }
25 }
26 else
27 {
28 for (int i = 0; i < pageCount; i++)
29 {
30 string _imgFile = imgFile + (i + 1).ToString() + ".png";
31 if (File.Exists(_imgFile))
32 {
33 File.Delete(_imgFile);
34 }
35 }
36 imgFile += "%d.png";
37 }
38
39 ProcessStartInfo info = new ProcessStartInfo();
40 info.CreateNoWindow = true;
41 info.WindowStyle = ProcessWindowStyle.Hidden;
42 info.WorkingDirectory = System.Configuration.ConfigurationManager.AppSettings["GhostScriptView"];
43 info.Arguments = System.Configuration.ConfigurationManager.AppSettings["GhostScriptArguments"] + @" -sOutputFile=" + imgFile + "  " + pdfFile;
44 info.FileName = @"gswin32c.exe";
45 Process subProcess = new Process();
46 subProcess.StartInfo = info;
47 subProcess.Start();
48 subProcess.WaitForExit(int.MaxValue);
49 }

完成上述几步即可简便完美的完成office到彩色图片的转换,大家不妨也试试。

3.总结和说明:

Acrobat 8 Pro需要激活和注册;

Acrobat 8 Pro生成pdf的时候会有自己的虚拟打印机弹出框,当office文件为ppt或者xls的时候会打开文件然后再关闭,doc则不会;

office转换的pdf存放路径不要带有中文

最后:如有程序安装包和DLL需求消息我就可以了,祝大家工作愉快。

[转载]C#中WebBrowser控件使用技巧分享

mikel阅读(1081)

[转载]WebBrowser控件使用技巧分享 – 斯克迪亚 – 博客园.

在发布“淘宝登货员”时发现不少朋友对WebBrowser控件比较感兴趣,故在此分享一下使用心得。

首先分享一个WebBrowser的扩展类(此类所需的dll将在文章末尾提供下载),大家最好都使用这个类来替代.Net框架中的WebBrowser类,它提供了两个扩展功能:

1.屏蔽错误脚本提示。修正了WebBrowser控件本身屏蔽错误不全的问题,由启明提出,原文:http://www.cnblogs.com/hobe/archive/2007/01/14/619906.html

2.扩展NewWindow事件。修正了WebBrowser控件本身的NewWindow事件不提供新窗口Url的问题,通过新增的BeforeNewWindow事件予以支持,由佳文转载并整理,原文:http://www.cnblogs.com/yjwgood/archive/2009/02/09/1386789.html

整合后的代码如下:

public class ExWebBrowser : System.Windows.Forms.WebBrowser

{

private SHDocVw.IWebBrowser2 Iwb2;

protected override void AttachInterfaces(object nativeActiveXObject)

{

Iwb2 = (SHDocVw.IWebBrowser2)nativeActiveXObject;

Iwb2.Silent = true;

base.AttachInterfaces(nativeActiveXObject);

}

protected override void DetachInterfaces()

{

Iwb2 = null;

base.DetachInterfaces();

}

System.Windows.Forms.AxHost.ConnectionPointCookie cookie;

WebBrowserExtendedEvents events;

//This method will be called to give you a chance to create your own event sink

protected override void CreateSink()

{

//MAKE SURE TO CALL THE BASE or the normal events won’t fire

base.CreateSink();

events = new WebBrowserExtendedEvents(this);

cookie = new System.Windows.Forms.AxHost.ConnectionPointCookie(this.ActiveXInstance, events, typeof(DWebBrowserEvents2));

}

protected override void DetachSink()

{

if (null != cookie)

{

cookie.Disconnect();

cookie = null;

}

base.DetachSink();

}

//This new event will fire when the page is navigating

public event EventHandler BeforeNavigate;

/// <summary>

/// 可用于替代原来的NewWindow事件,新增了事件的Url参数支持。

/// </summary>

[CategoryAttribute(操作), DescriptionAttribute(经过扩展的NewWindow事件,使用继承后的WebBrowserExtendedNavigatingEventArgs类型参数实现Url参数支持)]

public event EventHandler BeforeNewWindow;

protected void OnBeforeNewWindow(string url, out bool cancel)

{

EventHandler h = BeforeNewWindow;

WebBrowserExtendedNavigatingEventArgs args = new WebBrowserExtendedNavigatingEventArgs(url, null);

if (null != h)

{

h(this, args);

}

cancel = args.Cancel;

}

protected void OnBeforeNavigate(string url, string frame, out bool cancel)

{

EventHandler h = BeforeNavigate;

WebBrowserExtendedNavigatingEventArgs args = new WebBrowserExtendedNavigatingEventArgs(url, frame);

if (null != h)

{

h(this, args);

}

//Pass the cancellation chosen back out to the events

cancel = args.Cancel;

}

//This class will capture events from the WebBrowser

class WebBrowserExtendedEvents : System.Runtime.InteropServices.StandardOleMarshalObject, DWebBrowserEvents2

{

ExWebBrowser _Browser;

public WebBrowserExtendedEvents(ExWebBrowser browser) { _Browser = browser; }

//Implement whichever events you wish

public void BeforeNavigate2(object pDisp, ref object URL, ref object flags, ref object targetFrameName, ref object postData, ref object headers, ref bool cancel)

{

_Browser.OnBeforeNavigate((string)URL, (string)targetFrameName, out cancel);

}

public void NewWindow3(object pDisp, ref bool cancel, ref object flags, ref object URLContext, ref object URL)

{

_Browser.OnBeforeNewWindow((string)URL, out cancel);

}

}

[System.Runtime.InteropServices.ComImport(), System.Runtime.InteropServices.Guid(“34A715A0-6587-11D0-924A-0020AFC7AC4D”),

System.Runtime.InteropServices.InterfaceTypeAttribute(System.Runtime.InteropServices.ComInterfaceType.InterfaceIsIDispatch),

System.Runtime.InteropServices.TypeLibType(System.Runtime.InteropServices.TypeLibTypeFlags.FHidden)]

public interface DWebBrowserEvents2

{

[System.Runtime.InteropServices.DispId(250)]

void BeforeNavigate2(

[System.Runtime.InteropServices.In,

System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.IDispatch)] object pDisp,

[System.Runtime.InteropServices.In] ref object URL,

[System.Runtime.InteropServices.In] ref object flags,

[System.Runtime.InteropServices.In] ref object targetFrameName, [System.Runtime.InteropServices.In] ref object postData,

[System.Runtime.InteropServices.In] ref object headers,

[System.Runtime.InteropServices.In,

System.Runtime.InteropServices.Out] ref bool cancel);

[System.Runtime.InteropServices.DispId(273)]

void NewWindow3(

[System.Runtime.InteropServices.In,

System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.IDispatch)] object pDisp,

[System.Runtime.InteropServices.In, System.Runtime.InteropServices.Out] ref bool cancel,

[System.Runtime.InteropServices.In] ref object flags,

[System.Runtime.InteropServices.In] ref object URLContext,

[System.Runtime.InteropServices.In] ref object URL);

}

}

public class WebBrowserExtendedNavigatingEventArgs : CancelEventArgs

{

private string _Url;

public string Url

{

get { return _Url; }

}

private string _Frame;

public string Frame

{

get { return _Frame; }

}

public WebBrowserExtendedNavigatingEventArgs(string url, string frame)

: base()

{

_Url = url;

_Frame = frame;

}

}

技巧1:在当前窗口内打开目标为新窗口的超链接

通过上述的扩展类支持得以实现,增加BeforeNewWindow事件的处理函数以进行处理:

void webBrowser1_BeforeNewWindow(object sender, EventArgs e)

{

WebBrowserExtendedNavigatingEventArgs eventArgs = e as WebBrowserExtendedNavigatingEventArgs;

if (eventArgs.Url.ToLower() != “about:blank”)

webBrowser1.Navigate(eventArgs.Url);

eventArgs.Cancel = true;

}

这种方法的弊病在于可能会错误地转向到网站的弹窗广告,为了规避此问题,可以强制取消一切弹出窗口,采取另一种方法实现当前窗口内打开新窗口超链接,增加DocumentCompleted事件的处理函数以进行处理:

void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)

{

if (webBrowser1.ReadyState > WebBrowserReadyState.Interactive)

{

foreach (HtmlElement f in webBrowser1.Document.Links)

{

var s = f.GetAttribute(“target”);

if (s != null && s.ToLower() == “_blank”) f.SetAttribute(“target”, “_self”);

}

}

}

此方法将遍历所有<a>元素,修改其目标为当前窗口,但是此方法又会引发新的问题,即如果页面中某些元素长时间都未加载完成时,此事件将迟迟不会被引发,也就是说用户必须要等到页面完完全全加载完毕之后才可能在当前窗口内打开新窗口超链接。

根据一些人的经验,DocumentCompleted事件会在每次加载网页的过程中触发两次,第一次触发时WebBrowser控件的ReadyState属性应为Interactive,第二次则为Complete,根据注释来看,Interactive应该是代表页面加载初步完成,已具有基本交互能力的状态,这时应当是理想的编辑状态,但我尝试将代码中的if (webBrowser1.ReadyState > WebBrowserReadyState.Interactive)修改为if (webBrowser1.ReadyState >= WebBrowserReadyState.Interactive),并没有什么明显效果,页面上的超链接还是要等待全部加载之后才会被修改。

为此我还尝试过在Navigated事件中进行处理,也不起作用。希望高人能对此给出完美的解决方案

技巧2:获取状态栏信息

增加StatusTextChanged事件处理函数进行处理:

void webBrowser1_StatusTextChanged(object sender, EventArgs e)

{

label1.Text = webBrowser1.StatusText;

}

技巧3:页面转向后改变地址栏地址

Navigated事件处理函数中改变地址栏地址是最恰当的:

private void webBrowser1_Navigated(object sender, WebBrowserNavigatedEventArgs e)

{

textBox1.Text = webBrowser1.Url.ToString();

}

技巧4:正确设置单选框的方法

建议使用执行单击事件的方式来设置单选框,而不是修改属性:

webBrowser1.Document.GetElementById(“RBT_A”).InvokeMember(“click”);

技巧5:正确设置联动型下拉列表的方法

比较常见的联动型多级下拉列表就是省/市县选择了,这种情况下直接设置选择项的属性不会触发联动,需要在最后执行触发事件函数才能正常工作:

foreach (HtmlElement f in s.GetElementsByTagName(“option”))

{

if (f.InnerText == 北京)

{

f.SetAttribute(“selected”, “selected”);

}

else

{

f.SetAttribute(“selected”, “”);

}

}

s.RaiseEvent(“onchange”);

此方法来源于:http://topic.csdn.net/u/20070309/11/aef46651-a15a-4777-b832-e71b09a7b9e0.html

技巧6:使用延迟等待服务器交互

有时会遇到联动型下拉列表需要同服务器交互的情况,如果只在一个函数里连续进行设置,往往会失败,因为代码执行速度很快,这期间页面还没有从服务器得到并装载数据。

这时候应当通过使用Timer等方法设置延迟间隔,再进行更改,需注意的是,不应当使用Sleep方法停止当前线程的执行以求达到延迟目的,因为WebBrowser控件也处于当前线程内,Sleep会同时暂停WebBrowser控件的运作。

还有一点需要注意,就是如果程序内用到多个Timer的话,有可能引发不可预料的错乱,详情及解决办法可参看我的前一篇文章

尚未解决的问题

有一个问题一直困扰我,始终也没找到相关的资料:

我现在可以通过WebBrowser实现对各种Html元素的操控,唯独无法控制Html的上传控件,即:

<input type=”file” size=”50″/>

应当是出于安全原因,JS代码无法访问和设置此控件所选择的文件路径,这是符合情理的,但是WebBrowser中也没能找到相关的支持,这样就无法实现自动上传等功能,希望有高手能指出解决办法。

还有一个似乎是无解的问题,就是读取和操作页面内的框架页或内嵌页的问题,很多人发出疑问,但始终没找到解决方法,此方面最典型的应用就是自动点嵌入式广告功能了,而现在不但无法点击,甚至都无法获取框架页的代码等信息。

其他相关技术资料

ExtendedWebBrowser的再扩展:http://hi.baidu.com/tanjian/blog/item/d46b83021772a10f4afb511c.html

C#利用WebBrowser操作HTMLhttp://hi.baidu.com/lightrock/blog/item/c4a61d2bf6dde5fce7cd40fb.html

关于C#.netWebBrowser如何处理多框架结构页面下载完成问题:http://blog1.poco.cn/myBlogDetail-htx-id-381745-userid-7940008-pri–n-0.shtml

利用webBrowser获取框架内Html页面内容:http://www.cnblogs.com/tishifu/archive/2007/12/10/990071.html

WebBrowser控件的简单应用2http://www.cnblogs.com/dlwang2002/archive/2007/04/11/709078.html

WebBrowser控件应用:弹出新窗体和关闭窗口:http://www.cnblogs.com/dlwang2002/archive/2007/04/14/713499.html

.Net 2.0实例学习:WebBrowser页面与WinForm交互技巧:http://smalldust.cnblogs.com/archive/2006/03/08/345561.html

WebBrowser控件禁用超链接转向、脚本错误提示、默认右键菜单和快捷键:http://www.zu14.cn/2008/11/19/webbrowser/

下载Interop.SHDocVw.dll:http://cid-0612298d2255e149.skydrive.live.com/self.aspx/.Public/%e6%96%87%e6%a1%a3/Interop.SHDocVw.zip

下载本文的PDF版本: http://cid-0612298d2255e149.skydrive.live.com/self.aspx/.Public/%e6%96%87%e6%a1%a3/WebBrowser%e6%8e%a7%e4%bb%b6%e4%bd%bf%e7%94%a8%e6%8a%80%e5%b7%a7%e5%88%86%e4%ba%ab.pdf