知识大全 C#+ASP.NET 2.0 定制复合组件之高级篇

Posted

篇首语:你不勇敢,没人替你坚强。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 C#+ASP.NET 2.0 定制复合组件之高级篇相关的知识,希望对你有一定的参考价值。

C#+ASP.NET 2.0 定制复合组件之高级篇  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

  一 增加EnhancedListBox的客户端功能        为了使用客户端代码实现EnhancedListBox中项的重排序 你必须使用JavaScript脚本 并且要把它们依附到EnhancedListBox的两个按钮上 为此 我建议你使用 往后考虑 的方法 就象编写一个老式的ASP以前的Web页面 首先编写一些生成HTML文件的JavaScript 为此 最好的方法是运行该控件 然后观察其源码并把它的HTML代码复制到一个编辑器 再添加JavaScript 列表 (见下载源代码)展示了你需要添加到你的控件中的JavaScript的原始形式 然后 借助于StringBuilder/StringWriter技术(参考源码列表 ) 该控件构建这部分代码 该JavaScript代码由两部分功能组成 接收一个HTML控件(在本例中是一个<select>控件) 使用选择索引并且在列表中上下移动它(基本上与我在本文开始我使用服务器代码向你展示的一样) 现在 你要理解 你把该JavaScript代码添加到Web控件的何处 为了实现在一个Web表单上有多个EnhancedListBox控件的情况下 该JavaScript代码不会被重复复制 你需要使用Page ClientScript对象的ReGISterClientScriptBlock方法输出它        要使这个方法起作用 你必须在重载的OnInit事件中调用它(见源码中列表 )        最后 为使按钮正确工作 你需要把添加的客户端方法依附到其上 在列表 中的代码中 你会看到引用了一个方法RenderButtons 尽管我没有把该代码在此列出(请参考本文相应源码) 但是它能够使用我在以前文章中介绍的技术生成按钮 当时 在生成实际HTML标签的之前 标签属性是使用AddAttribute方法以栈式存放的 在此 你使用一样的技术把客户端方法依附到你的按钮      string s_MoveUp = MoveItemUp(document all +this ClientID + );   output AddAttribute(HtmlTextWriterAttribute OnClick s_MoveUp);        记住 MoveItemUp是你已经编写成功的JavaScript函数之一 在生成用于排序的按钮之前 该代码将以堆栈存放这些JavaScript命令 对于向下(down)按钮 你使用一样的技术 注意 我使用ClientId代表该生成后的控件的ID 但是 在这个控件位于一个复合控件内部时 这个属性要考虑使用父控件的名字        现在 你可以成功地把该控件应用于一个Web表单中 你可以使用与你操作一个标准ListBox控件一样的方式在其上添加一些项        事实上 这完全是一个投放位置占位符(或ASP NET ListBox控件) 当你使用重排序按钮时 你将看到列表中的项相应地改变顺序 现在让我们先记下这个问题 如果你把一个按钮拖动到一个Web表单上(不需要为之添加代码)并执行一个回寄 你猜会发生什么呢?完全与我以前描述的一样 任何你使用重排序按钮作的重排序改变都将恢复到在最近一次回寄之前该控件看上去的状态 因此 让我们修改一下这个问题        首先 我再添加一些JavaScript(源码列表 ) 注意 这部分代码被添加到重载的OnInit方法中并且使用StringBuilder/StringWriter技术进行构建 而且 这个JavaScript方法的名字是BuildItemList 这个函数负责构建列表框完整内容的一个字符串描述并且把该串放到要传递到该函数的一个HTML元素的value属性中 你可以把这看作是列表内容的一种串行化 该串行化的输出风格会根据你自己的设计的不同而有所不同 调用这个JavaScript函数需要依附到该按钮上的其它代码      string s_MoveUp = MoveItemUp(document all + this ClientID + ); ;   string s_BuildItemList = BuildItemList(document all + this ClientID +    document all __ + this ClientID + ); ;   output AddAttribute(HtmlTextWriterAttribute Onclick MoveUp + + BuildItemList);        现在 让我们来分析一下你发送到BuildItemList函数的两个参数 第一个参数相应于生成的控件(<select>标签)的ID 第二个参数是另外一个ID 与前一个命名一致 但是前面有一个 __ 这是一个你仍然需要添加到你的Web控件的隐藏的文本框 它将作为一个 串行化 项列表的占位符 我要在OnPreRender事件中注册这个隐藏的文本域      protected override void OnPreRender(EventArgs e)        base OnPreRender(e);    if(Page != null)         Page ClientScript RegisterHiddenField( __ + this ID );               注意 我已经使用我们的控件的ID来标识隐藏的文本域        到目前为止 你已经拥有了一个完整功能的Web控件 其中 客户端JavaScript被绑定到其中的两个按钮上 该JavaScript成功地实现在ListBox中的项的重排序并且把其内容串行化为一个字符串 然后 该字符串被存储在一个隐藏的文本域中 所有这些都发生在客户端 如果一个回寄发生 不会发生重排序 因为当重排序时控件的Item服务器属性还没有收到你对它作的任何改变的消息 但是幸运的是 位于隐藏的文本域中的表单的一个串行化快照中发生了这一变化 现在 你有了可以与Item属性一起使用的内容了 那么 接下来 你该如何实现呢?

  二 同步        为了在第一次回寄和所有随后的回寄中实现同步 在IPostBackDataHandler接口的实现中提供了一个LoadPostData方法 在每一次回寄时都要调用这个LoadPostData方法 因此 你需要在此做一些工作        值得一提的是 ASP NET 修整了一个在 版本中被忽视的小地方 然而这一修改能够使你的工作容易许多 ASP NET ListBox控件已经在两个版本( 和 )中实现了IPostBackDataHandler接口 但是在 版本中 微软使这个接口的方法定义虚拟化(virtual 在VB中称作Overridable) 这意味着 你不必在EnhancedListBox控件中重新实现这个接口 而是 你仅需重载LoadPostData方法        更重要的是 这也意味着 你可以存取基类实现而不必创建所有已经存在于你的扩展控件中的功能 什么功能呢?这包括微软加于其中的一切 用于处理Item集合 SelectedIndex SelectedValue和SelectedItem属性 及其它许多执行ListBox控件功能的代码 在ASP NET 中 你必须在你的派生控件中实现这个接口并且要提供你自己对这两个方法的定义代码 不仅包括你自己的加入的代码而且还要重复微软已经在其控制中所实现的一切        我猜测 微软有人已经发现了他们的实现中的错误 并且把方法变为virtual的 这样开发者能够存取基类的代码 因此 在源码列表 中向你展示如何实现重载的LoadPostData方法 在这个重载中 你将首先调用基类实现代码 然后 加上你需要的代码以与Item集合同步        另外 你还可以利用ListBox控件—通过把它编写成一个复合控件 此时 你需要把ListBox中的每一个属性映射到你的EnhancedListBox以便使它成为ListBox控件的一个投放位置点位符 无论使用哪一种方法 或者通过LoadPostData方法的重新创建 你都仍然需要写很多代码 如果我专门为ASP NET 编写这个控件 那么我很可能采取最直接的方案 复合控件方案        LoadPostData方法使你能够存取寄送到服务器的每一个域 包括你的隐藏文本域(存储在要传递到这个方法的postCollection参数中) 你可以问 为什么需要该隐藏文本域 而不是使用这个参数来存取被回寄的<select>元素呢?现在 我作一下解释 首先 回顾一下典型的ASP时代 当时你使用Request Form属性来存取页面域 在回寄时 你能够存取一个<select>元素的唯一的部分是选择的项 在该方案中 你需要完整的列表内容(因此 包括隐藏的文本域) 列表 向你展示如何分析该隐藏的文本域的内容并且把Item重新添加到Item集合中 注意 你是怎样调用基类实现的        最后 在你第一次生成控件时 你必须构建这个隐藏的文本域 以防在任何重排序前发生页面回寄 Render方法的最后一行是      output Write( <script language= JavaScript >BuildItemList(document all + this ClientID + document all __ + this ClientID + );</script> );        你可以在列表 的最后看到这一点        现在 你可以使用EnhancedListBox控件来重排序一些项 回寄 并且确保在重新生成页面前 控件的服务器存储与在客户端被改变的客户端存储完全同步 因此 现在让我们使用相同的技术来构建一个复合控件ListMover

  三 构建复合控件—ListMover        这个ListMover控件包含两个EnhancedListBox控件 还有一些按钮用于在两个列表之间来回移动项 借助于这些复合控件构建技术 你可以学习如何创建子控⑶沂褂靡恍〩TML生成它们 最终的控件看上去如图 所示 对于这个控件 你要注意的是某些事情必须发生的位置         图 这个ListMover控件提供了一种标准方式让用户在两个列表间移动项        首先 借助于与在以前的控件中相同的技术 你必须把在这个控件中需要的JavaScript代码添加到OnInit事件的重载版本中 列表 显示了你需要的JavaScript代码 如你在上一个控件中所做的一样 你也是使用JavaScript存取一个ListBox(<select>元素)中的元素 而且 我已经编制了函数分别实现把项添加到一个列表 从一个列表中删除项 以及从一个列表中添加或删除所有项        我已经进行了功能的分离 而不是创建单个 move 方法 这样以来 我可以实现基于属性设置而使得从一个列表中删除项成为可选的 毫无疑问 这可以使最终的控件更为强壮些 但是我在本文中不再分析这些代码 还应该注意 就象在前面控件中一样 我也添加了一个BuildItemList方法        现在 你需要把这一客户端代码依附到复合控件的按钮中 你可以在CreateChildControls方法的最后完成这一点 并且 在此时 完成子控件的初始化和构建控件集合 在此 我仅向你展示相应于一个按钮的代码(另外的按钮代码与此类似 省略)      string s_AddToLeft = AddSelectedItemToList(document all +   this lstItemsOnRight ClientID + document all   + this lstItemsOnLeft ClientID + +   (this AllowDuplicatesOnLeft ? true : false ) + ); ;   string s_RemoveFromRight = RemoveSelectedItemFromList(document all +   this lstItemsOnRight ClientID + ); ;   string s_BuildItemList = BuildItemList(document all +   this lstItemsOnRight ClientID + document all __ + lstItemsOnRight ClientID + ); + BuildItemList(document all + this lstItemsOnLeft ClientID + document all __   + lstItemsOnLeft ClientID + ); ;   this btnAdd Attributes Add( onclick s_AddToLeft   + + s_RemoveFromRight + + s_BuildItemList   + return false );        注意 我实现了在以前的控件中同样的工作 我把JavaScript函数调用构建成一字符串并且把它们依附到一个按钮上 主要区别在于 既然这是一个包含其它控件的复合控件 那么你可能使用把代码添加到onclick事件的Attributes Add方法 这与在一个生成控件中把它放到一个栈上的方法形成对照 还要注意 我把多个功能放到onclick属性中 而且 函数调用的最后返回false以便取消按钮将执行的任何回寄        最后 代码将在一个对Render重载的方法中初始化对客户端函数BuildItemList的调用 这看起来很象我在EnhancedListBox控件中向你介绍的那个 在此不再重复 注意 在这个控件中 我注册了两个隐藏的文本域 每一个相应于一个ListBox      protected override void OnPreRender(EventArgs e)       base OnPreRender(e);    if(Page != null)         Page ClientScript ReGISterHiddenField( __ + this lstItemsOnRight ClientID    );     Page ClientScript RegisterHiddenField( __ + this lstItemsOnLeft ClientID    );     Page RegisterRequiresPostBack(this);               现在 你已经构建成功该复合控件 能够提供一些客户端JavaScript 并且把它绑定到按钮上 与以前一样 你可以把它放到一个表单上并且使用它 但是 在你添加同步代码之前 它仍将会遇到你在第一个控件中所遇到的问题—你可以前后移动项 但是一旦你初始化一个回寄(通过表单上的任何其它控件) 该控件就会恢复到它回寄之前的状态        为了修改这个问题 你要实现你在第一个控件中所做的同样的工作 然而 既然你在开发一个复合控件 而不是扩展一个已经现有的控件 那么你需要实现IPostBackDataHandler接口并且提供LoadPostData和RaisePostDataChangedEvent方法的实现代码 这些实现(见列表 )与前面的控件基本一致 除了你要实现两个EnhancedListBox控件中的项集合的同步而不是只考虑一个控件外 并且与以前一样 你需要确保你保存你的SelectedIndex位置 这样以来 在你完成项集合的同步后你就可以把它们设置回去 还要注意 在第一个控件中 你重载了基控件的LoadPostData方法 因此在某处调用了它的基类 现在 既然你要从头编写一个复合控件 那么就没有基类可调用 而仅需提供你自己的方法实现        这个控件的最后版本包含若干新的属性 包括用来决定是否添加到一个列表中的项能够被从另一个列表中删除的属性(如果一个列表将允许出现重复项的话) 它还包含可扩展的风格化以实现最大化重用的目的 等等        就这些 你已经使用了可用于客户端脚本中的隐藏的文本域来存储列表框的状态 在回寄期间 你使用隐藏文本域的内容来与服务器端项集合重新同步 最终结果是一个漂亮的复合控件—允许你在没有服务器回寄的情况下实现各列表项间的来回移动 而当一个回寄真正发生时仍能够保持这种变化  

cha138/Article/program/ASP/201311/21733

相关参考

知识大全 ASP.NET 2.0高级控件之FileUpload控件

ASP.NET2.0高级控件之FileUpload控件  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧

知识大全 ASP.NET 2.0高级数据处理之使用参数

ASP.NET2.0高级数据处理之使用参数  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!你可以处理

知识大全 ASP.NET 2.0高级数据处理之冲突检测

ASP.NET2.0高级数据处理之冲突检测  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!前面我们提

知识大全 ASP.NET 2.0高级数据处理之数据绑定

ASP.NET2.0高级数据处理之数据绑定  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!在前面的模

知识大全 ASP.NET 2.0高级数据处理之处理控件事件

ASP.NET2.0高级数据处理之处理控件事件  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!在前面

知识大全 ASP.NET 2.0高级数据处理之主从数据表

ASP.NET2.0高级数据处理之主从数据表  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!在前面的

知识大全 ASP.NET组件设计之传输机制浅析

ASP.NET组件设计之传输机制浅析  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  ASPNET

知识大全 ASP.NET 2.0移动开发之列表控件

ASP.NET2.0移动开发之列表控件  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!概述  在很多

知识大全 ASP.NET 2.0服务器控件之验证控件示例

ASP.NET2.0服务器控件之验证控件示例  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  在上

知识大全 ASP.NET 2.0移动开发之属性重写和模板化

ASP.NET2.0移动开发之属性重写和模板化  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  本