分享
 
 
 

ASP.NET中设计带事件定制控件

王朝asp·作者佚名  2008-05-21
窄屏简体版  字體: |||超大  

在试图为客户开发一个在网络上运行的应用程序时,我发现有关正确使用.NET Web控件的讨论非常少。下面是使用.NET Web控件的常见问题:

1、如何使这些控件间相互通讯?

2、如何使这些控件保持状态?

3、如何将多个控件有效地联接在一个网页上?

我是一名ASP开发人员,发现转向ASP.NET并非是件轻而易举的事。我最初的想法是通过Session对象或使用查询语句保持状态,但发现这二种方法都太邋遢,而且,当试图对网页上的所有Web控件进行同步时就会出现问题。我在偶然间发现了一篇有关在Web控件中创建事件的文章,但在实践中仍然吃足了苦头,因此,我认为提供一个有关正确地创建Web控件并同时创建定制事件的实例是非常重要的。

讨论将按照下面的顺序进行:

1、创建一个Web控件

2、创建控件的定制事件和事件参数

3、在网页上正确地使用Web控件

在讨论期间,我还会向读者提供一些小技巧,使读者能够更精确和快速地开发应用程序。

我们在这里创建的Web控件是一个定制的下拉选择框,它基于标准版本的SQL Server或MSDE的pubs数据库中的stores表。在开发中我们使用了Visual Studio .NET 2003开发工具和C#编程语言。

在创建Pubs Web项目后,第一个任务(至少对于我是如此)是将WebForm1.aspx文件改名为Default.aspx,并修改类,使之与名字相符。然后是在IDE环境中创建一个文件夹结构,方便对象的查找。

(图1)

我创建了Controls目录存储所有创建的控件,以更方便地访问它们。根据创建控件时的粒度,我们可以进一步地细分Controls目录。

我将把控件命名为StoreSelector.ascx。第一步是在表单上添加DropDownList控件。

(图2)

现在就该为该控件“布线”了。创建一个Dataset类的对象:

#codeprivate DataSet data;#end code

创建向下拉列表中填写数据的BindData功能:

#codeprivate void BindData(){

data = new DataSet();

SqlConnection cnn = new SqlConnection("Data Source=(local);Initial

Catalog=pubs;Integrated Security=SSPI");

SqlDataAdapter adapter = new SqlDataAdapter();

adapter.SelectCommand = new SqlCommand("SELECT stor_id, stor_name,stor_address, city, state, zip FROM stores", cnn);

adapter.Fill(data, "stores");

storeList.DataSource = data;

storeList.DataMember = "stores";

storeList.DataTextField = "stor_name";

storeList.DataBind();

Session.Add("Data", data);}#end code

我在Session变量上增加了DataSet对象,以使数据在对话存在期间以及控件事件触发期间传递数据时都是可以访问的。注意,要确保Page_OnLoad事件的正确:

#codeprivate void Page_Load(object sender, System.EventArgs e){

if(!Page.IsPostBack)

{

BindData();

}}#end code

现在我们将新控件拖到Default.aspx网页上,并运行该项目。

(图3)

(图4)

很简单是吧?下面就该是技巧比较高的部分了。我们希望在Default.aspx上添加几个标签,反映不断变化的商店。我们希望每个标签显示现在选择的商店中的一列,在这里我们就需要为StoreSelector控件和事件参数类创建一个定制事件。下面我们先创建Event Argument Class(StoreSelectorCommandEventArgs.cs):

#codepublic class StoreSelectorCommandEventArgs{

private string _stor_id;

private string _stor_name;

private string _stor_address;

private string _city;

private string _state;

private string _zip;

public StoreSelectorCommandEventArgs(string stor_id, string stor_name,

string stor_address, string city, string state, string zip)

{

_stor_id = stor_id;

_stor_name = stor_name;

_stor_address = stor_address;

_city = city;

_state = state;

_zip = zip;

}

public string stor_id{ get{ return _stor_id; } }

public string stor_name{ get{ return _stor_name; } }

public string stor_address{ get{ return _stor_address; } }

public string city{ get{ return _city; } }

public string state{ get{ return _state; } }

public string zip{ get{ return _zip; } }}#end code

该类的目的是为了处理定义事件参数的“e”变量,我们要做的仅仅是创建了其中的一个。下面是定义如何处理事件的代理类(StoreSelectorCommandEventHandler.cs):

#codepublic delegate void StoreSelectorCommandEventHandler(object sender,StoreSelectorCommandEventArgs e);#end code

下面是产生的文件:

(图5)

现在我们来调整StoreSelector控件,触发事件。

下面的代码需要添加到StoreSelector控件中,才可能执行我们创建的事件:

#codepublic event StoreSelectorCommandEventHandler StoreSelectorChanged;protected virtual void OnStoreSelectorChanged(StoreSelectorCommandEventArgs e){

if(StoreSelectorChanged != null) StoreSelectorChanged(this, e);}#end code

现在,我们已经为控件定义了事件,我们需要触发该事件。我们计划在DropDownList OnChange事件被触发后触发该事件。注意确保DropDownList控件的AutPostBack属性被设置为真。

(图6)

下面是事件的代码:

#codeprivate void storeList_SelectedIndexChanged(object sender, System.EventArgs e){

data = (DataSet)Session["Data"];

OnStoreSelectorChanged(

new StoreSelectorCommandEventArgs

(data.Tables["stores"].Rows[storeList.SelectedIndex].ItemArray[0].ToString

(),

data.Tables["stores"].Rows[storeList.SelectedIndex].ItemArray[1].ToString(

),

data.Tables["stores"].Rows[storeList.SelectedIndex].ItemArray[2].ToString(),

data.Tables["stores"].Rows[storeList.SelectedIndex].ItemArray[3].ToString(),

data.Tables["stores"].Rows[storeList.SelectedIndex].ItemArray[4].ToString(),

data.Tables["stores"].Rows[storeList.SelectedIndex].ItemArray[5].ToString(

)));}#end code

我们来分析一下在这里所作的工作。当SelectedIndexChanged事件被触发时,我将它传递给为控件创建的新事件,我传送的数据直接与填写的dataset相关,所有条目都一个一个地被传递给StoreSelectorCommandEventArgs对象,然后触发事件。

为了访问Default.aspx网页的新功能,我们需要在该类的OnInit部分添加事件处理程序:

(图7)

如上图所示,StoreSelectorChanged事件出现在了Default.aspx网页上。下面我们赋予它一个功能。我将在Default.aspx网页上添加6个标签,随DropDownList的变化显示值:

(图8)

现在我们来编写事件。

美观是Intellisense是Intellisense认可定制的EventArg类属性的原则:

(图9)

最终的事件函数如下所示:

#codeprivate void StoreSelector1_StoreSelectorChanged(objectsender, Pubs.Controls.StoreSelectorCommandEventArgs e){

Label1.Text = e.stor_id;

Label2.Text = e.stor_name;

Label3.Text = e.stor_address;

Label4.Text = e.city;

Label5.Text = e.state;

Label6.Text = e.zip;}#end code

现在我们对该项目进行测试。该网页一加载,读者的头脑中可能会闪现出这样的念头:它有问题,但我向你保证保证,该项目没有任何问题。如果想在网页一加载时就触发该事件,我们必须通过设置DropDownList控件中有选择的索引属性在已经创建的控件中进行设置。

(图10)

只要我们从DropDownList中选择另一个Store,标签就会发生变化:

(图11)

现在我们使表单加载到第一个记录。我们在StoreSelector控件上添加下面的属性:

#Codepublic int SelectedIndex{

get{ return storeList.SelectedIndex; }

set

{

if(!Page.IsPostBack)

{

BindData();

}

if(value < storeList.Items.Count)

{

storeList.SelectedIndex = value;

OnStoreSelectorChanged(

new StoreSelectorCommandEventArgs

(data.Tables["stores"].Rows[value].ItemArray[0].ToString(),

data.Tables["stores"].Rows[value].ItemArray[1].ToString(),

data.Tables["stores"].Rows[value].ItemArray[2].ToString(),

data.Tables["stores"].Rows[value].ItemArray[3].ToString(),

data.Tables["stores"].Rows[value].ItemArray[4].ToString(),

data.Tables["stores"].Rows[value].ItemArray[5].ToString()));

}

}}#End Code

然后设置Default.aspx中Page_Load事件的属性:

#codeprivate void Page_Load(object sender, System.EventArgs e){

// 用户初始化网页的代码

if(!Page.IsPostBack)

{

StoreSelector1.SelectedIndex = 0;

}}#end code

运行该项目时,它就会将表单加载到第一个记录。

小结

希望这篇文章能够对广大读者有一定的帮助。这种类型的Web应用程序的开发几乎没有什么限制,只要设计得当,我们创建的每个Web控件可以在整个Web应用程序中使用。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有