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