zoukankan      html  css  js  c++  java
  • ExtAspNet应用技巧(十八) 编辑菜单


    界面截图

    点击编辑在新窗口中弹出编辑页面:


    注意模拟树的下拉列表,当前节点和当前节点的所有子节点都是不可选择的:


    点击“保存并关闭”则会首先保存数据,然后关闭弹出窗口,之后回发父页面并更新Grid:


    如果我修改了表单(排序由20->21),此时点击Window右上角的关闭按钮,会弹出提示框(这是ExtAspNet内置支持的特性):



    ASPX标签定义

        <ext:PageManager ID="PageManager1" AutoSizePanelID="SimpleForm1" runat="server" />
        <ext:SimpleForm ID="SimpleForm1" ShowBorder="false" ShowHeader="false" runat="server"
            BodyPadding="5px" EnableBackgroundColor="true" Title="SimpleForm">
            <Toolbars>
                <ext:Toolbar ID="Toolbar1" runat="server">
                    <Items>
                        <ext:Button ID="btnClose" SystemIcon="Close" EnablePostBack="false" runat="server"
                            Text="关闭">
                        </ext:Button>
                        <ext:ToolbarSeparator ID="ToolbarSeparator1" runat="server">
                        </ext:ToolbarSeparator>
                        <ext:Button ID="btnSaveClose" ValidateForms="SimpleForm1" SystemIcon="SaveClose"
                            OnClick="btnSaveClose_Click" runat="server" Text="保存并关闭">
                        </ext:Button>
                    </Items>
                </ext:Toolbar>
            </Toolbars>
            <Items>
                <ext:TextBox ID="tbxName" runat="server" Label="名称" Required="true" ShowRedStar="true">
                </ext:TextBox>
                <ext:TextBox ID="tbxUrl" runat="server" Label="链接" Required="true" ShowRedStar="true">
                </ext:TextBox>
                <ext:CheckBox ID="cbxShow" runat="server" Label="显示">
                </ext:CheckBox>
                <ext:NumberBox ID="tbxSortIndex" Label="排序" Required="true" ShowRedStar="true" runat="server">
                </ext:NumberBox>
                <ext:DropDownList ID="ddlParentMenu" Label="父菜单" Required="true" ShowRedStar="true" runat="server">
                </ext:DropDownList>
            </Items>
        </ext:SimpleForm>
        


    这里面的大部分技巧在上一篇文章 《ExtAspNet应用技巧(十七) - 新增菜单》 中都已经有所介绍。


    页面初始化代码

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                LoadData();
            }
        }
        private void LoadData()
        {
            btnClose.OnClientClick = ExtAspNet.ActiveWindow.GetConfirmFormModifiedClosePostBackReference();
            int menuId = GetQueryIntValue("id");
            XMenu menu = XMenu.FetchByID(menuId);
            if (menu == null)
            {
                // 参数错误,首先弹出Alert对话框然后关闭弹出窗口
                ExtAspNet.Alert.Show("参数错误!", String.Empty, ExtAspNet.ActiveWindow.GetCloseReference());
                return;
            }
            tbxName.Text = menu.Name;
            tbxUrl.Text = menu.NavigateUrl;
            tbxSortIndex.Text = menu.SortIndex.ToString();
            cbxShow.Checked = menu.Show;
            // 绑定下拉列表
            BindDDL(menu);
        }
        


    在介绍这段代码之前,我们先回忆下父页面中的Grid的编辑链接是如何定义的:

        <ext:WindowField Text="编辑" WindowID="Window1" Title="编辑" DataIFrameUrlFields="Id"
            DataIFrameUrlFormatString="~/admin/menu_edit.aspx?id={0}" Width="50px" />
        


    也就是说,当打开此编辑菜单的页面时,URL应该类似如下形式:http://localhost/appbox/admin/menu_edit.aspx?id=6

    所以,我们首先通过定义在PageBase中的GetQueryIntValue方法,获取URL中id值:

        protected string GetQueryValue(string queryKey)
        {
            return Request.QueryString[queryKey];
        }
        protected int GetQueryIntValue(string queryKey)
        {
            int queryIntValue = -1;
            try
            {
                queryIntValue = Convert.ToInt32(Request.QueryString[queryKey]);
            }
            catch (Exception)
            {
                // TODO
            }
            return queryIntValue;
        }
        



    之后再来看下这段代码:

        XMenu menu = XMenu.FetchByID(menuId);
        if (menu == null)
        {
            // 参数错误,首先弹出Alert对话框然后关闭弹出窗口
            ExtAspNet.Alert.Show("参数错误!", String.Empty, ExtAspNet.ActiveWindow.GetCloseReference());
            return;
        }
        

    我们可以把这段代码直译为,如果对应的menuId不存在,则首先弹出Alert对话框,在用户点击对话框的确认按钮后,关闭当前弹出的窗口(ActiveWindow)。
    对应的页面的效果为(是不是很酷):







    绑定下拉列表代码


    这段代码将是本章中最出彩的一段,我们要完成的功能如下(可以在后面看到对应的代码实现):
    1. 从数据库查询所有的菜单,按照SortIndex由小到大排序,生成XMenuCollection(这是SubSonic生成的数据库表映射实体类)。
    2. 通过XMenuHelper.GetMyMenuCollection静态函数将此对象转换为List<MyMenu>(内部已经计算好TreeLevel和IsTreeLeaf)。
    3. 添加根节点(所有节点的TreeLevel加一)。
    4. 设置当前节点以及当前节点的所有子节点都不可选择(这是通过ExtAspNet支持的方法来做的)。
    5. 绑定模拟树的下拉列表。
    6. 选中下拉列表中当前节点的父节点

    来看下对应的代码实现:

        private void BindDDL(XMenu menu)
        {
            XMenuCollection menus = new Select().From<XMenu>()
                .OrderAsc(XMenu.SortIndexColumn.ColumnName)
                .ExecuteAsCollection<XMenuCollection>();
            List<MyMenu> newMenus = XMenuHelper.GetMyMenuCollection(menus);
            // 所有节点的TreeLevel加一,然后添加根节点
            foreach (MyMenu myMenu in newMenus)
            {
                myMenu.TreeLevel += 1;
            }
            MyMenu rootMenu = new MyMenu();
            rootMenu.Name = "==根节点==";
            rootMenu.Id = 0;
            rootMenu.TreeLevel = 0;
            newMenus.Insert(0, rootMenu);
            // 本节点不可点击(也就是说当前节点不可能是当前节点的父节点)
            // 并且本节点的所有子节点也不可点击,你想如果当前节点跑到子节点的子节点,那么这些子节点就从树上消失了
            bool startChileNode = false;
            int currentMenuTreeLevel = 0;
            foreach (MyMenu myMenu in newMenus)
            {
                if (myMenu.Id == menu.Id)
                {
                    currentMenuTreeLevel = myMenu.TreeLevel;
                    myMenu.Enabled = false;
                    startChileNode = true;
                }
                else
                {
                    if (startChileNode)
                    {
                        if (myMenu.TreeLevel > currentMenuTreeLevel)
                        {
                            myMenu.Enabled = false;
                        }
                        else
                        {
                            startChileNode = false;
                        }
                    }
                }
            }
            // 绑定到下拉列表(启用模拟树功能和不可选择项功能)
            ddlParentMenu.EnableSimulateTree = true;
            ddlParentMenu.DataTextField = "Name";
            ddlParentMenu.DataValueField = "Id";
            ddlParentMenu.DataSimulateTreeLevelField = "TreeLevel";
            ddlParentMenu.DataEnableSelectField = "Enabled";
            ddlParentMenu.DataSource = newMenus;
            ddlParentMenu.DataBind();
            // 选中当前节点的父节点
            ddlParentMenu.SelectedValue = menu.ParentMenuId.ToString();
        }
        



    页面事件处理代码

        protected void btnSaveClose_Click(object sender, EventArgs e)
        {
            int menuId = GetQueryIntValue("id");
            XMenu menu = XMenu.FetchByID(menuId);
            menu.Name = tbxName.Text.Trim();
            menu.NavigateUrl = tbxUrl.Text.Trim();
            menu.SortIndex = Convert.ToInt32(tbxSortIndex.Text.Trim());
            menu.Show = cbxShow.Checked;
            menu.ParentMenuId = Convert.ToInt32(ddlParentMenu.SelectedValue);
            menu.Save(User.Identity.Name);
    
            ExtAspNet.Alert.Show("保存成功!", String.Empty, ExtAspNet.ActiveWindow.GetClosePostBackReference());
        }
        




    下一章,我们将会介绍如何日志管理模块。


    下载全部源代码




  • 相关阅读:
    Two Sum II
    Subarray Sum
    Intersection of Two Arrays
    Reorder List
    Convert Sorted List to Binary Search Tree
    Remove Duplicates from Sorted List II
    Partition List
    Linked List Cycle II
    Sort List
    struts2结果跳转和参数获取
  • 原文地址:https://www.cnblogs.com/sanshi/p/1565894.html
Copyright © 2011-2022 走看看