博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

可以这样做来达到Web页面继承的效果

Posted on 2005-06-07 21:42  Arbean.Wu  阅读(2453)  评论(4编辑  收藏  举报

    在实际的项目中,存在这么一个问题:所有页面都从自定义的页面基类(MyPageBase)中继承过来。一些公共的方法可以在基类中实现。其中有一个是防止并发问题的,任何页面在绑定数据之前,都去检查是否有其它用户以可写的方式打开了此文档(写独占),如果被他人独占,则以只读方式打开。同时在页面中显示如“只读”标识,这样既很好地避免了并发的问题,同时又很清楚的告诉当前用户“你现在只能浏览本文档,因为他人正在修改此文档……”(如图1)。现在问题来了:我不可能要求其它程序员都在自己做的页面的某个位置手工放置“只读”标识吧?!这样做重复劳动不说,风格也很难统一。怎么办呢?
 

1.JPG
图1


       如果在WinForm中,基类Form可以拖个Label控件,label1.Text = “只读”(或者是一副图片),则其所有派生类都会有这个Label控件。但WebForm中就不行,因为在Web中页面(指WebForm1.aspx)之间不能像WinForm一样实现继承,但页面的代码类(WebForm1.aspx.cs)可以继承。分析Web程序的原理:服务器接受客户端的请求后,经过处理生成一个Html的文本发送给客户端,如果我们可以在服务器发送Html的文本到客户端之前对Html的文本进行修改,然后再发送给客户端,那问题就能得到解决。幸运的是:页面类Page中有一个Render(HtmlTextWriter writer)方法可以承载。

做法:我在页面基类(MyPageBase)承载Render(HtmlTextWriter writer)方法,然后在得到的Html的文本中的<body>标识与<form>之间插入一段标识文本,用来标识文档是否“只读”。这样,所有从此页面基类中派生过来的页面,都在最顶端标出文档是否“只读”。当然是否显示“只读”标识必须看是否只读打开此文档的,如果不是只读打开(没有他人独占文档),则没必要显示“只读”标识,如图2。

2.JPG
图2


代码如下:

 1/// <summary>
 2    /// 本项目中所有页面的基类
 3    /// </summary>

 4    public class MyPageBase : System.Web.UI.Page
 5    {
 6        
 7        private bool _isReadOnly = true;
 8
 9        protected override void Page_Load(object sender, EventArgs e)
10        {
11            base.Page_Load(sender, e);
12
13
14            if (!IsPostBack)
15            {
16                try
17                {
18                    this.MainDataSet = this.ManagerProvider.Open(DocID, false);    //DocID为文档的ID
19                    this.ViewState.Add("IsReadOnly",false);
20                }

21                catch(LockException lockEx)        //LockException为自定义的锁定异常类
22                {
23                    this.MainDataSet = this.ManagerProvider.Open(DocID, true);
24                    this.ViewState.Add("IsReadOnly",true);
25
26                    SetPageReadOnly();        //设置页面为只读的
27                }

28
30                
31            }

32
33        }

34
35
36        /// <summary>
37        /// 根据本页面/文档是是否是“只读”,选择是否加载“只读”图片
38        /// </summary>

39        protected override void Render(HtmlTextWriter writer)
40        {
41            bool isReadOnly = (bool)this.ViewState["IsReadOnly"];
42            if(isReadOnly )
43            {
44                StringWriter wt = new StringWriter();
45                HtmlTextWriter buffer = new
 HtmlTextWriter(wt);
46                base
.Render(buffer);
47

48                string pMarkup =
 wt.ToString();
49                int indexEndBody = 0
;
50                string readonlyFlag = @"
<table width=100%  border=0 cellspacing=0 cellpadding=0>
51
                                        <tr>
52
                                            <td><img src=../../include/images/ReadOnly.JPG width=404 height=58 align=left></td>
53
                                        </tr>
54                                        </table>"
;
55

56                indexEndBody = pMarkup.IndexOf(">",pMarkup.IndexOf("<body"
));
57                pMarkup = pMarkup.Insert(indexEndBody + 1
, readonlyFlag);
58

59
                writer.Write(pMarkup);
60            }

61            else
62                base.Render(writer);
63        }

64        
65        
66        /// <summary>
67        /// 设置页面为只读的,派生类可以重载此方法,加入对页面中各控件的Enable属性的设置。
68        /// </summary>

69        protected virtual void SetPageReadOnly()
70        {
71        }

72


                                                                       Arbean Wu 于广州
                                                                        2005-6-7