首先看看需求,网站本身有一个BasePage页面基类,仅仅是app_code中的一个cs文件,网站上所有的页面都继承了该页,如果要一个个页面手动添加siteMapPath控件是很麻烦的,因此决定将控件SiteMapPath放在基类,问题是基类没有aspx,因此需要在后台代码中动态添加SiteMapPath控件。
第一个版本:
这时候第一个问题出现了,这样添加的站点地图导航控件会出现在页面的最后,而不是放在页面的最开始
于是第二次修改
控件是到了页面正上方,但是页面上的样式全丢了,查看源代码发现,SiteMapPath出现在了HTML标签的上面
于是第三次修改
正确地把siteMapPath加入到了窗体内开始的位置,但是新的问题发现了,页面上所有控件的ViewState状态都没法正常保存了,
例如回传后TextBox原有的值,CheckBox的选择框
asp.net页面周期是Init、Load Viewstate、Load PostData、Page_Load推测是PageLoad时加入控件导致原本Load完成的ViewState被破坏了,因此需要把代码改到Init中实现
第四次修改
最终,siteMapPath控件显示正常。
新的需求出现,某个页面是这样的
ProductCategory.aspx?CategoryId=1
原本的站点地图显示是
首页 > 产品分类列表
对应的SiteMap文件节点为
<siteMapNode url="~/ProductCategory.aspx" title="产品分类列表" description=""></siteMapNode>
现在需要根据传入的CategoryId不同显示不同的分类列表,例如CategoryId=1,表示显示所有数码产品,显示效果就应该是:
首页 > 数码产品列表
由于所有的分类都是在数据库动态生成的,因此,不可能一次性事先写入到SiteMap文件,也就是说需要以编程方式修改站点地图节点
查阅了相关msdn资料后,在ProductCategory.aspx.cs页面中实现代码如下:
实现效果。
注意,SiteMapResolve事件注册后在所有页面都会生效,因此,需要Unload时候取消该事件的注册,以免影响其它页面正常显示
至此,动态加载及修改站点地图控件告一段落。
站点地图控件可以说是微软提供的控件中很简单的一个控件,拖过去就可以用,但是挖掘一下,其实有很多东西可以挖掘的,例如动态加载、编程方式修改、节点模版设置、多个站点地图共存、站点地图控件对queryString中多个参数的识别、自定义站点地图支持程序等等。
“吾生也有涯,而知也无涯。”庄子的这前半句话还是有道理的。