您的位置:首页 > 编程语言 > ASP

Asp.net TreeView来构建用户选择输入的方法 推荐

2009-12-28 00:00 671 查看
一般的单项数据选择可以使用DropdownList控件来实现,但对于有多个选择性输入,而且输入有层次关系的内容,最好选择TreeView控件来实现。

本文介绍如何使用使用TreeView控件来有效获取用户的输入,其中涉及到TreeView控件的级联选择、去掉节点HTML链接变为展开目录、获取选择内容、如何构造数据库的信息变为树形内容以及弹出窗口使用等知识点,本文输入应用级别的例子,希望能做个记号,对己对人,皆为利好!^_^
本文的经营范围是一个可以输入分类及详细子内容的,由于内容繁多,而且具有一定的层次关系,因此,不适合采用DropdownList和CheckboxList控件,因此采用了带CheckBox属性的TreeView控件来辅助用户的输入。
输入界面大致如下所示,用户通过选择按钮,触发弹出对话框,在对话框中放置了TreeView控件。


在弹出的对话框中,放置的TreeView控件,一个带有CheckBox,可以方便用户选择,并且具有级联(通过Javascript实现,减少Post回发),另外由于内容比较多,我设置了展开的级别层次。





用户通过选择或者反选大类,可以选择或反选其列表下面的所有项目,也可以单独选择子项目。




由于通过Javascript不太好获取并组装返回的内容,本文通过了在后台遍历树的方式对返回值进行处理,然后在父窗体的Javascript中对返回值进行了绑定,使其在界面控件中得以显示指定格式的内容。



以下为HTML的代码,其中OnTreeNodeChecked为级联Javascript函数,SubmitValue为对返回值进行绑定的操作。
代码
<div class="search"> 
<span> 
<asp:ImageButton ID="btnSelect" runat="server" 
ImageUrl="~/Themes/Default/btn_select.gif" onclick="btnSelect_Click" 
/> 
<asp:ImageButton ID="btnClose" runat="server" OnClientClick="javascript:window.close();return false;" 
ImageUrl="~/Themes/Default/btn_close.gif" /> 
</span> 
<table cellspacing="0" cellpadding="0" border="0" width="100%"> 
<tr> 
<td class="ico"> 
  
</td> 
<td class="form"> 
<asp:TreeView ID="TreeView1" runat="server" onclick="OnTreeNodeChecked();" ShowCheckBoxes="All" 
ShowLines="True" ExpandDepth="1" Font-Bold="False" ForeColor="#0000CC"> 
</asp:TreeView> 
</td> 
</tr> 
</table> 
</div> 
<script language='javascript' type='text/javascript'> 
function OnTreeNodeChecked() { 
var ele = event.srcElement; 
if (ele.type == 'checkbox') { 
var childrenDivID = ele.id.replace('CheckBox', 'Nodes'); 
var div = document.getElementById(childrenDivID); 
if (div == null) return; 
var checkBoxs = div.getElementsByTagName('INPUT'); 
for (var i = 0; i < checkBoxs.length; i++) { 
if (checkBoxs[i].type == 'checkbox') 
checkBoxs[i].checked = ele.checked; 
} 
} 
} 
function SubmitValue() { 
var val = ""; 
var returnVal = new Array(); 
var inputs = document.all.tags("INPUT"); 
var n = 0; 
for (var i = 0; i < inputs.length; i++) // 遍历页面上所有的 input 
{ 
if (inputs[i].type == "checkbox") { 
if (inputs[i].checked) { 
var strValue = inputs[i].value; 
val += strValue + ','; 
//returnVal[n] = val; 
n = n + 1; 
} 
} //if(inputs[i].type="checkbox") 
} //for 
window.returnValue = val; 
window.close(); 
} 
</script>

下面代码是页面的后台代码,其中展示了如何对树进行数据绑定,使其能够显示有层次格式的内容,其中AddTreeNode是一个递归函数。btnSelect_Click事件处理函数,专门对返回的数据进行组装,以一定的格式显示到客户端的控件输入上。
代码
protected void Page_Load(object sender, EventArgs e) 
{ 
if (!this.IsPostBack) 
{ 
BindData(); 
} 
} 
private void BindData() 
{ 
ArrayList scopeTree = BLLFactory<BusinessScope>.Instance.GetTree(); 
foreach (BusinessScopeNodeInfo nodeInfo in scopeTree) 
{ 
TreeNode node = new TreeNode(nodeInfo.Name); 
node.SelectAction = TreeNodeSelectAction.Expand; 
this.TreeView1.Nodes.Add(node); 
AddTreeNode(node, nodeInfo); 
} 
} 
private void AddTreeNode(TreeNode parentNode, BusinessScopeNodeInfo nodeInfo) 
{ 
TreeNode treeNode = null; 
foreach (BusinessScopeNodeInfo subNodeInfo in nodeInfo.Children) 
{ 
treeNode = new TreeNode(subNodeInfo.Name); 
treeNode.SelectAction = TreeNodeSelectAction.Expand; 
parentNode.ChildNodes.Add(treeNode); 
AddTreeNode(treeNode, subNodeInfo); 
} 
} 
protected void btnSelect_Click(object sender, ImageClickEventArgs e) 
{ 
string result = ""; 
foreach (TreeNode parent in this.TreeView1.Nodes) 
{ 
foreach (TreeNode node in parent.ChildNodes) 
{ 
StringBuilder sb = new StringBuilder(); 
foreach (TreeNode subNode in node.ChildNodes) 
{ 
if (subNode.Checked) 
{ 
sb.AppendFormat("{0},", subNode.Text); 
} 
} 
if (sb.Length > 0) 
{ 
sb.Insert(0, string.Format("{0}(", node.Text)); 
sb.Append(")"); 
result += sb.ToString().Replace(",)", ")") + ";"; 
} 
else if (node.Checked) 
{ 
result += node.Text; 
} 
} 
} 
Helper.CloseWin(this, result.Trim(';')); 
}

其中数的数据组装也是需要注意的一个地方,为了提高效率,避免频繁查找数据库,我们先把符合条件的数据放到DataTable,然后通过对象的Select在内存中查找,这样可以很好的提高递归函数的查找效率。
代码
/// <summary> 
/// 获取数据树 
/// </summary> 
/// <returns></returns> 
public ArrayList GetTree() 
{ 
ArrayList arrReturn = new ArrayList(); 
string sql = string.Format("Select * From {0} Order By PID, Seq ", tableName); 
Database db = DatabaseFactory.CreateDatabase(); 
DbCommand cmdWrapper = db.GetSqlStringCommand(sql); 
DataSet ds = db.ExecuteDataSet(cmdWrapper); 
if (ds.Tables.Count > 0) 
{ 
DataTable dt = ds.Tables[0]; 
DataRow[] dataRows = dt.Select(string.Format(" PID = {0}", -1)); 
for (int i = 0; i < dataRows.Length; i++) 
{ 
int id = Convert.ToInt32(dataRows[i]["ID"]); 
BusinessScopeNodeInfo menuNodeInfo = GetNode(id, dt); 
arrReturn.Add(menuNodeInfo); 
} 
} 
return arrReturn; 
} 
private BusinessScopeNodeInfo GetNode(int id, DataTable dt) 
{ 
BusinessScopeInfo menuInfo = this.FindByID(id); 
BusinessScopeNodeInfo menuNodeInfo = new BusinessScopeNodeInfo(menuInfo); 
DataRow[] dChildRows = dt.Select(string.Format(" PID={0}", id)); 
for (int i = 0; i < dChildRows.Length; i++) 
{ 
int childId = Convert.ToInt32(dChildRows[i]["ID"]); 
BusinessScopeNodeInfo childNodeInfo = GetNode(childId, dt); 
menuNodeInfo.Children.Add(childNodeInfo); 
} 
return menuNodeInfo; 
}

其中所用到的数据实体如下面两个类所示,其中BusinessScopeNodeInfo 是对象 BusinessScopeInfo的进一步封装,方便提供树的基本信息,也就是BusinessScopeNodeInfo 是一个包含了子类数据的对象,BusinessScopeInfo仅仅是数据库对象的映射实体。
代码
/// <summary> 
/// BusinessScopeNodeInfo 的摘要说明。 
/// </summary> 
public class BusinessScopeNodeInfo : BusinessScopeInfo 
{ 
private ArrayList m_Children = new ArrayList(); 
/// <summary> 
/// 子菜单实体类对象集合 
/// </summary> 
public ArrayList Children 
{ 
get { return m_Children; } 
set { m_Children = value; } 
} 
public BusinessScopeNodeInfo() 
{ 
this.m_Children = new ArrayList(); 
} 
public BusinessScopeNodeInfo(BusinessScopeInfo scopeInfo) 
{ 
base.Id = scopeInfo.Id; 
base.Name = scopeInfo.Name; 
base.Seq = scopeInfo.Seq; 
} 
}

代码
[Serializable] 
public class BusinessScopeInfo : BaseEntity 
{ 
#region Field Members 
private decimal m_Id = 0; 
private decimal m_Pid = -1; 
private string m_Name = ""; 
private string m_Seq = ""; 
#endregion 
#region Property Members 
public virtual decimal Id 
{ 
get 
{ 
return this.m_Id; 
} 
set 
{ 
this.m_Id = value; 
} 
} 
public virtual decimal Pid 
{ 
get 
{ 
return this.m_Pid; 
} 
set 
{ 
this.m_Pid = value; 
} 
} 
public virtual string Name 
{ 
get 
{ 
return this.m_Name; 
} 
set 
{ 
this.m_Name = value; 
} 
} 
public virtual string Seq 
{ 
get 
{ 
return this.m_Seq; 
} 
set 
{ 
this.m_Seq = value; 
} 
} 
#endregion 
}

其中的数据格式大致如下(本文的例子是在Oracle环境中工作的),其实SqlServer或者其他数据库也是一样。



主要研究技术:代码生成工具、Visio二次开发
转载请注明出处:
撰写人:伍华聪
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: