作者: 彭斌 ,广州.NET俱乐部 2006-3-9
在去年的CS1.x专题中,我用了大部分的时间去讨论CS底层的结构与运行机制.在接下来的CS2.0系列文章中我将专著细节.来分析CS2.0的一些部件的实现.
CS1.0与2.0有些变化,但是运行机制变化不大,变化的只是细节与增加的功能.
细节的第一篇,我们从一个按钮开始说起:
上面的“邮件提醒”按钮是在CS2.0论坛模块里的一个具体帖子左上角出现的。该按钮不是一般的按钮,有图片并且还有文字(这个文字不是图片中的一部分那么简单,文字会根据xml的资源文件的不同而替换不同的语言),另外点击按钮还会通过Ajax回调一个服务器端方法,实现无刷新操作。
首先要明白的是,该按钮不是继承自Button,而是一个自定义控件。在CommunityServer.Controls项目,找到Utility文件夹下的ThreadSubscribeLinkButton.cs类。这就是该按钮的实现了。
public class ThreadSubscribeLinkButton : HtmlAnchor, ITrackedThread
该Button是继承了HtmlAnchor(就是HTML 的<a>)与 ITrackedThread。
ITrackedThread接口定义很简单:
public interface ITrackedThread
{
bool IsTracked { get;set;}
int ThreadID { get;set;}
bool Visible { get;set;}
}
三个属性,分别是“是否已经跟踪”、“被跟踪的线索ID”、“是否可见” ,这里说明一下thread这个单词在CS 中的解释:首先,一个论坛下的一个Post(我们一般叫帖子),发表后就会有一个thread,这个线索包括了Post本身,还包括针对该Post的回复等等。Post和其回复就形成了一个thread。
我们回到ThreadSubscribeLinkButton.cs类看一些重要的属性:
public virtual bool UseImages
public virtual string TrackingResourceName
public virtual string NotTrackingResourceName
public virtual string WorkingResourceName
由于CS是提供多种语言支持,所有想要替换按钮上的文字就需要这些属性了。同时,如果要显示在不同的操作状态,如:在处理的时候显示一个漏沙图标 ,还有在处理完成后要显示一个完成的图标 。这些都需要上述属性的支持。另外,我们可以看出这些属性是可以重写的。
接下来在类中还有几个重要的方法:
protected override void OnLoad(EventArgs e)
这是最早激发的一个事件实现,在CreateChildControls之前。在这里我们可以看到为该类为页面注册了一个Ajax方法:
AjaxManager.Register(this,this.GetType().Name,true,AjaxDebug.None);
(关于Ajax类这次细节分析暂时忽略)
protected override void CreateChildControls()
在OnLoad之后就建立控件内容,内容主要包括一些js脚本的,并且根据IsTracked的值判断按钮应该显示的文字和图片。
protected override void OnPreRender(EventArgs e)
在建立控件内容后,就触发预呈现的OnPreRender事件。在该方法下,主要根据UseImages的值判断调用下面两个方法中的哪一个。
private void BuildCallbackScript()
private void BuildCallbackScriptWithImages()
这两个私有方法,构造Ajax回调的脚步。
[AjaxMethod(IncludeControlValuesWithCallBack=false)]
public bool ToggleEmailReplies(int threadID)
这是Ajax回调的方法,也就是说当点击按钮后,会通过js 通过xmlhttp调用该方法。
ThreadTracking.ReverseThreadTrackingOptions(threadID, context.User.UserID);
通过上面的调用,最终把值保存到数据库。ToggleEmailReplies方法最后返回一个bool变量,客户端的js脚本就会根据这个bool值变化按钮的文字与图片。