2

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

4 回答 4

3

HTTP 是所谓的“无状态协议”。基本上,就好像服务器患有严重的阿尔茨海默病(无意不尊重)。服务器回答了您的查询,但随后忘记了您曾经在那里。

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

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

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

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

我会发布更多代码示例,但您没有提供加载树视图等的代码,因此很难做到。

更多信息

ASP.NET 状态管理概述 (MSDN)

于 2012-10-04T19:49:42.597 回答
2

如果您将树与链接到其他页面的 url 绑定,请使用查询字符串附加选择,然后从其他页面的查询字符串加载树选择。

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

于 2012-10-06T17:00:44.797 回答
2

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

您面临的问题是因为本质上,通过您的重定向,您转到了不同的 html 页面,因此 ViewState 不在窗口中,更不用说它是同一个地址。

于 2012-10-02T10:44:02.583 回答
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;
          } 
     }
 }

我认为这将解决您的问题。

于 2012-10-11T13:06:36.553 回答