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

asp.net|控件|设计

在试图为客户开发一个在网络上运行的应用程序时,我发现有关正确使用.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环境中创建一个文件夹结构,方便对象的查找。

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

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

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

#code
private DataSet data;
#end code
  创建向下拉列表中填写数据的BindData功能:

#code
private 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事件的正确:

#code
private void Page_Load(object sender, System.EventArgs e)
{
 if(!Page.IsPostBack)
 {
  BindData();
 }
}
#end code
  现在我们将新控件拖到Default.aspx网页上,并运行该项目。

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

#code
public 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):

#code
public delegate void StoreSelectorCommandEventHandler(object sender,
StoreSelectorCommandEventArgs e);
#end code
  下面是产生的文件:

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

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

#code
public event StoreSelectorCommandEventHandler StoreSelectorChanged;
protected virtual void OnStoreSelectorChanged(StoreSelectorCommandEventArgs e)
{
 if(StoreSelectorChanged != null) StoreSelectorChanged(this, e);
}
#end code
  现在,我们已经为控件定义了事件,我们需要触发该事件。我们计划在DropDownList OnChange事件被触发后触发该事件。注意确保DropDownList控件的AutPostBack属性被设置为真。

  下面是事件的代码:

#code
private 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部分添加事件处理程序:

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

  现在我们来编写事件。

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

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

#code
private void StoreSelector1_StoreSelectorChanged(object
sender, 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控件中有选择的索引属性在已经创建的控件中进行设置。

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

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

#Code
public 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事件的属性:

#code
private void Page_Load(object sender, System.EventArgs e)
{
 // 用户初始化网页的代码
 if(!Page.IsPostBack)
 {
  StoreSelector1.SelectedIndex = 0;
 }
}
#end code
  运行该项目时,它就会将表单加载到第一个记录。

  小结

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

时间: 2024-11-05 20:46:41

ASP.NET中设计带事件定制控件的相关文章

在asp.net中为Web用户控件添加属性和事件

asp.net|web|控件 在asp.net中为Web用户控件添加属性和事件 在90年代初,Microsoft为Web程序员提供的 Active Server Pages(ASP)革命性地改变了Web的编程.它可以利用十分易用的模型在Web服务器上动态生成HTML,并且很容易的实现了对数据库的访问,就当时来说,这是一项多么吸引人的技术,包括现在Internet上的许多web站点都是用Asp写的,我的同事前辈们更是玩Asp的高手,经历这么多年而不衰,可见他的成功. 但是,技术是在不断的发展着,引

ASP.NET 2.0 和数据绑定控件:新的角度,新的做法

asp.net|控件|数据 适用于:Microsoft ASP.NET 1.xMicrosoft ASP.NET 2.0 摘要:了解 ASP.NET 2.0 中的用于生成自定义数据绑定控件的工具是如何演变的.   本页内容 为什么需要新的数据源模型  ASP.NET 2.0 中的数据绑定控件  分析要点  数据绑定机制   列表控件  HeadlineList 示例控件  管理自定义集合  关于复合控件的一点讨论  小结 为什么需要新的数据源模型数据绑定是开发人员在 ASP.NET 1.x 中发

ASP.NET2.0中的AccessDataSource控件

access|asp.net|控件 ASP.NET 2.0包含了AccessDataSource控件,用来从Access数据库中将数据提取至ASP.NET 2.0(.aspx)页面.这个控件拥有的属性很简单.AccessDataSource的最重要的属性是DataFile属性,用来指向硬盘上MDB文件的路径.AccessDataSource拥有的其他属性还有SelectCommand,用来设定一个显示需要返回的结果集(表和列)的语句.SelectCommand必须使用SQL语法来定义. 在VWD

ASP.NET上传大文件控件

asp.net|控件|上传 这段时间写了个asp.net 上传大文件控件.经过测试,在ie中可显示进度条.特此共享,望广大网友多提意见. 大文件上传控件(包含进度条) 使用说明如下:      <summary>     上传进度条控件     </summary>     <example>     Web.config 配置     <?xml version="1.0"?>    <configuration>     

探讨ASP.NET 2.0的Web控件改进之概述

asp.net|web|控件 一. 引言 到目前为止,你可能已经了解了大量的ASP.NET 2.0新特征-母版页面,主题,提供者,等等--所有这样内容都相当精彩:但是,你是否了解到有关定制Web控件开发方面的重大变化?这正是我在本文中所想讨论的.如果你已经从事于控件开发,那么,我想本文所描述的ASP.NET 2.0中的新的改进特征会立即应用于你的控件开发中. 首先应该注意的是,你以前使用ASP.NET 1.1(或1.0)开发的所有Web控件在2.0版本下将继续良好运行-微软并没有破坏你的现有代码

ASP.net下的前台日历控件源代码

asp.net|控件|日历|源代码 #region 声明//----------------------------------------------------------------------//// 作者: 李淼(Nick.Lee)//// ASP.net下的前台日历控件源代码(不刷新页面) // 时间:2005-3-15 // boyorgril@msn.com// QQ:16503096//注意:引用请标明出处,谢谢//-------------------------------

ASP.net下的前台日历控件源代码(不刷新页面)

asp.net|控件|日历|刷新|页面|源代码 #region 声明//----------------------------------------------------------------------//// 作者: 李淼(Nick.Lee)//// ASP.net下的前台日历控件源代码(不刷新页面) // 时间:2005-3-15 // boyorgril@msn.com// QQ:16503096//注意:引用请标明出处,谢谢//-------------------------

ASP.NET 2.0的AccessDataSource控件

ASP.NET 2.0包含了AccessDataSource控件,用来从Access数据库中将数据提 取至ASP.NET 2.0(.aspx)页面.这个控件拥有的属性很简单.AccessDataSource 的最重要的属性是DataFile属性,用来指向硬盘上MDB文件的路径. AccessDataSource拥有的其他属性还有SelectCommand,用来设定一个显示需要 返回的结果集(表和列)的语句.SelectCommand必须使用SQL语法来定义. 在VWD中,可以用两种方式来添加Ac

iOS中UITableViewController自带的刷新控件

iOS中UITableViewController自带的刷新控件 一.引言         在iOS开发中,使用tableView的界面,大多会用到一个下拉刷新的的控件,第三方库中,我们一般会选择比较好用的MJRefresh,其实,在iOS6之后,系统为我们提供了一个原生的刷新控件,使用起来非常方便,只是制定性不强,如果我们没有复杂的需求,使用UIRefreshControl也是不错的一个选择. 二.UITableViewController         相对于UIViewControlle