随笔 - 29  文章 - 1 评论 - 180 trackbacks - 3
<2007年9月>
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456

欢迎访问我的非技术博客:
http://Moosdau.blog.163.com

与我联系

常用链接

留言簿(2)

随笔分类(28)

随笔档案(29)

搜索

  •  

最新评论

阅读排行榜

评论排行榜

这里介绍两种主要的方法, 先进行情景假定:
假定进入一个主页, 此主页包含两大模块, 一个叫做mod1, 一个叫做mod2, 点击第一个模块进行mod1 的主页, 左侧有树形列表显示mod1 的内容, 点击mod2 也跟mod1 一样, 不同之处在于左侧树形列表要显示mod2 的内容.
由于实际上可能有许多个模块, 所以为每个模块做一套页面是极不明智的做法, 应该只做一个模块主页, 因参数的不同而显示不同的内容, 在这种需求下, 树形列表treeview 必须展示不同的siteMap.

<1>设定siteMapProvider

这是最简单直接的做法, 缺点是灵活程度不够强, 如果遇到因权限的不同而需要不同的视图时, 这种方法就有点无能为力了. 但是在上面的情景假定中, 这应该是最理想的解决方案:
<1.1>配置web.config.
在system.web 节点下, 增加siteMap的定义, 示例:
   

 <siteMap >
      
<providers>
        
<add name="mod1" type="System.Web.XmlSiteMapProvider" siteMapFile="mod1.sitemap"/>
        
<add name="mod2" type="System.Web.XmlSiteMapProvider" siteMapFile="mod2.sitemap"/>
      
</providers>
    
</siteMap>


siteMap 节点本来应该指定一下"defaultProvider" 属性, 但是由于这里使用siteMap 文件, 正好是其默认的"XmlSiteMapProvider" 类型, 所以无需再次指定.
在providers 里面, 添加对每一个地图文件的定义, 其中mod1.sitemap 和mod2.sitemap 是已经定义好的两个sitemap地图文件. 每个provider的name 属性必须唯一.

<1.2>配置treeview的前台代码
往页面上放一个treeview控件, 并为它增加一个sitemapDataSource 控件. 代码:
 这里为它指定一个默认的provider, 引用在web.config 中定义的name属性名.

 

           <asp:TreeView ID="TreeView1" runat="server" DataSourceID="SiteMapDataSource1">
            
</asp:TreeView>
            
            
<asp:SiteMapDataSource ID="SiteMapDataSource1" runat="server" SiteMapProvider="mod1" />


<1.3> 配置变更代码
做为测试, 在页面上放一个按钮, 在按钮的点击事件中:
  

      if (SiteMapDataSource1.SiteMapProvider == "mod1")
            SiteMapDataSource1.SiteMapProvider 
= "mod2";
        
else
            SiteMapDataSource1.SiteMapProvider 
= "mod1";


运行测试, 点击按钮, 可以看到treeview 在两个sitemap 定义之间切换显示.

 

 

二. 自定义provider 类.

这是最自由的做法, 在这里可以放入任何自定义代码来定义最终的显示状态.
<2.1> 编写自定义provider 类
这个类应该继承自StaticSiteMapProvider 类,  示例代码:

 

   public class mySiteMapProvider : StaticSiteMapProvider
    
{
        
private SiteMapNode _root = null;

        
protected override void Clear()
        
{
            _root 
= null;
            
base.Clear();

        }



        
public override SiteMapNode BuildSiteMap()
        
{
            
lock (this)
            
{
                Clear();
                _root 
= new SiteMapNode(this"root""url""title");

                AddNode(_root, 
null);
                SiteMapNode cnode 
= new SiteMapNode(this"sub1""suburl1""subtitle1");
                AddNode(cnode, _root); 
                cnode 
= new SiteMapNode(this"sub2""suburl2""subtitle2");
                AddNode(cnode, _root); 

            }

            
//返回构建后的根节点。
            return _root;


        }


 


        
protected override SiteMapNode GetRootNodeCore()
        
{
            
return RootNode;
        }


 

        
public override SiteMapNode RootNode
        
{
            
get
            
{
                SiteMapNode temp 
= BuildSiteMap();
                
return temp;
            }

        }


 


        
public override void Initialize(string name, System.Collections.Specialized.NameValueCollection attributes)
        
{
            
base.Initialize(name, attributes);
        }



    }


 

这是一个高度简化的示意类, 在实际使用中, 绝对不应该用这么简单的做法, 比如在BuildSiteMap 方法中应加入必要的安全检查.  另外, 也是在BuildSiteMap 方法中, 应用实际的数据来代替这里的示意数据, 比如, 可以从数据库中读取各个结点. 也可以从xml 文件中读取.

<2.2>配置web.config
和使用默认的siteMap 文件一样, 这里也需要配置一下web.config, 代码:

<siteMap defaultProvider="mySiteMapProvider">
   
<providers>
    
<add name="mySiteMapProvider" type="LCT.mySiteMapProvider" />
   
</providers>
  
</siteMap>

 

其中type属性 须指出完整的命名空间. LCT 是我这个示意所在的命名空间名.

<2.3>前台代码:

 

            <asp:TreeView ID="TreeView1" runat="server" DataSourceID="SiteMapDataSource1">
            
</asp:TreeView>
            
            
<asp:SiteMapDataSource ID="SiteMapDataSource1" runat="server"/>


实际上不需要对前台进行任何的多余指定, siteMapDataSource 会自动对默认的provider 进行数据读取.

 至于显示哪一个mod 的sitemap, 只要把要显示的mod的名字写进一个session 变量里, 然后在build 的时候读取一下即可, 在通用类(而不是页面代码)  里使用当前页的session 等状态的方法是:
System.Web.HttpContext.Current.Session["XXXX"]
感谢Jack Niu  告诉我这个方法。

没有永恒的事
一切都在不断重复
我热爱这个世界
但绝不骄纵了它
posted on 2007-09-28 08:54 木刀 阅读(1554) 评论(6)  编辑 收藏 所属分类: asp.net 点滴

FeedBack:
#1楼  2007-09-28 10:03 Jack Niu      
在你的那个siteMap类中,可以这样写啊:
System.Web.HttpContext.Current.Session["XXXX"],也可以直接用Session的。
  回复  引用  查看    
#2楼 [楼主] 2007-09-28 10:15 木刀      
to: @Jack Niu
太谢谢你啦!
真不知道还可以这样访问.

我是把这个类放在一个独立的文件中的, 而不是放在页面的代码里, 所以不能直接用session.

真晕, 我原来的通用类里都是把response, request 这些东西作为参数传过来的, 真是... 唉~~ 呵呵 , 再次感谢!
  回复  引用  查看    
#3楼  2007-09-28 11:34 Vincent Yang      
custom sitemap provider在msdn上面有现成的code阿
  回复  引用  查看    
#4楼 [楼主] 2007-09-28 11:40 木刀      
to:@Vincent Yang
呃......我没有看到。
  回复  引用  查看    

标题  
姓名  
主页
Email (只有博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2007-09-28 10:18 编辑过
 
另存  打印