开发网站后台管理时,经常遇到页面返回的情况,如果采用history.go(-1)的方式返回上一页面,则有时在页面回发之后会停留在当前页面,需要点击多次;如果用ReturnUrl参数,则感觉使用场合不是很合适,而且需要在每个连接上面都指定ReturnUrl参数,虽然可以用Request.Url.PathAndQuery来获取当前页面的完整链接,但实现起来较为繁琐;我在参考了vs2005ASP.NET网站配置的代码之后,发现它是返回上一页的方式是使用Stack的方式来处理,即后进先出的方式;这样我整理了一下,发现通过这种方式来处理返回的应用很便捷。

    这里主要解决两个问题:一个是视图控制,即要显示那个视图(上一视图会自动隐藏)和返回上一视图;二是页面跳转控制,返回上一页面,无需传送参数,也不必指定url。

 

    解决这两个问题都使用到了Stack,对于视图控制,该Stack存储于ViewState中,对于页面控制,则存储与Session中;下面是编码部分:

  1. 页面跳转,首先在页面基类中设计属性:Urls和方法ShowPreviouseUrl();
  1. 代码
Stack Urls

        {

            get { return Session["Urls"] as Stack ?? new Stack(); }

            set { Session["Urls"] = value; }

        }
  1. 代码
protected void ShowPreviouseUrl()

        {

              if (Urls.Count > 1)

              {

                  Stack tempUrls = Urls;

                  tempUrls.Pop();

                  string url = tempUrls.Peek() as string;

                  Urls = tempUrls;

                  Response.Redirect(url);

              }

        }
  1. 在页面基类中的OnLoad事件加入:
if(!IsPostBack)

        {

            string url = Request.Url.PathAndQuery;

            if (Urls.Count == 0 || !url.Equals(Urls.Peek() as string))

            {

                Stack tempUrls = Urls;

                tempUrls.Push(url);

                Urls = tempUrls;

            }

        }
  1. 在具体的一个页面中放置一个返回链接,并加入事件即可:
protected void LinkButtonBack_Click(object sender, EventArgs e)

        {

            ShowPreviouseUrl();

        }
  1. 页面中视图控制,同样在页面基类中设计属性Views和方法ShowPreviouseView()、ShowView():
  1. 代码
Stack Views

        {

            get { return ViewState["Views"] as Stack ?? new Stack(); }

            set { ViewState["Views"] = value; }

        }
  1. 代码:
protected void ShowPreviousePanel()

        {

            Stack tempStatck = Views;



            if (tempStatck.Count == 0 || tempStatck.Count == 1)

            {

                if (Urls.Count > 1)

                {

                    Stack tempUrls = Urls;

                    tempUrls.Pop();

                    string url = tempUrls.Peek() as string;

                    Urls = tempUrls;

                    Response.Redirect(url);

                }

                return;

            }



            FindControl(Page, tempStatck.Pop() as string).Visible = false;

            FindControl(Page, tempStatck.Peek() as string).Visible = true;



            Panels = tempStatck;



        }
  1. 代码:
protected void ShowPanel(string viewId)

        {

            Stack tempStatck = Views;

            if (tempStatck.Count > 0)

            {

                FindControl(Page, tempStatck.Peek() as string).Visible = false;

            }



            Control targetView = FindControl(Page, viewId);

            if (targetView == null)

            {

                throw new LogicException("没有找到要显示的视图");

            }



            targetView .Visible = true;



            tempStatck.Push(viewId);



            Views= tempStatck;

        }
protected static Control FindControl(Control container, string ControlId)

        {

            if (container != null && container.Controls.Count > 0)

            {

                if (container.FindControl(ControlId) == null)

                {

                    foreach (Control item in container.Controls)

                    {

                        Control target = FindControl(item, ControlId);

                        if (target != null)

                        {

                            return target;

                        }

                    }

                }

                else

                {

                    return container.FindControl(ControlId);

                }

            }

            return null;



        }
  1. 当编写某个应用时并需要多个操作时,可以考虑把该应用编写为一个aspx页面,而多个操作则编写为对应视图的操作;(这里暂不考虑rest规则)加入存在两个Panel,则将其Visible属性为false:
<asp:Panel ID="PanelFileList" runat="server" Visible="false"></asp:Panel>



     <asp:Panel ID="PanelFielUpload" runat="server" Visible="false"></asp:Panel>
  1. 然后再On_Load事件中确定显示某个视图:
ShowPanel(PanelFileList.ID)
  1. 返回上一视图,在返回控件加入onclick事件,并添加调用方法:
ShowPreviousePanel();