文章截图 - 更好的排版
问题描述
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); }