如何通过回发来维护树视图用户交互?

时间:2012-10-02 10:29:18

标签: c# asp.net telerik postback radtreeview

我在母版页中使用RadTreeView

但我面临以下问题:

当我点击树视图的节点时,我失去了我的选择。每次我点击它使(Response.Redirect("..."))节点进入(!Page.IsPostback)的节点 每次都重新绑定树视图,这样我就会失去选择。

如何解决此问题。

我的.aspx:

 <telerik:RadTreeView ID="rtv_cm" runat="server" OnNodeExpand="rtv_cm_NodeExpand"
                OnNodeClick="rtv_cm_NodeClick" Skin="WebBlue">
 </telerik:RadTreeView>

我的.cs:

 protected void Page_Load(object sender, EventArgs e)
        {
            if (Session["emp_num"] != null && !string.IsNullOrEmpty(Session["emp_num"].ToString()))
            {

                if (!Page.IsPostBack)
                {

                    LoadRootNodes(rtv_cm, TreeNodeExpandMode.ServerSide);
                }
            }
            else
            {
                Response.Redirect("Frm_login.aspx");
            }
        }

protected void rtv_cm_NodeClick(object sender, RadTreeNodeEventArgs e)
        {
            dt_childs = (DataTable)Session["dt_childs"];
            IEnumerable<DataRow> result = from myRow in dt_childs.AsEnumerable()
                                          where myRow.Field<string>("task_id").TrimEnd() == e.Node.Value.TrimEnd()
                                          select myRow;
            if (result != null)
            {
                if (!string.IsNullOrEmpty(result.ElementAtOrDefault(0).Field<string>("page_name")))
                {
                    Response.Redirect(result.ElementAtOrDefault(0).Field<string>("page_name").TrimEnd(), false);
                }
            }
        }

我如何获得菜单:

  private void LoadRootNodes(RadTreeView treeView, TreeNodeExpandMode expandMode)
        {
            dt = Menu_db.GetMenu(Session["emp_num"].ToString(), CMSession.Current.db_code);
            IEnumerable<DataRow> result = from myRow in dt.AsEnumerable()
                                          where myRow.Field<string>("task_id").TrimEnd() == "0"
                                          select myRow;
            if (result != null && result.Count()>0)
            {
                DataTable dt_roots = result.CopyToDataTable<DataRow>();
                Session["dt"] = dt;
                Session["dt_roots"] = dt_roots;

                foreach (DataRow row in dt_roots.Rows)
                {
                    RadTreeNode node = new RadTreeNode();

                    node.Text = row["task_name"].ToString().TrimEnd();
                    node.Value = row["task_id"].ToString().TrimEnd();
                    if (Convert.ToInt32(row["count"]) > 0)
                    {
                        node.ExpandMode = expandMode;
                    }
                    treeView.Nodes.Add(node);
                }
            }
        }

4 个答案:

答案 0 :(得分:3)

HTTP就是所谓的“stateless protocol”。基本上,就好像服务器有严重的阿尔茨海默病病例(没有意图不尊重)。服务器回答您的查询,但随后忘记您曾经在那里。

当HTTP主要用于获取静态文档时,这没有问题,但Web应用程序需要某种状态。有很多方法可以实现,但ASP.NET通常会大量使用“ViewState”。视图状态只是一个<input type="hidden">标记,包含base-64格式的字节代码。 (如果您在浏览器中查看呈现的HTML页面的来源,则会看到它 - 名为“__VIEWSTATE”)。当用户重新提交表单(通过单击按钮等)时,视图状态数据将被发送回服务器。基本上,这就像提醒服务器上次告诉你的内容一样。这就是TextBoxes和GridViews能够在回发之间保持状态的方式 - 它们将状态存储在“viewstate”中。

然而,viewstate的问题在于它很容易丢失。您必须提交表单,否则视图状态将不会保留。如果您使用锚标记或Request.Redirect,则您可以单独使用表单并单独访问网页,并且在此过程中,您不会传递任何视图状态。

通常无法避免这种情况,因此还有其他方法可以存储应用程序的状态。但是,与viewstate不同,这是您必须手动为要保留的每个值进行的操作。您可以将数据存储在cookie中,可以将数据存储在服务器上(使用Server["key"]Session["key"]),也可以将数据保存在更具体的数据库中,如数据库或文本文件。但是,所有这一切都必须手动完成,然后在重新加载页面时必须重新加载数据。

在您的情况下,您可能想要猜测基于当前页面选择了哪个项目(因为树视图项目和页面似乎已链接)并明确设置所选项目。如果这不可行,您可以尝试使用Session等内容将所选项目存储在Session["Master_SelectedTreeViewItem"] = treeViewItem.Id;中。然后,在Page_Load中,获取此值(小心,可能是null),然后将相应的树视图项设置为选中。

我会发布更多代码示例,但是你没有提供加载treeview等的代码,所以很难做到。

更多信息

ASP.NET State Management Overview (MSDN)

答案 1 :(得分:2)

我能想到的唯一方法是将选择存储在会话和(!Page.IsPostBack)中,查找该会话密钥并在绑定后更新您的选择。

你面临的问题是因为基本上,通过你的重定向,你会转到另一个html页面,所以ViewState不在窗口,不要指出它是同一个地址。

答案 2 :(得分:2)

如果使用链接到其他页面的URL绑定树,请使用查询字符串附加选择,然后从另一页的查询字符串中加载树选择。

如果您认为要重定向到的第二个页面具有与第一个相同的UI,请不要重定向而是将其加载到具有选择的新内容的同一页面上,这将允许您在asp.net中维护状态如果控件支持视图状态。

答案 3 :(得分:1)

我已经遇到了这个问题,完全相同的问题,需要在TreeViewItemClick上重定向。

我解决了它存储最后选择的项目是会话,并在页面加载时再次选择它。

有些想法

protected void rtv_cm_NodeClick(object sender, RadTreeNodeEventArgs e)
{
    Session["LastClickedNode"] = e.Node.Value;
    ...
}

并在您的Load方法中,验证是否需要选择节点,如下所示。

 private void LoadRootNodes(RadTreeView treeView, TreeNodeExpandMode expandMode)
 {
     //... your code
     if (Session["LastClickedNode"] !=null)
     {
          if (row["task_id"].ToString().TrimEnd() == Session["LastClickedNode"].ToString())
          {
               node.Selected = true;
          } 
     }
 }

我认为这可以解决您的问题。