首先,做任何界面都需要先在纸面上设计一下布局。我们需要左右布局,左边出现treeview显示部门列表,而右边则显示部门所对应的员工信息。并且我们需要使用asp.net ajax方式,既页面是无刷新的。
接下来,由于这个demo界面交互行为实在是太简单,我们直接进入BLL设计环节。(正常情况下你应该将界面划分小的组件,每一个组件使用interface定义出用户行为)我们定义三个类型
usingSystem.Collections.Generic;
publicclass部门
{
publicstring名称 { get; set; }
publicstring编号{get;set;}
privateList<部门> _children = newList<部门>();
publicList<部门> 下级部门
{
get
{
return_children;
}
}
}
publicclass员工
{
publicstring姓名 { get; set; }
publicint生日_月 { get; set; }
publicint生日_日 { get; set; }
}
usingSystem;
usingSystem.Collections.Generic;
publicstaticclassBLL
{
privatestaticRandom Rnd = newRandom();
publicstatic部门 Get部门()
{
var x = new部门 { 名称 = "公司", 编号 = "0"};
var x1 = new部门 { 名称 = "总经办", 编号 = "001"};
var x3 = new部门 { 名称 = "人事劳资", 编号 = "003"};
x.下级部门.Add(x1);
x.下级部门.Add(x3);
var x32 = new部门 { 名称 = "食堂", 编号 = "00302"};
x3.下级部门.Add(x32);
returnx;
}
publicstaticList<员工> Get部门员工(stringcode)
{
if(code == null)
returnnewList<员工>();
var ret = newList<员工>();
for(var i = 0; i < Rnd.Next(10, 101); i++)
ret.Add(new员工
{
姓名 = "部门"+ code + "员工_"+ i.ToString(),
生日_月 = Rnd.Next(1, 13),
生日_日 = Rnd.Next(1, 29)
});
returnret;
}
}
设计好BLL之后,应该build一下网站。因为这些代码需要在界面设计时被感知。
现在剩下的就是aspx的设计了!注意以下设置都是使用vs的属性窗口、或者控件设计窗口输入的,没有必要进行手工修改html代码那么“高级”易错的动作。
首先创建一个asp.net ajax的页面,在我的电脑上创建的是default.aspx。然后拖入一个Table,设置其为1行两列,width为 100%。接下来,为左右两个td中分别拖入一个UpdatePanel,将名称修改为LeftPanel和RightPanel,将它们的 UpdateMode属性设置为,因为它们是分别刷新的(并不随其它地方的刷新而刷新)。
接着为左边的UpdatePanel中拖入一个TreeView控件,右边的UpdatePanel中的控件中拖入一个GridView控件。然后点击 GridView的设计窗口,设置数据源,选择ObjectDatasource数据源,这时候可以直接选择我们在BLL类中定义的那个“Get部门员 工”方法,接下来设计窗口要我们设置参数,我们选择这个参数关联控件->treeview1->输入要取得的属性表达 式:SelectedValue->默认值为空。
然后到GridView的属性窗体,设置其自动分页。
最后一步就是到treeview的属性窗体,创建其SelectedNodeChanged方法。
至此界面设计结束。得到的html是这样的:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<htmlxmlns="http://www.w3.org/1999/xhtml">
<headrunat="server">
<title></title>
</head>
<body>
<formid="form1"runat="server">
<asp:ScriptManagerID="ScriptManager1"runat="server">
</asp:ScriptManager>
<tablewidth="100%">
<tr>
<tdvalign="top">
<asp:UpdatePanelID="LeftPanel"runat="server"UpdateMode="Conditional">
<ContentTemplate>
<asp:TreeViewID="TreeView1"runat="server"OnSelectedNodeChanged="TreeView1_SelectedNodeChanged">
</asp:TreeView>
</ContentTemplate>
</asp:UpdatePanel>
</td>
<tdvalign="top">
<asp:UpdatePanelID="RightPanel"runat="server"UpdateMode="Conditional">
<ContentTemplate>
<asp:GridViewrunat="server"AllowPaging="True"AutoGenerateColumns="False"DataSourceID="ObjectDataSource1"
EnableModelValidation="True">
<Columns>
<asp:BoundFieldDataField="姓名"HeaderText="姓名"SortExpression="姓名"/>
<asp:BoundFieldDataField="生日_月"HeaderText="生日_月"SortExpression="生日_月"/>
<asp:BoundFieldDataField="生日_日"HeaderText="生日_日"SortExpression="生日_日"/>
</Columns>
</asp:GridView>
<asp:ObjectDataSourceID="ObjectDataSource1"runat="server"SelectMethod="Get部门员工"
TypeName="BLL">
<SelectParameters>
<asp:ControlParameterControlID="TreeView1"DefaultValue=""Name="code"
PropertyName="SelectedValue"Type="String"/>
</SelectParameters>
</asp:ObjectDataSource>
</ContentTemplate>
</asp:UpdatePanel>
</td>
</tr>
</table>
</form>
</body>
</html>
上面的设计,treeview选择一个节点之后什么都没有做,并且也没有为treeview绑定初始数据。原本我们应该尽可能少些代码,以提高界面应用程 序开发的可维护性。其实一些特殊数据的绑定机制、事件如何与BLL方法触发机制,等等,你可以实现写成工具库,然后调用一下,用一句话就可以自动绑定数 据,或者自动注册好事件处理程序。
这里我还是使用现编的代码。
protectedvoidTreeView1_SelectedNodeChanged(objectsender, EventArgs e)
{
this.RightPanel.Update();
}
这一句代码是说,当treeview上另一个节点被选择时,我们就局部刷新页面右半边的员工列表界面。由于员工列表自动跟treeview的selectedvalue绑定好了,所以我们不需要写一行代码。
然后我们写treeview的初始化代码
protectedvoidPage_Load(objectsender, EventArgs e)
{
if(!IsPostBack)
{
var g = BLL.Get部门();
BindDepartment(this.TreeView1.Nodes, g);
}
}
方法BindDepartment(ns, g)的目的是在树的节点列表ns中插入一个部门,并递归处理g的下级部门。
实际上写下了这个方法,你可以按 Ctrl+K+M 键让c#编辑器给你自动生成一个方法存根。如果没有生成也没有关系,反正代码在这里:
privatevoidBindDepartment(TreeNodeCollection treeNodeCollection, 部门 g)
{
var treenode = newTreeNode { Text = g.名称, Value = g.编号 };
treeNodeCollection.Add(treenode);
if(g.下级部门.Count > 0)
g.下级部门.ForEach(x => { BindDepartment(treenode.ChildNodes, x); });
}
至此,可以开始运行一下这个无刷新的列表显示组织机构的小demo了。首先,页面装载部门列表,因为treeview的selectedvalue没有 值,于是使用null调用“Get部门员工”方法,因此没有显示员工列表。然后当你点击某个部门,页面右边部分就及时刷新显示了此部门的员工(动态随机生 成的10~100个员工假数据),你可以在员工列表上翻页查看。