就是js条用C#winform js 交互后台代码出现错误:无法获取未定义或null引用的属性

C# winform WebBrowser怎么获取js中的变量的值?怎么触发js的事件?_百度知道
C# winform WebBrowser怎么获取js中的变量的值?怎么触发js的事件?
# 我有一个winform 程序 需要访问别人的网页 并且在我的程序里触发网页中的JS事件 但JS事件没有返回值.,我需要返回值?在线等.,所以只能获取事件中的变量,怎样才可以获得JS事件中的变量呢
我有更好的答案
参考如下代码:
//项目中添加Micrsoft.mshtml引用
//Begin temp.htm-------
&title&demo&/title&
&script language=&JavaScript& type=&text/javascript&&
var testText = &Zswang&;
function ShowMessage(AText)
alert(testText);
alert(AText);
//End temp.htm-------
using System.R
private void button1_Click(object sender, EventArgs e)
IHTMLDocument2 vDocument = webBrowser1.Document.DomDocument as IHTMLDocument2;
IHTMLWindow2 vWindow = (IHTMLWindow2)vDocument.parentW
Type vWindowType = vWindow.GetType();
object testText = vWindowType.InvokeMembe...
把出错行贴出来。。
其他类似问题
webbrowser的相关知识
等待您来回答
为您推荐:
下载知道APP
随时随地咨询
出门在外也不愁c#,winform
代码列表 - 为程序员服务
为程序员服务
c#,winform 相关代码
[代码片段(2行)]…
[代码片段(13行)]…
[代码片段(6行)]…
[代码片段(2行)]…
[代码片段(6行)]…
[代码片段(4行)]…
[代码片段(6行)]…
[代码片段(4行)]…
[代码片段(16行)]…
[代码片段(6行)]…
[代码片段(18行)]…
如果将窗体或容器控件(如Panel控件)的AutoScroll属性设置为True时,那么当窗体或Panel容不下其中的子控件时就会出现 滚动条,通过移动滚动条可以上下显示出窗体或Panel中的全部内容。但是默认情况下滚动条的移动只能通过鼠标直接拖动滚动条来实现,而不能通过鼠标的滚 轮来实现上下移动,因此需要手动添加代码来实现这个功能。
滚动鼠标的滚轮,触发的是窗体或控件上的 MouseWhe…
首先在窗体构造方法,里加入这样一句话
this.MouseWheel += new System.Windows.Forms.MouseEventHandler(this.panel1_MouseWheel);
#region 进入窗体时加载
public FormAlarmInfoQuer…
按ESC快捷键退出窗体
[代码片段(24行)]…
c#设置窗口全屏,只需在form的load事件中设置其TopMost属性为true,设置其边框样式为None,设置WindowState为Maximized即可:
private void Form1_Load(object s…
在winform中可以使用PictureBox控件来显示gif文件:
1. 从工具箱拖动picturebox控件到form上
2. 选中picturebox,选择属性,将picturebox的image设置为要添加的gif文…
在form关闭的同时停止BackgroundWork:
protected override void OnFormClosing(FormClosingEventArgs e) {
if (!mCompleted && ) {
backgroundWorker1.CancelAsync();
在winform中控件渲染如果很耗时的话,我们可以对控件做二次缓冲(double buffer)。
有两种方法可供选择
第一个方法是设置控件的DoubleBuffered属性,…
要让TextBox只接受数字,我们有两个选择:
1. 使用NumericUpDown控件替代文本框,这个控件只允许用户选择数字,用户可以使用上下键调整数字的大小

首先需要新建一个winform窗体,然后将AcceptDrop设置为true,这样程序就会接受DropEnter和DropDrop事件了。
当DropEnter事件触发时,需要将AllowedEffect属性设置为非None值比如e.Effect = DragDropEffects.Move.
当DragDrop事件触发时,可以得到一个文件全路径的字符串数组。
如下是示例代码…
Winform的TextBox控件有AutoComplete方法,但是仅支持前缀搜索,并且没办法通过重写的方式改变这种搜索方式。
我们可以通过TextBox控件的OnTextChanged事件来…
由于某种特殊需求,我需要在winform程序中模拟鼠标点击事件,经过Google,终于找到了如下解决方案。
using System.Windows.F
using Sy…
winform的WebBrowser控件,可以方便的载入页面并执行一些操作,我们可以注入自己的js脚本在页面中执行,方法如下:
HtmlElement head = webBrowser1.Doc…
WebBrowser控件用来显示网页内容,有时候我们需要在网页中执行一段自定义的javascript代码。
如下是实现和注释:
//找到head元素
HtmlElement head = webBrowser1.Document.GetElementsByTagName(&head&)[0];
//创建script标签
HtmlElement scriptEl = …
简单实现Label控件的拖动效果,还可以引用图片哦
using System.Collections.G
using System.D
using System.Drawi…
**c#使用System.Media.SoundPlayer播放资源文件中的wav文件**
using System.R
using System.IO;
using System.R
using System.M
using System.D
namespace CN.Out…
在winform程序中给form添加了keyup事件,但是程序却不响应键盘事件,解决办法是重写Form基类的ProcessCmdKey(ref Message msg, Keys keyData)方法。
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
winform相关标签
相关聚客文章
相关专栏文章VB调用C#写的WinForm.NET控件 - 袁永福 电子病历,医疗信息化 - 博客园
点击下载本文配套的演示程序代码。
一.前言:
  虽然IT开发技术日新月异,不过业界仍然运行着大量的VB系统,这些系统凝聚了不少客户的投资,应当要一定程度的保护和利用。因此也就产生了一种需求,也就是使用旧的开发技术仍然可以使用新技术的产出。本文就讨论如何在VB6.0开发中使用上WinForm.NET控件。[袁永福版权所有]
二.软件原理:
  运行VB IDE,打开或创建一个EXE工程,打开窗体设计器,如下图所示:&
  为了能在窗体上添加控件,需要往窗体左边的工具箱上添加项目,需要点击菜单项目&Project-Components&,此时会弹出如下图所示的对话框:&
&  点击&Browse&按钮,弹出文件选择对话框,这个对话框中优先选择OCX文件,而C#编译结果绝不可能是OCX文件的,此时即使选择一个.NET程序集DLL文件,无论如何必然会报错&This file not registerable as an ActiveX Component&。[袁永福版权所有]
  因此也就是说,使用C#开发的WinForm.NET控件是不可能直接通过传统的模式放置在VB窗体上。
  不过VB仍然可以通过COM方式调用.NET程序集中的对COM公开的类型。此时就可以想出一种曲线实现方式,那就是VB创建C#组件,该组件是一个WinForm.NET控件,然后调用Win32API SetParent函数,将WinForm.NET控件硬塞入VB窗体中。这样在用户界面上,用户能看到和使用WinForm.NET控件;在后台,VB代码能访问.NET组件提供的公开的属性、方法和事件,实现了VB全方位的调用WinForm.NET控件。&
三.C#开发
C#控件开发
  根据上述的软件原理,笔者开发一个WinForm.NET控件并成功的应用于VB6.0的开发中,现对软件进行说明。
  这个WinForm.NET控件名为MyWinFormControl,派生自System.Windows.Forms.UserControl类型,它包含在一个名为DCWinFormControlLib的C#项目中,项目输出类型为类库,目标框架为.NET2.0,添加了对System.Windows.Forms.dll的引用。
界面设计:
MyWinFormControl控件的用户界面设计如下:&
  在界面上放置一个名为&btnAction&的按钮,一个名为&myTextBox&的文本框。
定义公开属性和方法:
  打开该控件的C#代码文件,可以看到声明该类型的C#代码如下:
[System.Visible(true)]
[System.Runtime.InteropServices.Guid("F--E3")]
[System.SourceInterfaces(typeof(IComMyEvent))]
public partial class MyWinFormControl : UserControl
  这段代码中,第一行代码的ComVisible标记类型为COM公开的;第二行代码Guid标记了类型在COM中的唯一编号;第三行代码的ComSourceInterfaces指明该类型实现了名为IComMyEvent的事件接口。[袁永福版权所有]
  VB中无法直接绑定编译阶段未知的控件事件,同时也无法直接感应C#中的事件,为此需要编写一个接口通知VB存在若干事件,使得VB能绑定事件。因此在此定义了IComMyEvent接口,声明了C#控件中的事件,IComMyEvent接口定义如下
using System.Runtime.InteropS
[Guid("096EF9A6-24CB-DA38C9A6F1")]
[ComVisible( true )]
[InterfaceType( ComInterfaceType.InterfaceIsIDispatch )]
public interface IComMyEvent
/// &summary&
/// 按钮按下事件
/// &/summary&
[DispId(12340)]
void ComButtonClick();
/// &summary&
/// 文本内容修改事件t
/// &/summary&
[DispId(12350)]
void ComTextChanged();
/// &summary&
/// 无参数无返回值委托类型
/// &/summary&
public delegate void VoidEventHandler();
而后在控件的C#代码中添加以下代码:
#region 实现 IComMyEvent 中的成员
/// &summary&
/// 按钮按下事件
/// &/summary&
public event VoidEventHandler ComButtonClick = null;
/// &summary&
/// 文本内容修改事件
/// &/summary&
public event VoidEventHandler ComTextChanged = null;
#endregion
  这样C#中定义的事件在VB中就能绑定了,以下代码就是触发这些事件的:
private void btnAction_Click(object sender, EventArgs e)
if (ComButtonClick != null)
// 触发ComButtonClick事件
ComButtonClick();
private void myTextBox_TextChanged(object sender, EventArgs e)
if (ComTextChanged != null)
// 触发ComTextChanged事件
ComTextChanged();
  对控件实现了COM公开的事件后,就可以编写COM公开的属性和方法,其代码如下:
/// &summary&
/// 公开的属性
/// &/summary&
public string UserText
return myTextBox.T
myTextBox.Text =
/// &summary&
/// 公开的方法
/// &/summary&
public double Calcute(double p)
return Math.Sin(p);
  这个用户控件虽然能在VB代码中创建和访问,但还不能直接拖放到VB窗体上,此时还需要使用代码将C#控件添加到VB窗体上:
/// &summary&
/// 将控件添加到指定句柄的窗体中
/// &/summary&
/// &param name="containerHandle"&指定的窗体句柄对象&/param&
/// &returns&操作是否成功&/returns&
public bool AppendToContainerControl(int containerHandle)
CrossPlatformControlHostManager man = new CrossPlatformControlHostManager();
man.ContainerHandle = new IntPtr(containerHandle);
man.ControlHandle = this.H
man.Dock = this.D
return man.UpdateLayout();
  在这个函数中,参数为VB窗体中某个控件的句柄,该控件用于承载C#控件。这段代码使用了笔者编写的一个CrossPlatformControlHostManager类型,该类型专业用于执行跨应用程序的控件承载,实现&乾坤大挪移&,该类型首先定义了几个属性:[袁永福版权所有]
private IntPtr _ControlHandle = IntPtr.Z
/// &summary&
/// 操作的控件句柄对象
/// &/summary&
public IntPtr ControlHandle
get{ return _ControlH }
set{ _ControlHandle = }
private IntPtr _ContainerHandle = IntPtr.Z
/// &summary&
/// 容器元素对象
/// &/summary&
public IntPtr ContainerHandle
get{ return _ContainerH }
set{ _ContainerHandle = }
private DockStyle _Dock = DockStyle.F
/// &summary&
/// 停靠样式
/// &/summary&
public DockStyle Dock
get{ return _D }
set{ _Dock = }
此外还定义了一个方法,其代码如下:
/// &summary&
/// 更新排版
/// &/summary&
/// &returns&操作是否成功&/returns&
public bool UpdateLayout()
WindowInformation info = new WindowInformation(this.ControlHandle);
WindowInformation container = new WindowInformation(this.ContainerHandle);
if (info.CheckHandle() == false
|| container.CheckHandle() == false)
return false;
if (info.ParentHandle != container.Handle)
if (info.SetParent(container.Handle) == false)
return false;
Rectangle clientRect = container.ClientB
Rectangle bounds = info.B
Rectangle descBounds =
switch (this.Dock)
case DockStyle.Fill:
descBounds = clientR
case DockStyle.Bottom:
descBounds = new Rectangle(
clientRect.Height - bounds.Height,
clientRect.Width,
bounds.Height);
case DockStyle.Left:
descBounds = new Rectangle(
bounds.Width,
clientRect.Height);
case DockStyle.Right:
descBounds = new Rectangle(
clientRect.Width - bounds.Width,
bounds.Width,
clientRect.Height);
case DockStyle.Top:
descBounds = new Rectangle(
clientRect.Width,
bounds.Height);
if (descBounds != bounds)
info.Bounds = descB
return true;
  这段代码中,用到了一个WindowInformation的类型,这个笔者编写的另外一个类型,实现了一些窗体相关的Win32API的封装。
  在UpdateLayout中,首先判断双方的窗体句柄是否有效,然后判断两个窗体控件的父子关系,若不是则设置控件的父子关系,底层调用的是Win32API函数SetParent。[袁永福版权所有]
  然后根据对象的Dock属性值和父控件的客户区大小来计算出子控件应有的位置和大小,然后设置子控件的位置和大小。
  这样这个控件本身开发完毕了。
设置程序集
另外还需要对C#项目进行一些设置来完成公开COM开发接口的工作。
打开工程文件中的AssemblyInfo.cs文件,该文件默认在Properties目录下,设置其代码内容为:
using System.R
using pilerS
using System.Runtime.InteropS
// 有关程序集的常规信息通过以下
// 特性集控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("袁永福的COM测试")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("DCWinFormControlLib")]
[assembly: AssemblyCopyright("Copyright &
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 将 ComVisible 设置为 false 使此程序集中的类型
// 对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型,
// 则将该类型上的 ComVisible 特性设置为 true。
[assembly: ComVisible(true)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("c241537f-dfe8-7f9437ee7c")]
[assembly: AssemblyVersion("1.0.0.*")]
  这段代码中,重点之一是&ComVisible&,这是程序集允许向COM公开;还有一个&Guid&,这是为类型库提供一个编号;还有&AssemblyVersion&设置程序集的版本号,这里有一个*表示这个版本号是累计的,[袁永福版权所有]每次编译生成的程序集的版本号都会增加的。
要提供COM开发接口,.NET程序集必须是强名称的。
要对.NET程序集强名称,首先是要有一个SNK签名文件,若没有,则可以使用.NET SDK中的SN.EXE工具生成一个SNK文件。
打开VS.NET自带的.NET SDK命令行界面,执行命令行&SN.EXE &k d:\dctest.snk&,即可生成一个强名称使用的SNK文件。则命令行输出文本为:
Microsoft(R) .NET Framework 强名称实用工具 版本 4.0.30319.1版权所有(C) Microsoft Corporation。保留所有权利。
密钥对写入到 d:\dctest.snk
在VS.NET中打开项目的属性页面,切换到&签名&页面,如下图所示:
勾选&为程序集签名&,然后在强名称秘钥文件下列列表中点击&浏览&项目,选择SNK文件。然后重新编译,即可生成强名称的.NET程序集DLL文件了。
注册和生成类型库文件
当成功的编译生成.NET程序集DLL文件后,需要对该程序集进行注册和生成COM开发使用的类型库文件。[袁永福版权所有]
在VS.NET命令行环境,执行命令&regasm& 编译输出目录\DCWinFormControlLib.dll /tlb /codebase&,则该命令行输出的内容如下:
Microsoft(R) .NET Framework 程序集注册实用工具 4.0.30319.1版权所有(C) Microsoft Corporation 。保留所有权利。
成功注册了类型成功注册了导出到&编译输出目录\dcwinformcontrollib.tlb&的程序集和类型库
特别要注意,对于Win7或更高系统中,必须以管理员的模式启动VS.NET命令行环境,否则程序会爆无权限的错误。
四.VB程序开发
  当成功的执行完上述操作后,我们就已经生成了可用于VB开发的.NET程序组件了。
&  笔者使用VB6.0开发了一个程序能应用MyWinFormControl控件,程序已经写好,现对其进行说明。[袁永福版权所有]
  首先该VB工程名为DCVBExe,它是 一个普通的EXE的VB工程。在VB6.0 IDE中点击菜单&工程-引用&,显示如下图所示的添加引用对话框:
在该对话框中就可以看到电脑系统中已经有了DCWinFormControlLib的引用了,VB工程就包含了该引用。
本VB工程的主窗体设计如下:
这个VB窗体中放置了一个名为&cmdSetText&的按钮控件,还有一个名为&picContainer&的PictureBox控件。
该窗体的VB代码如下:
Option Explicit
' 定义控件变量
Private WithEvents myWinFormControl As DCWinFormControlLib.myWinFormControl
' VB按钮点击事件处理
Private Sub cmdSetText_Click()
myWinFormControl.UserText = "袁永福到此一游"
' 窗体加载事件
Private Sub Form_Load()
Set myWinFormControl = New DCWinFormControlLib.myWinFormControl
myWinFormControl.Dock = 4
myWinFormControl.AppendToContainerControl Me.picContainer.hWnd
' 窗体大小改变事件
Private Sub Form_Resize()
If Me.ScaleWidth & 3000 And Me.ScaleHeight & 3000 Then
Me.picContainer.Width = Me.ScaleWidth - Me.picContainer.Left - 50
Me.picContainer.Height = Me.ScaleHeight - Me.picContainer.Top - 50
If Not myWinFormControl Is Nothing Then
myWinFormControl.AppendToContainerControl Me.picContainer.hWnd
' 窗体卸载事件
Private Sub Form_Unload(Cancel As Integer)
Set myWinFormControl = Nothing
' 响应控件ComButtonClick事件
Private Sub myWinFormControl_ComButtonClick()
MsgBox "用户点击了控件中的按钮"
' 响应控件ComTextChanged事件
Private Sub myWinFormControl_ComTextChanged()
Me.Caption = "用户修改了控件中的文字"
  在这段代码中&Private WithEvents myWinFormControl As DCWinFormControlLib.myWinFormControl&定义了C#控件的变量,此处使用了WithEvents关键字声明变量可以绑定事件,此时就可以添加myWinFormControl_ComButtonClick方法和myWinFormControl_ComTextChanged方法,这两个方法就是控件的事件处理。[袁永福版权所有]
  在窗体加载代码中调用了&myWinFormControl.Dock = 4&,实际上就是设置了C#中的System.Windows.Forms.Control类型的Dock属性,由于VB中还不能识别System.Windows.Forms.DockStyle枚举类型,因此只能设置整数,这里的整数4等价于DockStyle.Right值。
  由于MyWinFormControl类型只声明了IComMyEvnet接口,没实现其他接口,因此在开发阶段,VB无法识别控件的所有的属性和方法,因此在编写代码的时候无法弹出类型成员列表,因此只能利用VB的动态语言特性先硬编码,在运行时VB会后期的识别和调用组件的公开的类型成员。
  在窗体加载时还运行了&myWinFormControl.AppendToContainerControl Me.picContainer.hWnd&,用于将控件作为图片框的子控件硬塞入到VB窗体中。
  在窗体大小改变事件中,这行代码还重新执行了一遍,用于根据作为容器的图片框控件的大小来更新WinForm.NET控件的大小。
  这样VB程序开发完毕,编译执行EXE文件,该VB程序的运行界面如下图所示:
  本程序有一个已知的BUG,那就是输入焦点分配有点混乱。由于很多代码绕过了VB运行库,而是在.NET运行库中运行,这是一种不多见的软件运行架构。因此用户界面上尽量少放置或不放置可以获得焦点的VB控件。
五.常见问题和调试
  VB调用.NET控件是一种异构软件架构,很容易出现各种问题,最常见的是在VB中试图创建控件对象实例时爆出&ActiveX component can't create object&的错误。
解决方法如下
1.&&&&&& 首先确定系统安装了.NET框架。2.&&&&&& 执行命令行&regasm 程序集目录\DCWinFormControlLib.dll &&/tlb& &/codebase&。3.&&&&&& 若还不行需要清理下系统注册表,对于本控件,设置的GUID值为&F--E3&,因此使用注册表编辑器打开注册项目路径&HKEY_CLASSES_ROOT\CLSID\{F--E3}\InprocServer32&,可以看到该组件历次版本的注册信息,删掉这些注册表项目,然后重新运行一遍regasm命令行。4.&&&&&& 可以使用gacutil工具将DCWinFormControlLib.dll放置在全局程序集缓存中。5.&&&&&& 还可以将VB编译生成的EXE文件放在DCWinFormControlLib.dll和DCWinFormControl.tlb的文件目录中运行。
  另外一个有可能遇到的情况就是VB程序不能运行,运行VB程序需要系统中有VB虚拟机,要检查Windows系统目录下的System32子目录中是否存在MSVBVM60.DLL,若没有则需要下载安装VB6运行时,推荐下载地址为&/download/5/a/d/5ad868a0-8ecd-4bb0-a882-fe53eb7ef348/VB6.0-KB.exe&。[袁永福版权所有]
  本文虽然讨论的仅仅是VB中调用C#写的WinForm控件,实际上可以扩展开来使用,比如可以以此为基础,实现在VB\PB\DELPHI\VC窗体中嵌入WinForm.NET控件,由于WinForm.NET控件能承载WPF元素,因此也就能在VB中嵌入WPF程序了。
随笔 - 177
评论 - 1662有时候我们需要在C#中直接调用js方法,这是完全没问题的。当然,我们也可以把js代码转化为C#,然后在C#中执行,但是这个就得花时间了~~下面我给大家介绍下一种直接在C#中调用JS文件的方法。
0、贴个效果图
1、创建个Winform项目。
2、在From1上增加一个文本框一个按钮。
3、在解决方案中创建一个test.js文件。
test.js代码如下:
function sayHello(str) {
return "Hello," +
4、进入Form1.cs编码后台代码。
Form1.cs代码如下:
private void button1_Click(object sender, EventArgs e)
string path = AppDomain.CurrentDomain.BaseDirectory + "test.js";
string str2 = File.ReadAllText(path);
string fun = string.Format(@"sayHello('{0}')" ,this.textBox1.Text.Trim());
string result = ExecuteScript(fun, str2);
MessageBox.Show(result);
/// &summary&
/// 执行JS
/// &/summary&
/// &param name="sExpression"&参数体&/param&
/// &param name="sCode"&JavaScript代码的字符串&/param&
/// &returns&&/returns&
private string ExecuteScript(string sExpression, string sCode)
MSScriptControl.ScriptControl scriptControl = new MSScriptControl.ScriptControl();
scriptControl.UseSafeSubset = true;
scriptControl.Language = "JScript";
scriptControl.AddCode(sCode);
string str = scriptControl.Eval(sExpression).ToString();
catch (Exception ex)
string str = ex.M
return null;
效果图如第0步。
注:在后台代码中如果找不到命名空间:MSScriptControl.ScriptControl,请参照下图增加引用。
&阅读指引:二
& & & & & & & &
阅读(...) 评论()想问下在C#的winform中是可以用webBrower和htmlDcoment来获取页面上JS执行后的网页源码,但是在。net里网页应该怎么做呢
[问题点数:40分,无满意结帖,结帖人q]
想问下在C#的winform中是可以用webBrower和htmlDcoment来获取页面上JS执行后的网页源码,但是在。net里网页应该怎么做呢
[问题点数:40分,无满意结帖,结帖人q]
不显示删除回复
显示所有回复
显示星级回复
显示得分回复
只显示楼主
相关帖子推荐:
2014年2月 .NET技术大版内专家分月排行榜第二
2014年4月 .NET技术大版内专家分月排行榜第三2014年3月 .NET技术大版内专家分月排行榜第三2013年10月 .NET技术大版内专家分月排行榜第三
2015年4月 .NET技术大版内专家分月排行榜第一
2015年3月 .NET技术大版内专家分月排行榜第二
匿名用户不能发表回复!|
每天回帖即可获得10分可用分!小技巧:
你还可以输入10000个字符
(Ctrl+Enter)
请遵守CSDN,不得违反国家法律法规。
转载文章请注明出自“CSDN(www.csdn.net)”。如是商业用途请联系原作者。

我要回帖

更多关于 c winform js 的文章

 

随机推荐