工作中经常用的的是第三发控件Developer Express,相信大家都知道它的强大功能,这次用到了TreeList做了一个权限的管理,发现TreeList非常好用,大家可以看它自带的Demo就知道了,功能很多,这里我就把我用到的说出来,大家一起交流学习。
TreeList有一个KeyFieldName和ParentFieldName,这2个非常重要,只要构造一个DataTable赋值给TreeList的DataSource,这个DataTable里面要有2列是必须的,因为这2列要赋给上面说的KeyFieldName和ParentFieldName,先不说上面意思,树应该是从根节点递归、递归、一直往下递归到叶子,KeyFieldName和ParentFieldName就起到这个作用,比如:下面的一个DataTable:
KeyFieldName | ParentFieldName | NodeName | NodeCode | Others |
1 | Null | 根节点1名称 | 根节点1编码 | 其他 |
2 | 1 | 节点1子节点名称 | 节点1子节点编码 | 其他 |
3 | 1 | 节点1子节点名称 | 节点1子节点编码 | 其他 |
4 | Null | 根节点4名称 | 根节点4编码 | 其他 |
5 | 4 | 节点4子节点名称 | 节点4子节点编码 | 其他 |
6 | 5 | 节点5子节点名称 | 节点5子节点编码 | 其他 |
这时,如果把这个DataTable赋给TreeList的话,就会产生下面的一棵树:
下面是一个构造TreeList的数据源的简单示例:
/// 构造一棵树型表结构
/// </summary>
/// <returns></returns>
private DataTable CreateTreeListTable()
{
DataTable dt = new DataTable();
DataColumn dcOID = new DataColumn( " KeyFieldName " , Type.GetType( " System.Int32 " ));
DataColumn dcParentOID = new DataColumn( " ParentFieldName " , Type.GetType( " System.Int32 " ));
DataColumn dcNodeName = new DataColumn( " NodeName " , Type.GetType( " System.String " ));
DataColumn dcNodeCode = new DataColumn( " NodeCode " , Type.GetType( " System.String " ));
DataColumn dcOthers = new DataColumn( " Others " , Type.GetType( " System.String " ));
dt.Columns.Add(dcOID);
dt.Columns.Add(dcParentOID);
dt.Columns.Add(dcNodeName);
dt.Columns.Add(dcNodeCode);
dt.Columns.Add(dcOthers);
// 以上代码完成了DataTable的构架,但是里面是没有任何数据的
DataRow dr1 = dt.NewRow();
dr1[ " KeyFieldName " ] = 1 ;
dr1[ " ParentFieldName " ] = DBNull.Value;
dr1[ " NodeName " ] = " 根节点名称 " ;
dr1[ " NodeCode " ] = " 根节点编码 " ;
dr1[ " Others " ] = " 其他 " ;
dt.Rows.Add(dr1);
DataRow dr2 = dt.NewRow();
dr2[ " KeyFieldName " ] = 2 ;
dr2[ " ParentFieldName " ] = 1 ;
dr2[ " NodeName " ] = " 节点子节点名称 " ;
dr2[ " NodeCode " ] = " 节点子节点编码 " ;
dr2[ " Others " ] = " 其他 " ;
dt.Rows.Add(dr2);
DataRow dr3 = dt.NewRow();
dr3[ " KeyFieldName " ] = 3 ;
dr3[ " ParentFieldName " ] = 1 ;
dr3[ " NodeName " ] = " 节点子节点名称 " ;
dr3[ " NodeCode " ] = " 节点子节点编码 " ;
dr3[ " Others " ] = " 其他 " ;
dt.Rows.Add(dr3);
DataRow dr4 = dt.NewRow();
dr4[ " KeyFieldName " ] = 4 ;
dr4[ " ParentFieldName " ] = DBNull.Value;
dr4[ " NodeName " ] = " 根节点名称 " ;
dr4[ " NodeCode " ] = " 根节点编码 " ;
dr4[ " Others " ] = " 其他 " ;
dt.Rows.Add(dr4);
DataRow dr5 = dt.NewRow();
dr5[ " KeyFieldName " ] = 5 ;
dr5[ " ParentFieldName " ] = 4 ;
dr5[ " NodeName " ] = " 节点子节点名称 " ;
dr5[ " NodeCode " ] = " 节点子节点编码 " ;
dr5[ " Others " ] = " 其他 " ;
dt.Rows.Add(dr5);
DataRow dr6 = dt.NewRow();
dr6[ " KeyFieldName " ] = 6 ;
dr6[ " ParentFieldName " ] = 5 ;
dr6[ " NodeName " ] = " 节点子节点名称 " ;
dr6[ " NodeCode " ] = " 节点子节点编码 " ;
dr6[ " Others " ] = " 其他 " ;
dt.Rows.Add(dr6);
return dt;
}
好了,一个TreeList构造完成,下面就是TreeList的一些常用用法,都比较简单,这里就直接上代码了,代码中有简单的注释,大家一看就明白哦。
/// 点击节点前
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void treeLstModuleAction_BeforeCheckNode( object sender, DevExpress.XtraTreeList.CheckNodeEventArgs e)
{
e.State = (e.PrevState == CheckState.Checked ? CheckState.Unchecked : CheckState.Checked);
}
/// <summary>
/// 点击节点后
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void treeLstModuleAction_AfterCheckNode( object sender, DevExpress.XtraTreeList.NodeEventArgs e)
{
SetCheckedChildNodes(e.Node, e.Node.CheckState);
SetCheckedParentNodes(e.Node, e.Node.CheckState);
}
/// <summary>
/// 选择子节点时触发
/// </summary>
/// <param name="node"></param>
/// <param name="check"></param>
private void SetCheckedChildNodes(TreeListNode node, CheckState check)
{
for ( int i = 0 ; i < node.Nodes.Count; i ++ )
{
node.Nodes[i].CheckState = check;
SetCheckedChildNodes(node.Nodes[i], check);
}
}
/// <summary>
/// 选择父节点时触发
/// </summary>
/// <param name="node"></param>
/// <param name="check"></param>
private void SetCheckedParentNodes(TreeListNode node, CheckState check)
{
if (node.ParentNode != null )
{
bool b = false ;
CheckState state;
for ( int i = 0 ; i < node.ParentNode.Nodes.Count; i ++ )
{
state = (CheckState)node.ParentNode.Nodes[i].CheckState;
if ( ! check.Equals(state))
{
b = ! b;
break ;
}
}
node.ParentNode.CheckState = b ? CheckState.Indeterminate : check;
SetCheckedParentNodes(node.ParentNode, check);
}
}
/// <summary>
/// 判断此节点下的所有孩子节点是否选中
/// </summary>
/// <param name="node"></param>
/// <returns></returns>
private Boolean IsChildsChecked(TreeListNode node)
{
for ( int i = 0 ; i < node.Nodes.Count; i ++ )
{
if (node.Nodes[i].CheckState == CheckState.Unchecked)
return false ;
if (node.Nodes[i].HasChildren)
IsChildsChecked(node.Nodes[i]);
}
return true ;
}
好了,至此,关于TreeList的一些常用用法就说到这了,大家如果有好的想法,请不吝赐教,谢谢!