从TreeView的节点数据加载到WebService再到Ajax的联想
MS的TreeView到Ajax会有什么联系呢?说真的,我对Ajax不是很明白,自从下载了它的帮助及说明后,才恍然大悟,原来它就是MS的WebService的一个新名词。
不管三七二十一,我们先来从简单的入手,看看这个WebService到底是什么,以及这个Ajax又为我们做了什么?
首先,你可以从MS的网站上下载到关于TreeView的Web Controls。这里是相关的下载及说明。
http://msdn.microsoft.com/library/default.asp?url=/workshop/webcontrols/webcontrols_entry.asp
你应该可以学会什么是WebControls以及如何使用TreeView.
好了,我们看看如何在页面上添加一个TreeView:下面的代码添加到ASPX页面里,当然,要对MS的控件添加引用:<%@ Register TagPrefix="iewc" Namespace="Microsoft.Web.UI.WebControls" Assembly="Microsoft.Web.UI.WebControls, Version=1.0.2.226, Culture=neutral, PublicKeyToken=31bf3856ad364e35" %> <%@ Register TagPrefix="iewc" Namespace="Microsoft.Web.UI.WebControls" Assembly="Microsoft.Web.UI.WebControls, Version=1.0.2.226, Culture=neutral, PublicKeyToken=31bf3856ad364e35" %> <%@ Register TagPrefix="iewc" Namespace="Microsoft.Web.UI.WebControls" Assembly="Microsoft.Web.UI.WebControls, Version=1.0.2.226, Culture=neutral, PublicKeyToken=31bf3856ad364e35" %> <%@ Register TagPrefix="iewc" Namespace="Microsoft.Web.UI.WebControls" Assembly="Microsoft.Web.UI.WebControls, Version=1.0.2.226, Culture=neutral, PublicKeyToken=31bf3856ad364e35" %>
 <%@ Register TagPrefix="iewc" Namespace="Microsoft.Web.UI.WebControls" Assembly="Microsoft.Web.UI.WebControls, Version=1.0.2.226, Culture=neutral, PublicKeyToken=31bf3856ad364e35" %>
<%@ Register TagPrefix="iewc" Namespace="Microsoft.Web.UI.WebControls" Assembly="Microsoft.Web.UI.WebControls, Version=1.0.2.226, Culture=neutral, PublicKeyToken=31bf3856ad364e35" %>
 <%@ Page language="c#" Codebehind="WebForm1.aspx.cs" AutoEventWireup="false" Inherits="Webb.WAVE.WebService.WebForm1" %>
<%@ Page language="c#" Codebehind="WebForm1.aspx.cs" AutoEventWireup="false" Inherits="Webb.WAVE.WebService.WebForm1" %>
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
 <HTML>
<HTML>
 <HEAD>
    <HEAD>
 </HEAD>
    </HEAD>
 <body>
    <body>
 <form id="Form1" method="post" runat="server">
        <form id="Form1" method="post" runat="server">
 <iewc:TreeView id="TreeView1" runat="server">
            <iewc:TreeView id="TreeView1" runat="server">
 <iewc:TreeNode Text="Node0">
                <iewc:TreeNode Text="Node0">
 <iewc:TreeNode Text="Node5"></iewc:TreeNode>
                    <iewc:TreeNode Text="Node5"></iewc:TreeNode>
 <iewc:TreeNode Text="Node6"></iewc:TreeNode>
                    <iewc:TreeNode Text="Node6"></iewc:TreeNode>
 <iewc:TreeNode Text="Node7"></iewc:TreeNode>
                    <iewc:TreeNode Text="Node7"></iewc:TreeNode>
 </iewc:TreeNode>
                </iewc:TreeNode>
 <iewc:TreeNode Text="Node1"></iewc:TreeNode>
                <iewc:TreeNode Text="Node1"></iewc:TreeNode>
 <iewc:TreeNode Text="Node2"></iewc:TreeNode>
                <iewc:TreeNode Text="Node2"></iewc:TreeNode>
 <iewc:TreeNode Text="Node3"></iewc:TreeNode>
                <iewc:TreeNode Text="Node3"></iewc:TreeNode>
 <iewc:TreeNode Text="Node4"></iewc:TreeNode>
                <iewc:TreeNode Text="Node4"></iewc:TreeNode>
 </iewc:TreeView>
            </iewc:TreeView>
 </form>
        </form>
 </body>
    </body>
 </HTML>
</HTML>
 这应该是极简单的事情了。
这应该是极简单的事情了。
然而我却偶然在MS的网站上看到了这样的代码:
 <iewc:TreeView id="TreeView1" runat="server">
            <iewc:TreeView id="TreeView1" runat="server">
 <iewc:TreeNode Text="Node0">
                <iewc:TreeNode Text="Node0">
 <!--#include file="TextFile1.txt"-->
                <!--#include file="TextFile1.txt"-->
 </iewc:TreeNode>
                </iewc:TreeNode>
 <iewc:TreeNode Text="Node1"></iewc:TreeNode>
                <iewc:TreeNode Text="Node1"></iewc:TreeNode>
 <iewc:TreeNode Text="Node2"></iewc:TreeNode>
                <iewc:TreeNode Text="Node2"></iewc:TreeNode>
 <iewc:TreeNode Text="Node3"></iewc:TreeNode>
                <iewc:TreeNode Text="Node3"></iewc:TreeNode>
 <iewc:TreeNode Text="Node4"></iewc:TreeNode>
                <iewc:TreeNode Text="Node4"></iewc:TreeNode>
 </iewc:TreeView>而文本文件就是一些子节点数据文件。这不是一个好方法来添加节点,因为一方面在设计时会出现错误而不能显示TreeView,另一方面也使得页面逻辑混乱,然而它却为我打开了一个思路!
            </iewc:TreeView>而文本文件就是一些子节点数据文件。这不是一个好方法来添加节点,因为一方面在设计时会出现错误而不能显示TreeView,另一方面也使得页面逻辑混乱,然而它却为我打开了一个思路!
如果我所添加的文件不是一个真实的文件,而是动态生成的文本文件呢?也就是说可以为不同的用户在TreeView里添加不同的数据节点。这是个好想法,然而上而的语法是不能通过的。因为include方法只能添加静态文件,而不能使用任何的参数。
于是不得不用其它的方法,就是使用XML文件来添加节点。这个方法在MS的网站上有很多的说明,因此就不多说了。我们只关心这个XML文件的来历,即动态的生成:
这有一个测试:
 using System;
using System;
 using System.Collections;
using System.Collections;
 using System.ComponentModel;
using System.ComponentModel;
 using System.Data;
using System.Data;
 using System.Drawing;
using System.Drawing;
 using System.Web;
using System.Web;
 using System.Web.SessionState;
using System.Web.SessionState;
 using System.Web.UI;
using System.Web.UI;
 using System.Web.UI.WebControls;
using System.Web.UI.WebControls;
 using System.Web.UI.HtmlControls;
using System.Web.UI.HtmlControls;
 using Webb.WAVE.Controls;
using Webb.WAVE.Controls;

 namespace Webb.WAVE.WebService
namespace Webb.WAVE.WebService
 {
{
 /// <summary>
    /// <summary>
 /// Summary description for TestForLoadTreeNodes.
    /// Summary description for TestForLoadTreeNodes.
 /// </summary>
    /// </summary>
 public class TestForLoadTreeNodes : System.Web.UI.Page
    public class TestForLoadTreeNodes : System.Web.UI.Page
 {
    {
 private string m_openFolderPic    = @"..\images\WAVE_Folder.gif";
        private string m_openFolderPic    = @"..\images\WAVE_Folder.gif";
 private string m_closeFolderPic    = @"..\images\WAVE_FolderOpen.gif";
        private string m_closeFolderPic    = @"..\images\WAVE_FolderOpen.gif";
 private string m_filePic        = @"..\images\WAVE_File.gif";
        private string m_filePic        = @"..\images\WAVE_File.gif";

 public bool IsShowFiles            = true;
        public bool IsShowFiles            = true;
 public bool IsShowCheckBox        = false;
        public bool IsShowCheckBox        = false;


 private void Page_Load(object sender, System.EventArgs e)
        private void Page_Load(object sender, System.EventArgs e)
 {
        {
 // Put user code to initialize the page here
            // Put user code to initialize the page here
 Object m_parentFolder    = this.Request["FolderID"];
            Object m_parentFolder    = this.Request["FolderID"];
 if(m_parentFolder==null)
            if(m_parentFolder==null)
 {
            {
 this.ShowErrorNode();
                this.ShowErrorNode();
 }
            }
 long m_folderID    = 0L;
            long m_folderID    = 0L;
 try
            try
 {
            {
 m_folderID    = Convert.ToInt32(m_parentFolder);
                m_folderID    = Convert.ToInt32(m_parentFolder);
 }
            }
 catch
            catch
 {
            {
 this.ShowErrorNode();
                this.ShowErrorNode();
 }
            }
 if(m_folderID==0)
            if(m_folderID==0)
 {
            {
 this.ShowErrorNode();
                this.ShowErrorNode();
 }
            }
 this.ShowNodeXML(m_folderID);
            this.ShowNodeXML(m_folderID);
 this.Response.End();
            this.Response.End();
 }
        }
 
  
 private void ShowErrorNode()
        private void ShowErrorNode()
 {
        {
 string m_errorNode    =@"<TREENODES>
            string m_errorNode    =@"<TREENODES>
 <TREENODE TEXT=""Load Data Error!""/>
<TREENODE TEXT=""Load Data Error!""/>
 </TREENODES>";
</TREENODES>";
 this.Response.Write(m_errorNode);
            this.Response.Write(m_errorNode);
 }
        } 

 /// <summary>
        /// <summary>
 ///
        /// 
 /// </summary>
        /// </summary>
 /// <param name="i_folderID"></param>
        /// <param name="i_folderID"></param>
 private void ShowNodeXML(long i_folderID)
        private void ShowNodeXML(long i_folderID)
 {
        {
 //Sub Folder
            //Sub Folder
 DataTable m_table    = new DataTable();
            DataTable m_table    = new DataTable();
 WaveFolderManager.GetSubFolderData(m_table,i_folderID);
            WaveFolderManager.GetSubFolderData(m_table,i_folderID);
 render xml data
            render xml data
 }
        } 

 Web Form Designer generated code
        Web Form Designer generated code
 }
    }
 }
}
 它专门用于查询数据库,根据参数来生成XML文件。于是我们在TreeView上可以添加一些事件,让它动态的绑定节点(不用刷新页面)。
它专门用于查询数据库,根据参数来生成XML文件。于是我们在TreeView上可以添加一些事件,让它动态的绑定节点(不用刷新页面)。
 private void TreeView1_Load(object sender, System.EventArgs e)
        private void TreeView1_Load(object sender, System.EventArgs e)
 {
        {
 string m_treeViewID    = this.TreeView1.ClientID;
            string m_treeViewID    = this.TreeView1.ClientID;
 //(sender as TreeView).Attributes.Add("onexpand","return ShowTreeNode('"+m_treeViewID+"');");
            //(sender as TreeView).Attributes.Add("onexpand","return ShowTreeNode('"+m_treeViewID+"');");
 string m_textBoxID    = this.TextBox_SelectedData.ClientID;
            string m_textBoxID    = this.TextBox_SelectedData.ClientID;
 (sender as TreeView).Attributes.Add("onselectedindexchange","return SelectedNode('"+m_treeViewID+"','"+m_textBoxID+"');");
            (sender as TreeView).Attributes.Add("onselectedindexchange","return SelectedNode('"+m_treeViewID+"','"+m_textBoxID+"');");    
 (sender as TreeView).Attributes.Add("onclick","return ShowTreeNode('"+m_treeViewID+"');");
            (sender as TreeView).Attributes.Add("onclick","return ShowTreeNode('"+m_treeViewID+"');");    
 //    (sender as TreeView).Attributes.Add("onload","this.click();alert();return false;");
        //    (sender as TreeView).Attributes.Add("onload","this.click();alert();return false;");    
 }相关JS代码:
        }相关JS代码:
 //TreeView.js
//TreeView.js
 //Cleint Jscript: Load tree nodes for IE web controls of treeview.
//Cleint Jscript: Load tree nodes for IE web controls of treeview.
 //Edit by: Wu.Country 2006-05
//Edit by: Wu.Country 2006-05

 ///
///
 ///
///
 ///str_objID:TreeVirw client ID
///str_objID:TreeVirw client ID
 function ShowTreeNode(str_ObjID){
function ShowTreeNode(str_ObjID){
 var m_treeView        = eval("document.all."+str_ObjID);
    var m_treeView        = eval("document.all."+str_ObjID);
 var m_selectedNode    =  m_treeView.getTreeNode(m_treeView.selectedNodeIndex);
    var m_selectedNode    =  m_treeView.getTreeNode(m_treeView.selectedNodeIndex);
 //alert(m_selectedNode.getAttribute("NodeData"));
    //alert(m_selectedNode.getAttribute("NodeData"));
 var m_nodeData        = m_selectedNode.getAttribute("NodeData");
    var m_nodeData        = m_selectedNode.getAttribute("NodeData");
 var m_isLoaded        = m_selectedNode.getAttribute("IsLoaded");
    var m_isLoaded        = m_selectedNode.getAttribute("IsLoaded");
 if(m_isLoaded!=null){
    if(m_isLoaded!=null){
 event.cancelBubble=true;
        event.cancelBubble=true;
 return false;
        return false;
 }else{
    }else{
 var m_id    = m_nodeData.split("|");
        var m_id    = m_nodeData.split("|");
 if(m_id[2]!="folder"){
        if(m_id[2]!="folder"){
 m_selectedNode.setAttribute("IsLoaded",true);
            m_selectedNode.setAttribute("IsLoaded",true);    
 event.cancelBubble=true;
            event.cancelBubble=true;
 return false;
            return false;
 }
        }
 //The request respone should return a XML file.
        //The request respone should return a XML file.
 //<TREENODES>
        //<TREENODES>
 //<TREENODE TEXT="MyDocuments" NodeData="4|2|folder"/>
        //<TREENODE TEXT="MyDocuments" NodeData="4|2|folder"/>
 //<TREENODE TEXT="MyUser'sFolder_1" NodeData="8|2|folder"/>
        //<TREENODE TEXT="MyUser'sFolder_1" NodeData="8|2|folder"/>
 //<TREENODE TEXT="2006_05" NodeData="245|2|folder"/>
        //<TREENODE TEXT="2006_05" NodeData="245|2|folder"/>
 //<TREENODE TEXT="策划方案.doc" NodeData="1289|2|file"/>
        //<TREENODE TEXT="策划方案.doc" NodeData="1289|2|file"/>
 //</TREENODES>
        //</TREENODES>
 //
        //
 m_selectedNode.setAttribute("treeNodeSrc","WebService/LoadTreeNodes.aspx?FolderID="+m_id[0]);
        m_selectedNode.setAttribute("treeNodeSrc","WebService/LoadTreeNodes.aspx?FolderID="+m_id[0]);            
 m_selectedNode.databind();
        m_selectedNode.databind();        
 m_selectedNode.setAttribute("IsLoaded",true);
        m_selectedNode.setAttribute("IsLoaded",true);
 m_selectedNode.setAttribute("EXPANDED",true);
        m_selectedNode.setAttribute("EXPANDED",true);
 }
    }
 //    event.cancelBubble=true;
//    event.cancelBubble=true;
 //    return false;
//    return false;
 }
}

 function SelectedNode(str_ObjID,str_ObjData){
function SelectedNode(str_ObjID,str_ObjData){
 var m_treeView        = eval("document.all."+str_ObjID);
    var m_treeView        = eval("document.all."+str_ObjID);
 var m_TextBox        = eval("document.all."+str_ObjData);
    var m_TextBox        = eval("document.all."+str_ObjData);
 var m_selectedNode    =  m_treeView.getTreeNode(m_treeView.selectedNodeIndex);
    var m_selectedNode    =  m_treeView.getTreeNode(m_treeView.selectedNodeIndex);
 var m_nodeData        = m_selectedNode.getAttribute("NodeData");
    var m_nodeData        = m_selectedNode.getAttribute("NodeData");
 var m_isLoaded        = m_selectedNode.getAttribute("IsLoaded");
    var m_isLoaded        = m_selectedNode.getAttribute("IsLoaded");
 ShowTreeNode(str_ObjID);
    ShowTreeNode(str_ObjID);
 m_TextBox.value        = m_selectedNode.getAttribute("NodeData")+"|"+m_selectedNode.getAttribute("Text");
    m_TextBox.value        = m_selectedNode.getAttribute("NodeData")+"|"+m_selectedNode.getAttribute("Text");
 //alert(m_selectedNode.getAttribute("NodeData"));
    //alert(m_selectedNode.getAttribute("NodeData"));
 //    event.cancelBubble=true;
//    event.cancelBubble=true;
 //    return false;
//    return false;
 }
}

 function ExpendTreeNode(str_ObjID){
function ExpendTreeNode(str_ObjID){
 var m_treeView        = eval("document.all."+str_ObjID);
    var m_treeView        = eval("document.all."+str_ObjID);
 m_treeView.setAttribute("selectedNodeIndex","0");
    m_treeView.setAttribute("selectedNodeIndex","0");
 alert();
    alert();
 }
}
 于是我们就简单的完成了一个概念上讲,类似WebService的事情了。
于是我们就简单的完成了一个概念上讲,类似WebService的事情了。
回顾一下我们的做法:
1、先做一个ASPX文件,它只负责生成XML文件,当然是TreeView可用的数据岛。
2、在TreeView上添加JS事件,让它在展开的时候,根据当前所选择的节点ID来查找所有子节点,并将参数传给上而的ASPX文件。
3、将返回结果绑定到TreeView上。
本质上讲,MS的webService和上面的过程类似。
我们再看一个WebService的例子:
 [WebMethod]
        [WebMethod]
 public string HelloWorld(long i_parentID)
        public string HelloWorld(long i_parentID)
 {
        {
 string m_retrunStr    = string.Empty;
            string m_retrunStr    = string.Empty;
 DataTable m_table    = new DataTable();
            DataTable m_table    = new DataTable();
 WaveFolderManager.GetSubFolderData(m_table,i_parentID);
            WaveFolderManager.GetSubFolderData(m_table,i_parentID);
 render xml data
            render xml data            
 } 经过调用后可以得到:
        } 经过调用后可以得到:
 <?xml version="1.0" encoding="utf-8" ?>
  <?xml version="1.0" encoding="utf-8" ?> 
 <string xmlns="http://tempuri.org/"><TREENODES> <TREENODE TEXT="MyDocuments" NodeData="4|2|folder" /> <TREENODE TEXT="MyUser'sFolder_1" NodeData="8|2|folder" /> <TREENODE TEXT="2006_05" NodeData="245|2|folder" /> <TREENODE TEXT="策划方案.doc" NodeData="1289|2|file"/> <TREENODE TEXT="策划方案.doc" NodeData="1308|2|file"/> <TREENODE TEXT="ABC.JPG" NodeData="1309|2|file"/> <TREENODE TEXT="策划方案.doc" NodeData="1400|2|file"/> <TREENODE TEXT="策划方案.doc" NodeData="1401|2|file"/> <TREENODE TEXT="test_135MB.avi" NodeData="1410|2|file"/> <TREENODE TEXT="test_3.25MB.avi" NodeData="1411|2|file"/> <TREENODE TEXT="冥王哈迪斯之冥界篇_前章06.rmvb" NodeData="1412|2|file"/> <TREENODE TEXT="MS_WSS_Dec_05.pdf" NodeData="1548|2|file"/> <TREENODE TEXT="MS_WSS_Dec_05.pdf" NodeData="1550|2|file"/></string> 显然,我们是没有办法直接使用WebMethod来返回数据给页面上的JS函数或者对象来使用的,虽然我们可以很轻松的写好WebMethod方法来返回我们想要的数据!
  <string xmlns="http://tempuri.org/"><TREENODES> <TREENODE TEXT="MyDocuments" NodeData="4|2|folder" /> <TREENODE TEXT="MyUser'sFolder_1" NodeData="8|2|folder" /> <TREENODE TEXT="2006_05" NodeData="245|2|folder" /> <TREENODE TEXT="策划方案.doc" NodeData="1289|2|file"/> <TREENODE TEXT="策划方案.doc" NodeData="1308|2|file"/> <TREENODE TEXT="ABC.JPG" NodeData="1309|2|file"/> <TREENODE TEXT="策划方案.doc" NodeData="1400|2|file"/> <TREENODE TEXT="策划方案.doc" NodeData="1401|2|file"/> <TREENODE TEXT="test_135MB.avi" NodeData="1410|2|file"/> <TREENODE TEXT="test_3.25MB.avi" NodeData="1411|2|file"/> <TREENODE TEXT="冥王哈迪斯之冥界篇_前章06.rmvb" NodeData="1412|2|file"/> <TREENODE TEXT="MS_WSS_Dec_05.pdf" NodeData="1548|2|file"/> <TREENODE TEXT="MS_WSS_Dec_05.pdf" NodeData="1550|2|file"/></string> 显然,我们是没有办法直接使用WebMethod来返回数据给页面上的JS函数或者对象来使用的,虽然我们可以很轻松的写好WebMethod方法来返回我们想要的数据!
于是就用到了所味的Ajax。其实除了Ajax,MS早就有一种技术可以直接在JS页面上调用WebService方法,它就是Css的behavior方法。
其实看上而的TreeView例子,为什么它可直接加载从ASPX页面上返回的节点数据呢?就是因为它已经实现了behavior,你要从MS的网站上下载这个文件:webservice.htc(在MS的网站上搜索一个,应该可以很快的找到该文件并下载),其实上面的TreeView就有这样的文件,而且在运行时是加载了一些HTC文件的,这才使得TreeView有了神出鬼没的数据加载效果。
没关系,我们可以自己为一个HTML Button添加事件并返回WebService上的数据。
看一个例子:还是用上而的服务:
 <%@ Page language="c#" Codebehind="WebForm1.aspx.cs" AutoEventWireup="false" Inherits="Webb.WAVE.WebService.WebForm1" %>
<%@ Page language="c#" Codebehind="WebForm1.aspx.cs" AutoEventWireup="false" Inherits="Webb.WAVE.WebService.WebForm1" %>
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
 <HTML>
<HTML>
 <HEAD>
    <HEAD>
 <script language="javascript">
        <script language="javascript">
 <!--
    <!--
 function Init(){
    function Init(){
 Service.useService("TVFolderAndFiles.asmx?WSDL","TVFolderAndFiles");
        Service.useService("TVFolderAndFiles.asmx?WSDL","TVFolderAndFiles");
 }
    }
 function GetTreeNodeData(){
    function GetTreeNodeData(){
 Service.TVFolderAndFiles.callService(OnResule,"HelloWorld",2);
        Service.TVFolderAndFiles.callService(OnResule,"HelloWorld",2);
 }
    }
 function OnResule(result){
    function OnResule(result){
 Service.innerText    = result.value;
        Service.innerText    = result.value;
 }
    }
 -->
    -->
 </script>
        </script>
 </HEAD>
    </HEAD>
 <body onload="Init()">
    <body onload="Init()">
 <form id="Form1" method="post" runat="server">
        <form id="Form1" method="post" runat="server">
 <div id="Service" style="behavior:url(../WAVE_script/1.01/webservice.htc)"></div>
            <div id="Service" style="behavior:url(../WAVE_script/1.01/webservice.htc)"></div>
 <INPUT type="button" value="Button" onclick="GetTreeNodeData();">
            <INPUT type="button" value="Button" onclick="GetTreeNodeData();">
 </form>
        </form>
 </body>
    </body>
 </HTML>
</HTML>
 点击后,我们一样可以得到结果:
点击后,我们一样可以得到结果:
<TREENODES>
<TREENODE TEXT="MyDocuments" NodeData="4|2|folder" />
<TREENODE TEXT="MyUser'sFolder_1" NodeData="8|2|folder" />
<TREENODE TEXT="2006_05" NodeData="245|2|folder" />
<TREENODE TEXT="策划方案.doc" NodeData="1289|2|file"/>
<TREENODE TEXT="策划方案.doc" NodeData="1308|2|file"/>
<TREENODE TEXT="ABC.JPG" NodeData="1309|2|file"/>
<TREENODE TEXT="策划方案.doc" NodeData="1400|2|file"/>
<TREENODE TEXT="策划方案.doc" NodeData="1401|2|file"/>
<TREENODE TEXT="test_135MB.avi" NodeData="1410|2|file"/>
<TREENODE TEXT="test_3.25MB.avi" NodeData="1411|2|file"/>
<TREENODE TEXT="冥王哈迪斯之冥界篇_前章06.rmvb" NodeData="1412|2|file"/>
<TREENODE TEXT="MS_WSS_Dec_05.pdf" NodeData="1548|2|file"/>
<TREENODE TEXT="MS_WSS_Dec_05.pdf" NodeData="1550|2|file"/>
怎么样,是不是对这个WebService有了一个大概的认识呢?
而对于Ajax,其原理和上面的beheivor是一样的(我只试了一下,没深入研究),只不过简化了一些操作,用了一个HTTPHander来处理所以来自Ajax的请求,然后变向的从服务器哪里取得数据并返回给调用函数。
因为本人对Ajax研究的不深,所以也就不深入的讨论这个Ajax了,但从上面的讨论中应该可以明确的发现,不管用什么新技术还是什么新名词,都是为了解决实际的需求。我之所以从TreeView的节点数据加载开始讨论这个WebService,就是因为TreeView的节点数据加载太浪费时间,而且每次的页面视图占用太多的数据,所以想到用其它的方法来解决。而在解决这一问题的时候,自然的也就用到了上面的这些东西。
不管三七二十一,我们先来从简单的入手,看看这个WebService到底是什么,以及这个Ajax又为我们做了什么?
首先,你可以从MS的网站上下载到关于TreeView的Web Controls。这里是相关的下载及说明。
http://msdn.microsoft.com/library/default.asp?url=/workshop/webcontrols/webcontrols_entry.asp
你应该可以学会什么是WebControls以及如何使用TreeView.
好了,我们看看如何在页面上添加一个TreeView:下面的代码添加到ASPX页面里,当然,要对MS的控件添加引用:<%@ Register TagPrefix="iewc" Namespace="Microsoft.Web.UI.WebControls" Assembly="Microsoft.Web.UI.WebControls, Version=1.0.2.226, Culture=neutral, PublicKeyToken=31bf3856ad364e35" %> <%@ Register TagPrefix="iewc" Namespace="Microsoft.Web.UI.WebControls" Assembly="Microsoft.Web.UI.WebControls, Version=1.0.2.226, Culture=neutral, PublicKeyToken=31bf3856ad364e35" %> <%@ Register TagPrefix="iewc" Namespace="Microsoft.Web.UI.WebControls" Assembly="Microsoft.Web.UI.WebControls, Version=1.0.2.226, Culture=neutral, PublicKeyToken=31bf3856ad364e35" %> <%@ Register TagPrefix="iewc" Namespace="Microsoft.Web.UI.WebControls" Assembly="Microsoft.Web.UI.WebControls, Version=1.0.2.226, Culture=neutral, PublicKeyToken=31bf3856ad364e35" %>
 <%@ Register TagPrefix="iewc" Namespace="Microsoft.Web.UI.WebControls" Assembly="Microsoft.Web.UI.WebControls, Version=1.0.2.226, Culture=neutral, PublicKeyToken=31bf3856ad364e35" %>
<%@ Register TagPrefix="iewc" Namespace="Microsoft.Web.UI.WebControls" Assembly="Microsoft.Web.UI.WebControls, Version=1.0.2.226, Culture=neutral, PublicKeyToken=31bf3856ad364e35" %> <%@ Page language="c#" Codebehind="WebForm1.aspx.cs" AutoEventWireup="false" Inherits="Webb.WAVE.WebService.WebForm1" %>
<%@ Page language="c#" Codebehind="WebForm1.aspx.cs" AutoEventWireup="false" Inherits="Webb.WAVE.WebService.WebForm1" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" > <HTML>
<HTML> <HEAD>
    <HEAD> </HEAD>
    </HEAD> <body>
    <body> <form id="Form1" method="post" runat="server">
        <form id="Form1" method="post" runat="server"> <iewc:TreeView id="TreeView1" runat="server">
            <iewc:TreeView id="TreeView1" runat="server"> <iewc:TreeNode Text="Node0">
                <iewc:TreeNode Text="Node0"> <iewc:TreeNode Text="Node5"></iewc:TreeNode>
                    <iewc:TreeNode Text="Node5"></iewc:TreeNode> <iewc:TreeNode Text="Node6"></iewc:TreeNode>
                    <iewc:TreeNode Text="Node6"></iewc:TreeNode> <iewc:TreeNode Text="Node7"></iewc:TreeNode>
                    <iewc:TreeNode Text="Node7"></iewc:TreeNode> </iewc:TreeNode>
                </iewc:TreeNode> <iewc:TreeNode Text="Node1"></iewc:TreeNode>
                <iewc:TreeNode Text="Node1"></iewc:TreeNode> <iewc:TreeNode Text="Node2"></iewc:TreeNode>
                <iewc:TreeNode Text="Node2"></iewc:TreeNode> <iewc:TreeNode Text="Node3"></iewc:TreeNode>
                <iewc:TreeNode Text="Node3"></iewc:TreeNode> <iewc:TreeNode Text="Node4"></iewc:TreeNode>
                <iewc:TreeNode Text="Node4"></iewc:TreeNode> </iewc:TreeView>
            </iewc:TreeView> </form>
        </form> </body>
    </body> </HTML>
</HTML>
然而我却偶然在MS的网站上看到了这样的代码:
 <iewc:TreeView id="TreeView1" runat="server">
            <iewc:TreeView id="TreeView1" runat="server"> <iewc:TreeNode Text="Node0">
                <iewc:TreeNode Text="Node0"> <!--#include file="TextFile1.txt"-->
                <!--#include file="TextFile1.txt"--> </iewc:TreeNode>
                </iewc:TreeNode> <iewc:TreeNode Text="Node1"></iewc:TreeNode>
                <iewc:TreeNode Text="Node1"></iewc:TreeNode> <iewc:TreeNode Text="Node2"></iewc:TreeNode>
                <iewc:TreeNode Text="Node2"></iewc:TreeNode> <iewc:TreeNode Text="Node3"></iewc:TreeNode>
                <iewc:TreeNode Text="Node3"></iewc:TreeNode> <iewc:TreeNode Text="Node4"></iewc:TreeNode>
                <iewc:TreeNode Text="Node4"></iewc:TreeNode> </iewc:TreeView>
            </iewc:TreeView>如果我所添加的文件不是一个真实的文件,而是动态生成的文本文件呢?也就是说可以为不同的用户在TreeView里添加不同的数据节点。这是个好想法,然而上而的语法是不能通过的。因为include方法只能添加静态文件,而不能使用任何的参数。
于是不得不用其它的方法,就是使用XML文件来添加节点。这个方法在MS的网站上有很多的说明,因此就不多说了。我们只关心这个XML文件的来历,即动态的生成:
这有一个测试:
 using System;
using System; using System.Collections;
using System.Collections; using System.ComponentModel;
using System.ComponentModel; using System.Data;
using System.Data; using System.Drawing;
using System.Drawing; using System.Web;
using System.Web; using System.Web.SessionState;
using System.Web.SessionState; using System.Web.UI;
using System.Web.UI; using System.Web.UI.WebControls;
using System.Web.UI.WebControls; using System.Web.UI.HtmlControls;
using System.Web.UI.HtmlControls; using Webb.WAVE.Controls;
using Webb.WAVE.Controls;
 namespace Webb.WAVE.WebService
namespace Webb.WAVE.WebService {
{ /// <summary>
    /// <summary> /// Summary description for TestForLoadTreeNodes.
    /// Summary description for TestForLoadTreeNodes. /// </summary>
    /// </summary> public class TestForLoadTreeNodes : System.Web.UI.Page
    public class TestForLoadTreeNodes : System.Web.UI.Page {
    { private string m_openFolderPic    = @"..\images\WAVE_Folder.gif";
        private string m_openFolderPic    = @"..\images\WAVE_Folder.gif"; private string m_closeFolderPic    = @"..\images\WAVE_FolderOpen.gif";
        private string m_closeFolderPic    = @"..\images\WAVE_FolderOpen.gif"; private string m_filePic        = @"..\images\WAVE_File.gif";
        private string m_filePic        = @"..\images\WAVE_File.gif";
 public bool IsShowFiles            = true;
        public bool IsShowFiles            = true; public bool IsShowCheckBox        = false;
        public bool IsShowCheckBox        = false;

 private void Page_Load(object sender, System.EventArgs e)
        private void Page_Load(object sender, System.EventArgs e) {
        { // Put user code to initialize the page here
            // Put user code to initialize the page here Object m_parentFolder    = this.Request["FolderID"];
            Object m_parentFolder    = this.Request["FolderID"]; if(m_parentFolder==null)
            if(m_parentFolder==null) {
            { this.ShowErrorNode();
                this.ShowErrorNode(); }
            } long m_folderID    = 0L;
            long m_folderID    = 0L; try
            try {
            { m_folderID    = Convert.ToInt32(m_parentFolder);
                m_folderID    = Convert.ToInt32(m_parentFolder); }
            } catch
            catch {
            { this.ShowErrorNode();
                this.ShowErrorNode(); }
            } if(m_folderID==0)
            if(m_folderID==0) {
            { this.ShowErrorNode();
                this.ShowErrorNode(); }
            } this.ShowNodeXML(m_folderID);
            this.ShowNodeXML(m_folderID); this.Response.End();
            this.Response.End(); }
        } 
   private void ShowErrorNode()
        private void ShowErrorNode() {
        { string m_errorNode    =@"<TREENODES>
            string m_errorNode    =@"<TREENODES> <TREENODE TEXT=""Load Data Error!""/>
<TREENODE TEXT=""Load Data Error!""/> </TREENODES>";
</TREENODES>"; this.Response.Write(m_errorNode);
            this.Response.Write(m_errorNode); }
        } 
 /// <summary>
        /// <summary> ///
        ///  /// </summary>
        /// </summary> /// <param name="i_folderID"></param>
        /// <param name="i_folderID"></param> private void ShowNodeXML(long i_folderID)
        private void ShowNodeXML(long i_folderID) {
        { //Sub Folder
            //Sub Folder DataTable m_table    = new DataTable();
            DataTable m_table    = new DataTable(); WaveFolderManager.GetSubFolderData(m_table,i_folderID);
            WaveFolderManager.GetSubFolderData(m_table,i_folderID); render xml data
            render xml data }
        } 
 Web Form Designer generated code
        Web Form Designer generated code }
    } }
}
 private void TreeView1_Load(object sender, System.EventArgs e)
        private void TreeView1_Load(object sender, System.EventArgs e) {
        { string m_treeViewID    = this.TreeView1.ClientID;
            string m_treeViewID    = this.TreeView1.ClientID; //(sender as TreeView).Attributes.Add("onexpand","return ShowTreeNode('"+m_treeViewID+"');");
            //(sender as TreeView).Attributes.Add("onexpand","return ShowTreeNode('"+m_treeViewID+"');"); string m_textBoxID    = this.TextBox_SelectedData.ClientID;
            string m_textBoxID    = this.TextBox_SelectedData.ClientID; (sender as TreeView).Attributes.Add("onselectedindexchange","return SelectedNode('"+m_treeViewID+"','"+m_textBoxID+"');");
            (sender as TreeView).Attributes.Add("onselectedindexchange","return SelectedNode('"+m_treeViewID+"','"+m_textBoxID+"');");     (sender as TreeView).Attributes.Add("onclick","return ShowTreeNode('"+m_treeViewID+"');");
            (sender as TreeView).Attributes.Add("onclick","return ShowTreeNode('"+m_treeViewID+"');");     //    (sender as TreeView).Attributes.Add("onload","this.click();alert();return false;");
        //    (sender as TreeView).Attributes.Add("onload","this.click();alert();return false;");     }
        } //TreeView.js
//TreeView.js //Cleint Jscript: Load tree nodes for IE web controls of treeview.
//Cleint Jscript: Load tree nodes for IE web controls of treeview. //Edit by: Wu.Country 2006-05
//Edit by: Wu.Country 2006-05
 ///
/// ///
/// ///str_objID:TreeVirw client ID
///str_objID:TreeVirw client ID function ShowTreeNode(str_ObjID){
function ShowTreeNode(str_ObjID){ var m_treeView        = eval("document.all."+str_ObjID);
    var m_treeView        = eval("document.all."+str_ObjID); var m_selectedNode    =  m_treeView.getTreeNode(m_treeView.selectedNodeIndex);
    var m_selectedNode    =  m_treeView.getTreeNode(m_treeView.selectedNodeIndex); //alert(m_selectedNode.getAttribute("NodeData"));
    //alert(m_selectedNode.getAttribute("NodeData")); var m_nodeData        = m_selectedNode.getAttribute("NodeData");
    var m_nodeData        = m_selectedNode.getAttribute("NodeData"); var m_isLoaded        = m_selectedNode.getAttribute("IsLoaded");
    var m_isLoaded        = m_selectedNode.getAttribute("IsLoaded"); if(m_isLoaded!=null){
    if(m_isLoaded!=null){ event.cancelBubble=true;
        event.cancelBubble=true; return false;
        return false; }else{
    }else{ var m_id    = m_nodeData.split("|");
        var m_id    = m_nodeData.split("|"); if(m_id[2]!="folder"){
        if(m_id[2]!="folder"){ m_selectedNode.setAttribute("IsLoaded",true);
            m_selectedNode.setAttribute("IsLoaded",true);     event.cancelBubble=true;
            event.cancelBubble=true; return false;
            return false; }
        } //The request respone should return a XML file.
        //The request respone should return a XML file. //<TREENODES>
        //<TREENODES> //<TREENODE TEXT="MyDocuments" NodeData="4|2|folder"/>
        //<TREENODE TEXT="MyDocuments" NodeData="4|2|folder"/> //<TREENODE TEXT="MyUser'sFolder_1" NodeData="8|2|folder"/>
        //<TREENODE TEXT="MyUser'sFolder_1" NodeData="8|2|folder"/> //<TREENODE TEXT="2006_05" NodeData="245|2|folder"/>
        //<TREENODE TEXT="2006_05" NodeData="245|2|folder"/> //<TREENODE TEXT="策划方案.doc" NodeData="1289|2|file"/>
        //<TREENODE TEXT="策划方案.doc" NodeData="1289|2|file"/> //</TREENODES>
        //</TREENODES> //
        // m_selectedNode.setAttribute("treeNodeSrc","WebService/LoadTreeNodes.aspx?FolderID="+m_id[0]);
        m_selectedNode.setAttribute("treeNodeSrc","WebService/LoadTreeNodes.aspx?FolderID="+m_id[0]);             m_selectedNode.databind();
        m_selectedNode.databind();         m_selectedNode.setAttribute("IsLoaded",true);
        m_selectedNode.setAttribute("IsLoaded",true); m_selectedNode.setAttribute("EXPANDED",true);
        m_selectedNode.setAttribute("EXPANDED",true); }
    } //    event.cancelBubble=true;
//    event.cancelBubble=true; //    return false;
//    return false; }
}
 function SelectedNode(str_ObjID,str_ObjData){
function SelectedNode(str_ObjID,str_ObjData){ var m_treeView        = eval("document.all."+str_ObjID);
    var m_treeView        = eval("document.all."+str_ObjID); var m_TextBox        = eval("document.all."+str_ObjData);
    var m_TextBox        = eval("document.all."+str_ObjData); var m_selectedNode    =  m_treeView.getTreeNode(m_treeView.selectedNodeIndex);
    var m_selectedNode    =  m_treeView.getTreeNode(m_treeView.selectedNodeIndex); var m_nodeData        = m_selectedNode.getAttribute("NodeData");
    var m_nodeData        = m_selectedNode.getAttribute("NodeData"); var m_isLoaded        = m_selectedNode.getAttribute("IsLoaded");
    var m_isLoaded        = m_selectedNode.getAttribute("IsLoaded"); ShowTreeNode(str_ObjID);
    ShowTreeNode(str_ObjID); m_TextBox.value        = m_selectedNode.getAttribute("NodeData")+"|"+m_selectedNode.getAttribute("Text");
    m_TextBox.value        = m_selectedNode.getAttribute("NodeData")+"|"+m_selectedNode.getAttribute("Text"); //alert(m_selectedNode.getAttribute("NodeData"));
    //alert(m_selectedNode.getAttribute("NodeData")); //    event.cancelBubble=true;
//    event.cancelBubble=true; //    return false;
//    return false; }
}
 function ExpendTreeNode(str_ObjID){
function ExpendTreeNode(str_ObjID){ var m_treeView        = eval("document.all."+str_ObjID);
    var m_treeView        = eval("document.all."+str_ObjID); m_treeView.setAttribute("selectedNodeIndex","0");
    m_treeView.setAttribute("selectedNodeIndex","0"); alert();
    alert(); }
}
回顾一下我们的做法:
1、先做一个ASPX文件,它只负责生成XML文件,当然是TreeView可用的数据岛。
2、在TreeView上添加JS事件,让它在展开的时候,根据当前所选择的节点ID来查找所有子节点,并将参数传给上而的ASPX文件。
3、将返回结果绑定到TreeView上。
本质上讲,MS的webService和上面的过程类似。
我们再看一个WebService的例子:
 [WebMethod]
        [WebMethod] public string HelloWorld(long i_parentID)
        public string HelloWorld(long i_parentID) {
        { string m_retrunStr    = string.Empty;
            string m_retrunStr    = string.Empty; DataTable m_table    = new DataTable();
            DataTable m_table    = new DataTable(); WaveFolderManager.GetSubFolderData(m_table,i_parentID);
            WaveFolderManager.GetSubFolderData(m_table,i_parentID); render xml data
            render xml data             }
        } <?xml version="1.0" encoding="utf-8" ?>
  <?xml version="1.0" encoding="utf-8" ?>  <string xmlns="http://tempuri.org/"><TREENODES> <TREENODE TEXT="MyDocuments" NodeData="4|2|folder" /> <TREENODE TEXT="MyUser'sFolder_1" NodeData="8|2|folder" /> <TREENODE TEXT="2006_05" NodeData="245|2|folder" /> <TREENODE TEXT="策划方案.doc" NodeData="1289|2|file"/> <TREENODE TEXT="策划方案.doc" NodeData="1308|2|file"/> <TREENODE TEXT="ABC.JPG" NodeData="1309|2|file"/> <TREENODE TEXT="策划方案.doc" NodeData="1400|2|file"/> <TREENODE TEXT="策划方案.doc" NodeData="1401|2|file"/> <TREENODE TEXT="test_135MB.avi" NodeData="1410|2|file"/> <TREENODE TEXT="test_3.25MB.avi" NodeData="1411|2|file"/> <TREENODE TEXT="冥王哈迪斯之冥界篇_前章06.rmvb" NodeData="1412|2|file"/> <TREENODE TEXT="MS_WSS_Dec_05.pdf" NodeData="1548|2|file"/> <TREENODE TEXT="MS_WSS_Dec_05.pdf" NodeData="1550|2|file"/></string>
  <string xmlns="http://tempuri.org/"><TREENODES> <TREENODE TEXT="MyDocuments" NodeData="4|2|folder" /> <TREENODE TEXT="MyUser'sFolder_1" NodeData="8|2|folder" /> <TREENODE TEXT="2006_05" NodeData="245|2|folder" /> <TREENODE TEXT="策划方案.doc" NodeData="1289|2|file"/> <TREENODE TEXT="策划方案.doc" NodeData="1308|2|file"/> <TREENODE TEXT="ABC.JPG" NodeData="1309|2|file"/> <TREENODE TEXT="策划方案.doc" NodeData="1400|2|file"/> <TREENODE TEXT="策划方案.doc" NodeData="1401|2|file"/> <TREENODE TEXT="test_135MB.avi" NodeData="1410|2|file"/> <TREENODE TEXT="test_3.25MB.avi" NodeData="1411|2|file"/> <TREENODE TEXT="冥王哈迪斯之冥界篇_前章06.rmvb" NodeData="1412|2|file"/> <TREENODE TEXT="MS_WSS_Dec_05.pdf" NodeData="1548|2|file"/> <TREENODE TEXT="MS_WSS_Dec_05.pdf" NodeData="1550|2|file"/></string> 于是就用到了所味的Ajax。其实除了Ajax,MS早就有一种技术可以直接在JS页面上调用WebService方法,它就是Css的behavior方法。
其实看上而的TreeView例子,为什么它可直接加载从ASPX页面上返回的节点数据呢?就是因为它已经实现了behavior,你要从MS的网站上下载这个文件:webservice.htc(在MS的网站上搜索一个,应该可以很快的找到该文件并下载),其实上面的TreeView就有这样的文件,而且在运行时是加载了一些HTC文件的,这才使得TreeView有了神出鬼没的数据加载效果。
没关系,我们可以自己为一个HTML Button添加事件并返回WebService上的数据。
看一个例子:还是用上而的服务:
 <%@ Page language="c#" Codebehind="WebForm1.aspx.cs" AutoEventWireup="false" Inherits="Webb.WAVE.WebService.WebForm1" %>
<%@ Page language="c#" Codebehind="WebForm1.aspx.cs" AutoEventWireup="false" Inherits="Webb.WAVE.WebService.WebForm1" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" > <HTML>
<HTML> <HEAD>
    <HEAD> <script language="javascript">
        <script language="javascript"> <!--
    <!-- function Init(){
    function Init(){ Service.useService("TVFolderAndFiles.asmx?WSDL","TVFolderAndFiles");
        Service.useService("TVFolderAndFiles.asmx?WSDL","TVFolderAndFiles"); }
    } function GetTreeNodeData(){
    function GetTreeNodeData(){ Service.TVFolderAndFiles.callService(OnResule,"HelloWorld",2);
        Service.TVFolderAndFiles.callService(OnResule,"HelloWorld",2); }
    } function OnResule(result){
    function OnResule(result){ Service.innerText    = result.value;
        Service.innerText    = result.value; }
    } -->
    --> </script>
        </script> </HEAD>
    </HEAD> <body onload="Init()">
    <body onload="Init()"> <form id="Form1" method="post" runat="server">
        <form id="Form1" method="post" runat="server"> <div id="Service" style="behavior:url(../WAVE_script/1.01/webservice.htc)"></div>
            <div id="Service" style="behavior:url(../WAVE_script/1.01/webservice.htc)"></div> <INPUT type="button" value="Button" onclick="GetTreeNodeData();">
            <INPUT type="button" value="Button" onclick="GetTreeNodeData();"> </form>
        </form> </body>
    </body> </HTML>
</HTML>
<TREENODES>
<TREENODE TEXT="MyDocuments" NodeData="4|2|folder" />
<TREENODE TEXT="MyUser'sFolder_1" NodeData="8|2|folder" />
<TREENODE TEXT="2006_05" NodeData="245|2|folder" />
<TREENODE TEXT="策划方案.doc" NodeData="1289|2|file"/>
<TREENODE TEXT="策划方案.doc" NodeData="1308|2|file"/>
<TREENODE TEXT="ABC.JPG" NodeData="1309|2|file"/>
<TREENODE TEXT="策划方案.doc" NodeData="1400|2|file"/>
<TREENODE TEXT="策划方案.doc" NodeData="1401|2|file"/>
<TREENODE TEXT="test_135MB.avi" NodeData="1410|2|file"/>
<TREENODE TEXT="test_3.25MB.avi" NodeData="1411|2|file"/>
<TREENODE TEXT="冥王哈迪斯之冥界篇_前章06.rmvb" NodeData="1412|2|file"/>
<TREENODE TEXT="MS_WSS_Dec_05.pdf" NodeData="1548|2|file"/>
<TREENODE TEXT="MS_WSS_Dec_05.pdf" NodeData="1550|2|file"/>
怎么样,是不是对这个WebService有了一个大概的认识呢?
而对于Ajax,其原理和上面的beheivor是一样的(我只试了一下,没深入研究),只不过简化了一些操作,用了一个HTTPHander来处理所以来自Ajax的请求,然后变向的从服务器哪里取得数据并返回给调用函数。
因为本人对Ajax研究的不深,所以也就不深入的讨论这个Ajax了,但从上面的讨论中应该可以明确的发现,不管用什么新技术还是什么新名词,都是为了解决实际的需求。我之所以从TreeView的节点数据加载开始讨论这个WebService,就是因为TreeView的节点数据加载太浪费时间,而且每次的页面视图占用太多的数据,所以想到用其它的方法来解决。而在解决这一问题的时候,自然的也就用到了上面的这些东西。
    ================================
/\_/\
(=^o^=) Wu.Country@侠缘
(~)@(~) 一辈子,用心做一件事!
--------------------------------
学而不思则罔,思而不学则怠!
================================
/\_/\
(=^o^=) Wu.Country@侠缘
(~)@(~) 一辈子,用心做一件事!
--------------------------------
学而不思则罔,思而不学则怠!
================================
posted on 2006-05-16 16:33 Wu.Country@侠缘 阅读(1985) 评论(8) 收藏 举报


 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号