高分求,自定义控件。

gtiroy 2008-11-06 02:09:15
初次涉及到自定义控件。自己没有头绪。希望大家能给我贴出一个自定义控件的源代码(无论什么控件都可以)。
邮箱gtiroy#yahoo.cn
...全文
233 11 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
byte377 2008-11-12
  • 打赏
  • 举报
回复
将自定义.NET控件嵌入IE浏览器
利用Visual Studio .NET开发自定义的WinForm控件,恐怕大家都已经很熟悉了。正常情况下,这种控件只能用在基于.NET的Windows Application程序开发上,而无法直接嵌入到IE,这不免让人感觉遗憾。
毕竟.NET控件已经不同于在Win32下用Delphi或C++Builder开发的自定义控件。基于.NET开发的任何受控装配件(Assembly)都是IL代码,可以在运行期被.NET FrameWork进行反射(Reflection)、安全检查。应该有办法让这种特殊控件被IE使用。
经过几日的研究,终于找到一个方法可以将.NET WinForm自定义控件即用于普通的Windows Application开发,又可以将其当做ActiveX控件直接嵌入到IE中,同js脚本语言进行互动(客户端需要安装.NET FrameWork)。这无疑可以大大的节省客户端代码在Windows和Web应用的移植工作,并保持控件代码的最大复用。
原理为:.NET自定义控件没有普通ActiveX的GUID唯一标示,同时为了解决以往版本冲突引起的“DLL地狱”问题,.NET控件不再向注册表进行类型的注册,而是不同的版本部署在应用程序当前目录或GAC(Globle Assembly Cache)中。.NET可以为.NET控件产生强名称的代理,从而提供给其他语言比如VB、VC、Delphi等调用。我们只需要在装配件文件(C#下为AssemblyInfo.cs)中就可以设置这些开关,也可以在VS.NET的项目属性中设置。这样.NET就可以为我们自动产生ClassLibrary对应的OLE对象特征。然后我们再创建ActiveX用到的事件接口、安全接口等。
第一步――创建.NET自定义控件。
下面用Visual Studio.NET 2005 Professional为开发工具进行介绍。
创建新项目,选择Windows Control Library。名称为默认的:WindowsControlLibrary1。
在界面中放置如下控件:TextBox、Button。这就是界面上所有的内容。双击界面中的Button控件,书写如下代码:
private void button1_Click(object sender, EventArgs e)
{
StreamWriter bplStreamWriter = new StreamWriter(
System.Environment.GetEnvironmentVariable("SystemDrive")+"\\a.txt",
true);
bplStreamWriter.WriteLine(DateTime.Now.ToUniversalTime() +
"\tInserted Text by .Net WinFormControl.");
bplStreamWriter.Close();
}

该部分代码表示在系统盘根目录下创建一个文件,并添加一行文本。为了能调用StreamWriter类,我们要添加System.IO名称空间。
同时添加自定义控件的属性:ButtonCaption。
[Category("自定义控件的属性")]
[Description("设置按钮的文本内容")]
public string ButtonCaption
{
get
{
return button1.Text;
}
set
{
button1.Text = value;
}
}
添加委托(delegate)并创建按键点击事件:
// 声明按键点击事件类型
public delegate void ButtonClickHandler(string SendMsg);
public partial class UserControl1 : UserControl
{
// 声明按键点击事件
public event ButtonClickHandler OnButtonClick;

在刚才的按钮点击函数中增加点燃事件的代码:
private void button1_Click(object sender, EventArgs e)
{
……
if (OnButtonClick != null)
OnButtonClick(textBox1.Text);
}
增加公共方法SetText:
public void SetText(string text)
{
textBox1.Text = text;
}
此时点击运行,可以利用VS.NET 2005自带的控件容器运行我们的控件。通过属性编辑器可以验证ButtonCaption属性。点击Button可以发现在系统盘创建文件,并添加了文本内容。您也可以新创建一个Windows Application项目,将这个控件加入后,测试其属性、事件和方法,这里就不介绍了。

上一篇我介绍了如何创建普通的.NET控件。为了能让.NET控件嵌入到IE中,这次我们来
为控件添加COM特性。

打开项目属性,在Application页面中点击“Assembly Information…”按钮,打开
Make assembly COM-Visible选项。

进入项目属性的Build页面,打开Register for COM interop选项。

保存配置后进行Build,此时的.NET控件已经具备普通OLE对象的特性。打开VS.NET自带
的OLE/COM对象查看器(默认目录为C:\Program Files\Microsoft Visual Studio
8\Common7\Tools\Bin\OleView.Exe)。我们可以在.NET Category下看到我们创建的控
件WindowsControlLibrary1.UserControl1。所有的信息已经被自动注册,包括控件的
强路径。

其实,此时的.NET控件已经可以放入IE了,只是还不能算是合格的ActiveX控件,但仍
然是合格的.NET控件。

我们编写一个htm文件来测试该控件。htm文件内容如下:

文本框: <HTML>
<HEAD>
<meta http-equiv="Content-Type" content="text/html; charset=GBK">
</HEAD>
<body bgcolor="#D8EEFB">
<OBJECT id="UserControl1"
classid="WindowsControlLibrary1.dll#WindowsControlLibrary1.UserControl1"
VIEWASTEXT></OBJECT>
<br><br><br><br>
<input type='button' value=' 调用方法' onclick='UserControl1.SetText("Hello World!");'>
<br><br><br><br>
<input type='button' value=' 设置属性' onclick='UserControl1.ButtonCaption =
"Set";'>
</body>
</HTML>


将htm文件和WindowsControlLibrary1.dll部署在IIS的虚拟目录中,用浏览器浏览,就
可以看到如下效果。

虽然.NET控件可以被显示在IE中,但是.NET FrameWork能动态检查代码的安全性,因为
没有安全授权,不安全的代码将无法执行。比如点击按钮,我们可以得到如下提示。

有意思的是,只要该控件在装载时没有不安全代码,IE就不会有任何的提示,不同于IE
对加载ActiveX时的安全警告。这样说明IE对.NET的代码安全性是交给FrameWork处理
的。因此此类控件也有一种用处,就是不必数字签名,就可以加载显示在用户的IE浏览
器中,并顺利执行安全的受控代码。当然前提是用户需要安装.NET FrameWork。

此时我们还是没有得到一个真正的ActiveX控件,虽然它可以通过IIS发布在Web页面
中,也可以执行安全的代码。但存在如下局限性:无法发布到其他Web服务器上、无法
访问本地资源、js脚本无法响应控件的事件等。

下一篇我们将讨论.NET自定义控件如何实现所有的COM对象接口,包括属性、方法、事
件。并利用js脚本在Web页面中形成互动。

















这次我们将讨论.NET自定义控件如何实现所有的COM对象接口,包括属性、方法、事件。并利用js脚本在Web页面中形成互动。
按照上一篇我们介绍的将.NET控件添加COM特性后,VS.NET已经自动注册了该控件的属性、方法和事件,只是还需要我们实现事件接口。
为了实现事件接口,我们需要添加如下代码:
[ComVisible(true)]
[Guid("43BCDB16-0281-487b-BB53-997546122442")]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface UserControl1Events
{
[DispId(0)]
void OnButtonClick(string SendMsg);
}
为了保证Guid的有效性,我们可以使用VS.NET的Create GUID工具创建。接口中的方法就是我们要触发的事件函数。该函数的声明要参照我们控件中的事件,名称必须保持一致。
public event ButtonClickHandler OnButtonClick;
下一步我们就是要为我们的控件类创建Guid,并实现上面声明的事件接口。这里我们不要试图去实现事件接口,而是要用属性的方式去引用该COM接口。
[Guid("FBA0FCC2-D75F-40a5-9C8C-1C9D03813731")]
[ComSourceInterfaces(typeof(UserControl1Events))]
public partial class UserControl1 : UserControl
{
Build后我们已经得到一个具有公共属性、方法和事件的COM控件了。
我们创建html文件来测试新的ActiveX控件,代码如下:
<HTML>
<HEAD>
<meta http-equiv="Content-Type" content="text/html; charset=GBK">
</HEAD>
<script language='javascript' for='usercontrol1' event='OnButtonClick(Message)'>
alert("响应ActiveX触发的事件成功。"+Message);
window.defaultStatus = "OnButtonClick()";
</script>

<body>
<object id="usercontrol1" classid="clsid:FBA0FCC2-D75F-40a5-9C8C-1C9D03813731">
</object>
<br><br><br><br>
<input type='button' value=' 调用ActiveX方法' onclick='usercontrol1.SetText("Hello World!");'>
<br><br><br><br>
<input type='button' value=' 设置ActiveX属性' onclick='usercontrol1.ButtonCaption = "Set";'>

</HTML>
这次我们不再需要IIS,可以直接运行该html文件。可以得到下面的结果:
我们的.NET控件已经可以象普通的ActiveX控件使用。同时,该.NET控件也可以继续被.NET 的Windows Application使用。
长沙三毛 2008-11-11
  • 打赏
  • 举报
回复
下面是一个完整的TextBox扩展类TTextBoxEx,基本功能是:设置其ReadOnly属性是是否保持背景颜色。拷贝下面代码成一个.cs文件,添加到你的Windows应用程序的项目中,编译后在工具箱就可以看到该组件。搂主可以到俺的博客里看更复杂的扩展类:TNumEditBox。

[ToolboxItem(true)]
[ToolboxBitmap(typeof(TextBox))]
public class TTextBoxEx : TextBox
{
private string m_version;
private bool m_keepBackColorWhenReadOnly = true;
private Color m_backColor;
private Color m_backColorWhenReadOnly;

public TTextBoxEx()
{
this.m_version = "1.0";
this.ForeColor = Color.Blue;

m_backColor = base.BackColor;
base.ReadOnly = true;
m_backColorWhenReadOnly = base.BackColor;
base.ReadOnly = false;
}

[DefaultValue(typeof(Color), "Blue")]
public new Color ForeColor
{
get { return base.ForeColor; }
set { base.ForeColor = value; }
}

[DefaultValue(typeof(Color), "Window")]
public new Color BackColor
{
get { return m_backColor; }
set
{
if (m_backColor != value)
{
m_backColor = value;
this.OnBackColorChanged(EventArgs.Empty);
}
}
}

[Category("Custom")]
[Description("Set/Get if keep backcolor when textbox is readonly.")]
[DefaultValue(true)]
public bool KeepBackColorWhenReadOnly
{
get { return m_keepBackColorWhenReadOnly; }
set
{
if (m_keepBackColorWhenReadOnly != value)
{
m_keepBackColorWhenReadOnly = value;
this.OnBackColorChanged(EventArgs.Empty);
}
}
}

[Category("Custom")]
[Description("Get TNumEditBox Version.")]
public string Version
{
get { return m_version; }
protected set { m_version = value; }
}

public new bool ReadOnly
{
get { return base.ReadOnly; }
set
{
if (base.ReadOnly != value)
{
base.ReadOnly = value;
this.OnBackColorChanged(EventArgs.Empty);
}
}
}

protected override void OnBackColorChanged(EventArgs e)
{
base.OnBackColorChanged(e);

if (this.ReadOnly)
{
if (m_keepBackColorWhenReadOnly)
{
base.BackColor = m_backColor;
}
else
{
base.BackColor = m_backColorWhenReadOnly;
}
}
else
{
base.BackColor = m_backColor;
}
this.Invalidate();
}
}
mjjzg 2008-11-09
  • 打赏
  • 举报
回复
MSDN
yilanwuyu123 2008-11-09
  • 打赏
  • 举报
回复
mark 反编译
shazhixiaojie 2008-11-07
  • 打赏
  • 举报
回复
友情帮顶~
bingdian37 2008-11-07
  • 打赏
  • 举报
回复
Reflector.exe看也可以

你用vs2008直接调试到ms的源代码中去也可以

haiyangshao 2008-11-07
  • 打赏
  • 举报
回复
请问到哪个网站下载查看微软的开源码呢? 我正在开发一些控件, 但碰到一些困难, 想参考一下微软的开发方式!

[Quote=引用 4 楼 gxtiou 的回复:]
微软都已经开源来 直接找内置控件的源码看不更好?
[/Quote]
gxtiou 2008-11-06
  • 打赏
  • 举报
回复
微软都已经开源来 直接找内置控件的源码看不更好?
周公 2008-11-06
  • 打赏
  • 举报
回复
定义用户控件的属性和方法
可以采用定义页面的属性和方法时所用的方式定义用户控件的属性和方法。通过定义用户控件的属性,就能以声明方式及利用代码设置其属性。

用户控件中的事件
用户控件包含 Web 服务器控件时,可以在用户控件中编写代码来处理其子控件引发的事件。例如,如果用户控件包含一个 Button 控件,则可以在用户控件中为该按钮的 Click 事件创建处理程序。

默认情况下,用户控件中的子控件引发的事件对于宿主页不可用。但是,可以为用户控件定义事件并引发这些事件,以便将子控件引发的事件通知宿主页。进行此操作的方式与定义任何类的事件一样。
周公 2008-11-06
  • 打赏
  • 举报
回复
用户控件结构
ASP.NET Web 用户控件与完整的 ASP.NET 网页(.aspx 文件)相似,同时具有用户界面页和代码。可以采取与创建 ASP.NET 页相似的方式创建用户控件,然后向其中添加所需的标记和子控件。用户控件可以像页面一样包含对其内容进行操作(包括执行数据绑定等任务)的代码。

用户控件与 ASP.NET 网页有以下区别:

用户控件的文件扩展名为 .ascx。

用户控件中没有 @ Page 指令,而是包含 @ Control 指令,该指令对配置及其他属性进行定义。

用户控件不能作为独立文件运行。而必须像处理任何控件一样,将它们添加到 ASP.NET 页中。

用户控件中没有 html、body 或 form 元素。这些元素必须位于宿主页中。

可以在用户控件上使用与在 ASP.NET 网页上所用相同的 HTML 元素(html、body 或 form 元素除外)和 Web 控件。例如,如果您要创建一个将用作工具栏的用户控件,则可以将一系列 Button Web 服务器控件放在该控件上,并创建这些按钮的事件处理程序。
浮生若梦丶 2008-11-06
  • 打赏
  • 举报
回复
我这是实现省市2级联动的自定义控件,很简单,自定义控件的事件我也还不会,只会属性==================前台=============================

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="DropAreaCity.ascx.cs" Inherits="JYWebBook.UserControl.DropAreaCity" %>
<%@ Register Assembly="System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
Namespace="System.Web.UI" TagPrefix="asp" %>

<asp:DropDownList ID="dropArea" runat="server" AutoPostBack="True" OnSelectedIndexChanged="dropArea_SelectedIndexChanged">
</asp:DropDownList>
<asp:DropDownList ID="dropCity" runat="server">
<asp:ListItem Value="000">--请选择--</asp:ListItem>
</asp:DropDownList>


==================后台=============================

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Data.SqlClient;
using DLL;
using Model;

namespace JYWebBook.UserControl
{
public partial class DropAreaCity : System.Web.UI.UserControl
{
memberDB member = new memberDB();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
BindArea();
}
}

/// <summary>
/// 绑定省份
/// </summary>
private void BindArea()
{
ListItem lItem = new ListItem();

lItem.Text = "--请选择--";
lItem.Value = "000";

DataTable dt = tools.ConvertDataReaderToDataTable(member.getArea());
if (dt.Rows.Count != 0)
{
dropArea.DataSource = member.getArea();
dropArea.DataTextField = "provName";
dropArea.DataValueField = "provcode";
dropArea.DataBind();

dropArea.Items.Add(lItem);
dropArea.ClearSelection();
if (dropArea.Items.FindByValue("000") != null)
{
dropArea.Items.FindByValue("000").Selected = true;
}
}
}
/// <summary>
/// 绑定城市
/// </summary>
/// <param name="areaCode">省份代码</param>
private void BindCity(string areaCode)
{
ListItem lItem = new ListItem();

lItem.Text = "--请选择--";
lItem.Value = "000";

DataTable dt = tools.ConvertDataReaderToDataTable(member.getAreaCity("", areaCode));
if (dropArea.SelectedValue != "000")
{
if (dt.Rows.Count != 0)
{
dropCity.DataSource = member.getAreaCity("", areaCode);
dropCity.DataTextField = "CityName";
dropCity.DataValueField = "CityCode";
dropCity.DataBind();

dropCity.Items.Add(lItem);
dropCity.ClearSelection();
if (dropCity.Items.FindByValue("000") != null)
{
dropCity.Items.FindByValue("000").Selected = true;
}
}
}
else
{
dropCity.Items.Clear();
lItem.Text = "--请选择--";
lItem.Value = "000";
dropCity.Items.Add(lItem);
dropCity.ClearSelection();
if (dropCity.Items.FindByValue("000") != null)
{
dropCity.Items.FindByValue("000").Selected = true;
}
}
}
/// <summary>
/// 省份下拉框选择改变事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void dropArea_SelectedIndexChanged(object sender, EventArgs e)
{
string strAreaCode = dropArea.SelectedValue.ToString();
BindCity(strAreaCode);
}

/// <summary>
/// 选中的省份文本
/// </summary>
public string SelectedAreaText
{
get
{
return dropArea.SelectedItem.Text;
}
}
/// <summary>
/// 选中的省份值
/// </summary>
public string SelectedAreaValue
{
get
{
return dropArea.SelectedValue;
}
}
/// <summary>
/// 选中的城市文本
/// </summary>
public string SelectedCityText
{
get
{
return this.dropCity.SelectedItem.Text;
}
}
/// <summary>
/// 选中的城市值
/// </summary>
public string SelectedCityValue
{
get
{
return dropCity.SelectedValue;
}
}
}
}

8,833

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 组件/控件开发
社区管理员
  • 组件/控件开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧