ExtAspNet应用技巧(五) - 动态创建工具栏菜单


文章截图 - 更好的排版


问题描述
shguo 网友在一封邮件中提到,希望能够动态创建工具栏菜单。

我理解的大致步骤如下:
1. 提供一个 menu.xml 文件:
    <?xml version="1.0" encoding="utf-8" ?>
    <menu>
      <menuItem text="首页" navigateurl="default.aspx" />
      <menuItem text="新闻" >
        <menuItem text="国内新闻" navigateurl="News.aspx?type=guonei" />
        <menuItem text="国际新闻" navigateurl="News.aspx?type=guoji" >
          <menuItem text="亚洲新闻" navigateurl="News.aspx?type=yazhou" />
          <menuItem text="欧洲新闻"  navigateurl="News.aspx?type=ouzhou" />
        </menuItem>
      </menuItem>
    </menu>
    

2. 页面上放置一个Panel和一个Toolbar控件:
    <ext:PageManager ID="PageManager1" runat="server" />
    <ext:Panel ShowBorder="false" ShowHeader="false" runat="server">
        <ext:Toolbar runat="server">
        </ext:Toolbar>
    </ext:Panel>
    

3. 生成这样的页面: 


以页面声明的方式实现
这种方式比较简单,需要注意的有一点:一个工具栏项 - 首页 - 希望点击能够转到一个链接地址。
但是如果使用 ext:HyperLink 控件的话,页面显示效果不好。所以我们还是使用 ext:Button,但是通过这样的方式来达到链接的目的:
    EnablePostBack="false" OnClientClick="window.open('default.aspx', '_blank');"
    
全部源代码:
    <ext:Panel ShowBorder="false" ShowHeader="false" runat="server">
        <ext:Toolbar runat="server">
            <ext:Button EnablePostBack="false" OnClientClick="window.open('default.aspx', '_blank');"
                Text="首页" runat="server">
            </ext:Button>
            <ext:Button EnablePostBack="false" Text="新闻" runat="server">
                <Menu>
                    <ext:MenuHyperLink runat="server" Target="_blank" NavigateUrl="news.aspx?guonei"
                        Text="国内新闻">
                    </ext:MenuHyperLink>
                    <ext:MenuHyperLink runat="server" Target="_blank" NavigateUrl="news.aspx?guoji" Text="国际新闻">
                        <Menu>
                            <ext:MenuHyperLink runat="server" Target="_blank" NavigateUrl="news.aspx?yazhou"
                                Text="亚洲新闻">
                            </ext:MenuHyperLink>
                            <ext:MenuHyperLink runat="server" Target="_blank" NavigateUrl="news.aspx?ouzhou"
                                Text="欧洲新闻">
                            </ext:MenuHyperLink>
                        </Menu>
                    </ext:MenuHyperLink>
                </Menu>
            </ext:Button>
        </ext:Toolbar>
    </ext:Panel>
    


以编程的方式实现
1. 首先加载XML配置文件到XmlDocument:
    private XmlDocument LoadXml()
    {
        // 加载XML配置文件
        string xmlPath = Server.MapPath("~/other/menu.xml");
        string xmlContent = String.Empty;
        using (StreamReader sr = new StreamReader(xmlPath))
        {
            xmlContent = sr.ReadToEnd();
        }
        XmlDocument doc = new XmlDocument();
        doc.LoadXml(xmlContent);
        return doc;
    }
    

2. 生成Toolbar的工具栏按钮
    XmlDocument doc = LoadXml();
    // 根节点的子节点们
    XmlNodeList nodes = doc.DocumentElement.ChildNodes;
    foreach (XmlNode node in nodes)
    {
        ExtAspNet.Button btn = new Button();
        btn.Text = node.Attributes["text"].Value;
        btn.EnablePostBack = false;
        Toolbar1.Items.Add(btn);
        // 如果此节点没有子节点
        if (node.ChildNodes.Count == 0)
        {
            XmlAttribute attrURL = node.Attributes["navigateurl"];
            if (attrURL != null)
            {
                btn.OnClientClick = String.Format("window.open('{0}','_blank')", attrURL.Value);
            }
        }
        else
        {
            // 递归添加所有的菜单
            ResolveMenu(btn, node.ChildNodes);
        } 
    }
    

3. 最后是递归添加所有的菜单
    private void ResolveMenu(IMenu btn, XmlNodeList nodes)
    {
        foreach (XmlNode node in nodes)
        {
            XmlAttribute attrURL = node.Attributes["navigateurl"];
            if (attrURL != null)
            {
                ExtAspNet.MenuHyperLink lnk = new ExtAspNet.MenuHyperLink();
                lnk.Text = node.Attributes["text"].Value;
                lnk.NavigateUrl = attrURL.Value;
                lnk.Target = "_blank";
                btn.Menu.Items.Add(lnk);
                if (node.ChildNodes.Count > 0)
                {
                    ResolveMenu(lnk, node.ChildNodes);
                }
            }
        }
    }
    

注意:ResolveMenu的第一个参数是一个接口 IMenu,可以接受所有具有Menu属性的类实例。
这是使用接口是为了兼容Toolbar的工具按钮和MenuHyperLink。

请到http://extaspnet.codeplex.com/SourceControl/ListDownloadableCommits.aspx下载最新源代码,此示例在other\menu_dynamic_run.aspx。

更深一步,为工具栏按钮添加后台事件处理函数
    protected void Page_Load(object sender, EventArgs e)
    {
        LoadToolbar();
        ExtAspNet.Button btn = new Button();
        btn.Text = "获取工具栏按钮个数";
        btn.Click += new EventHandler(btn_Click);
        Toolbar1.Items.Add(btn);
    }
    private void btn_Click(object sender, EventArgs e)
    {
        Alert.Show("工具栏按钮个数:" + Toolbar1.Items.Count);
    }
    

posted @ 2009-08-10 16:56  三生石上(FineUI控件)  阅读(7017)  评论(13编辑  收藏  举报