///如未特别说明,本人所发表的技术文章都为原创, 任何人引用都请注明出处,并包含本声明
///作者: CSDN网名alias88,邮件:alias88@163.com,QQ:63343 欢迎加我 :)
此树可以绑定到数据源,意味着可随着绑定管理器同步操作,
例如position改变自动选择结点,反过来亦然,选择不同的结点将改变绑定管理器的position,而且数据操作也能同步于绑定管理器,您在DataGrid中的改变将即时反映在树中......
还有一个特点,对数据结构没有要求,它总是能正确地将您的数据以树结构展现出来,下图中,如果使用搜索功能筛选出任一部分数据出来,左边的树形结构也将是正确的
使用方法和例图:
TreeView1.AllowDrop =true;
this.TreeView1.SetDataBinding (this.UserDataSet ,"会计科目" ,"上级编号","科目编号","科目名称",null);
using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
using upLibrary.upCommon ;
using upLibrary.upReflect;
using upLibrary.upControls ;
using System.Diagnostics;
using upSystem.upData ;
namespace upSystem.upControls
{
/// <summary>
/// 一个实现了数据绑定的树
/// </summary>
public class upTreeView : upTreeViewBase
{
private object dataSource;
private string dataMember;
private string parentIDColumn,idColumn,textColumn;
private object[] topID=null;
private PropertyDescriptorCollection propertys=null;
private PropertyDescriptor parentIDProperty,idProperty,textProperty;
private CurrencyManager bindingManager=null;
private IBindingList bindingList=null;
private bool dataSourceEvent,treeViewEvent;
private DataView dataView=null;
private upSystem.upCommon.upStack stack=new upSystem.upCommon.upStack ();
private System.ComponentModel.Container components = null;
public event System.EventHandler DataSourceChanged;
private System.Windows.Forms.ContextMenu cntMenu;
public upTreeView()
{
InitializeComponent();
this.cntMenu = new System.Windows.Forms.ContextMenu();
MenuItem mnu;
mnu=cntMenu.MenuItems.Add ("&O展开");
mnu.Click +=new EventHandler(mnu_Click);
mnu=cntMenu.MenuItems.Add ("&C折叠");
mnu.Click +=new EventHandler(mnu_Click);
mnu=cntMenu.MenuItems.Add ("-");
mnu=cntMenu.MenuItems.Add ("&E全部展开");
mnu.Click +=new EventHandler(mnu_Click);
mnu=cntMenu.MenuItems.Add ("&A全部折叠");
mnu.Click +=new EventHandler(mnu_Click);
this.ContextMenu = this.cntMenu;
}
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region 组件设计器生成的代码
/// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器
/// 修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
}
#endregion
#region 属性
/// <summary>
/// 父节点
/// </summary>
public string ParentIDColumn
{
get{return parentIDColumn ; }
set
{
if (parentIDColumn!=value )
{
parentIDColumn=value;
}
}
}
/// <summary>
/// 子结点
/// </summary>
public string IDColumn
{
get{return idColumn ;}
set
{
if (idColumn!=value )
{
idColumn=value;
}
}
}
/// <summary>
/// 节点文本
/// </summary>
public string TextColumn
{
get{return textColumn ;}
set
{
if (textColumn!=value )
{
textColumn=value;
}
}
}
/// <summary>
/// 树的根结点
/// </summary>
public object[] TopID
{
get{return topID ; }
set
{
if (topID!=value )
{
topID=value;
}
}
}
/// <summary>
/// 数据源
/// </summary>
public object DataSource
{
get{return dataSource;}
set
{
object oldSource=this.dataSource ;
if (((value != null) && !(value is IList)) && !(value is IListSource))
{
throw new Exception("该数据源不能作为树的数据源!");
}
try
{
this.SetBindingManager(value, this.dataMember , false);
}
catch
{
this.dataSource =oldSource;
}
}
}
/// <summary>
/// 数据成员
/// </summary>
[DefaultValue((string) null)]
public string DataMember
{
get{return dataMember;}
set
{
string olddataMember = this.dataMember;
try
{
this.SetBindingManager(this.dataSource , value , false);
}
catch (Exception)
{
this.dataMember = olddataMember;
}
}
}
/// <summary>
/// 绑定管理器
/// </summary>
protected CurrencyManager BindingManager
{
get
{
return this.bindingManager;
}
}
/// <summary>
/// 绑定管理器所管理的数据列表
/// </summary>
protected IBindingList BindingList
{
get{return bindingList;}
set
{
SetDataSourceEvent(false);
this.bindingList=value;
if (this.bindingList is DataView )
dataView=(this.bindingList as DataView );
SetDataSourceEvent(true);
}
}
protected PropertyDescriptorCollection PropertyDescriptors
{
get{return propertys; }
}
private PropertyDescriptorCollection Propertys
{
set
{
propertys=value;
if (propertys!=null)
{
idProperty =propertys.Find (this.idColumn ,true);
parentIDProperty=propertys.Find (this.parentIDColumn ,true);
textProperty =propertys.Find (this.textColumn ,true);
}
else
{
idProperty=null;
parentIDProperty=null;
textProperty=null;
}
}
}
protected PropertyDescriptor IDProperty
{
get{ return this.idProperty ;}
}
protected PropertyDescriptor ParentIDProperty
{
get{ return parentIDProperty ;}
}
protected PropertyDescriptor TextProperty
{
get{ return textProperty ;}
}
#endregion
#region 绑定管理器的设置
/// <summary>
/// 设置绑定
/// </summary>
/// <param name="newDataSource"></param>
/// <param name="newdataMember"></param>
/// <param name="force"></param>
internal void SetBindingManager(object newDataSource, string newdataMember, bool force)
{
bool dataSourceChanged = this.dataSource != newDataSource;
bool dataMemberChanged = this.dataMember !=null && !this.dataMember.Equals(newdataMember);
if (force || dataSourceChanged || dataMemberChanged)
{
if (this.dataSource is IComponent)
{
((IComponent) this.dataSource).Disposed -= new EventHandler(this.DataSourceDisposed);
}
this.dataSource = newDataSource;
this.dataMember = newdataMember;
Propertys=null;
BindingList=null;
if (this.dataSource is IComponent)
{
((IComponent) this.dataSource).Disposed += new EventHandler(this.DataSourceDisposed);
}
CurrencyManager manager = null;
if (((newDataSource != null) && (this.BindingContext != null)) && (newDataSource != Convert.DBNull))
{
manager = (CurrencyManager) this.BindingContext[newDataSource, newdataMember];
}
if (this.bindingManager != manager || force)
{
SetDataSourceEvent(false);
this.bindingManager = manager;
Propertys=this.bindingManager.GetItemProperties ();
if (bindingManager.List is IBindingList )
BindingList=this.bindingManager.List as IBindingList ;
SetDataSourceEvent(true);
}
if (this.bindingManager != null)
{
this.bindingManager_ItemChanged(this.bindingManager, null);
}
}
if (dataSourceChanged)
{
this.OnDataSourceChanged(EventArgs.Empty);
}
}
protected void OnDataSourceChanged(System.EventArgs e)
{
if (DataSourceChanged!=null)
DataSourceChanged(this,e);
}
protected void DataSourceDisposed(object sender, EventArgs e)
{
this.SetBindingManager(null, "", true);
}
#endregion
#region 可否绑定的检查
/// <summary>
/// 可否绑定的检查
/// </summary>
internal void CheckColumnInDataManager()
{
if (this.bindingManager == null)
return ;
PropertyDescriptor idpd,pidpd,txtpd;
PropertyDescriptorCollection pds = this.bindingManager.GetItemProperties();
idpd=pds.Find (this.idColumn , true);
pidpd=pds.Find (this.parentIDColumn , true);
txtpd=pds.Find (this.textColumn , true) ;
if (idpd==null || pidpd==null || txtpd==null)
throw new ArgumentException(string.Format ("参数设置错误,有一个或多个列不属于数据源:{0},{1},{2}" ,
this.idColumn , this.parentIDColumn , this.textColumn ), "newdataMember");
// if(!typeof(IList).IsAssignableFrom(idpd.PropertyType)
// || !typeof(IList).IsAssignableFrom(pidpd.PropertyType)
// || !typeof(IList).IsAssignableFrom(txtpd.PropertyType))
// throw new Exception ("加载表到树所必需的三个列中,有一个或多个列的类型无效" );
return ;
}
internal bool CheckBeforeSetBinding()
{
if ( parentIDColumn==null|| idColumn==null || textColumn==null ) return false;
if ( parentIDColumn==string.Empty|| idColumn==string.Empty || textColumn==string.Empty ) return false;
CheckColumnInDataManager();
if (this.BindingManager ==null || this.BindingList ==null) return false;
if (this.bindingManager.List is DataView )
{
DataTable dt =(this.bindingManager.List as DataView ).Table ;
if (dt.Columns[this.IDColumn].Unique ==false)
throw new Exception (string.Format ("{0}列不具备唯一性!",dt.Columns [this.IDColumn].Caption));
}
return true;
}
#endregion
#region 绑定数据到树
public void SetDataBinding ( object Datasource, string Datamember)
{
this.dataMember =Datamember;
this.DataSource =Datasource;
SetDataBinding();
}
public void SetDataBinding ( object Datasource, string Datamember,string parentIDcol,string idCol,string textCol)
{
this.parentIDColumn =parentIDcol;
this.idColumn =idCol;
this.textColumn =textCol;
SetDataBinding( Datasource, Datamember);
}
/// <summary>
/// 将数据源绑定到树
/// 例子:SetDataBinding(myDataSet, "部门表","上级部门编号","部门编号","部门名称",new object[]{"office"})
/// </summary>
public void SetDataBinding ( object Datasource, string Datamember,string parentIDcol,string idCol,string textCol,object[] topId)
{
this.topID =topId;
SetDataBinding( Datasource, Datamember,parentIDcol,idCol,textCol);
}
public void SetDataBinding()
{
this.HideSelection =false;
this.Nodes.Clear() ;
try
{
SetTreeEvent(false);
SetDataSourceEvent(false);
if (!CheckBeforeSetBinding()) return ;
this.BeginUpdate ();
if (topID==null)
topID=GetRootID();
if (topID!=null)
{
object[] drs=this.GetItems ( this.idProperty ,topID );
if (drs!=null)
for(int i =0 ; i < drs.Length ; i ++ )
AddNodesByData(null,drs[i]);
}
}
catch
{
throw ;
}
finally
{
stack.Clear ();
this.EndUpdate ();
SetTreeEvent(true);
SetDataSourceEvent(true);
}
}
/// <summary>
/// 列出根结点,根结点为没有父结点的结点
/// </summary>
/// <returns></returns>
internal object [] GetRootID()
{
System.Collections.ArrayList rootid=new ArrayList ();
for (int i = 0 ; i < this.bindingList.Count ; i ++)
{
object pkey= this.parentIDProperty.GetValue(this.bindingList[i]);
object key= this.idProperty.GetValue(this.bindingList[i]);
if (this.IndexOfValue (this.idProperty ,pkey )==-1)
rootid.Add (key ); //此IDColumn的父不存在,所以此IDColumn是根,无论父是否为空字串,有些算法只将父为空的当作根
}
if (rootid.Count >0)
{
object [] result=new object [rootid.Count ];
rootid.CopyTo (result,0);
return result;
}
return null;
}
/// <summary>
/// 据数据源加入一个DataNode,并加入其所有子树
/// </summary>
/// <param name="pdNode">新DataNode的上级</param>
/// <param name="dataRow">用此行数据信息来新建DataNode</param>
internal void AddNodesByData(upDataNode pdNode,object dataRow)
{
if (dataRow==null) return ;
upDataNode td=BuildNewNode(dataRow) ; //不能利用Base.AddNode()功能,因为只能得到当前行
if (base.AddNode (pdNode,td))
{
object[] drvs=this.GetItems (this.parentIDProperty ,td.Key );
if (drvs!=null)
foreach (object drv in drvs)
AddNodesByData(td,drv);
}
}
internal upDataNode BuildNewNode(object dataRow)
{
object key=this.idProperty.GetValue (dataRow); //不能利用Base.AddNode()功能,因为只能得到当前行
if (key==null) return null;
object pkey=parentIDProperty.GetValue(dataRow);
object text=textProperty.GetValue(dataRow);
upDataNode td= new upDataNode (key,text.ToString ());
return td;
}
internal upDataNode BuildNewNode(DataRow dataRow)
{
object key=dataRow[this.idColumn ];
if (key==null) return null;
object pkey=dataRow[this.parentIDColumn ];
object text=dataRow[this.textColumn ];
upDataNode td= new upDataNode (key,text.ToString ());
return td;
}
#endregion
#region 绑定管理器的事件
internal void SetDataSourceEvent(bool on)
{
if (!on || (on && dataSourceEvent)) //如果要求去掉事件,或者要求加上事件但先前已加上事件
{
dataSourceEvent=false;
if (this.bindingManager!=null)
{
this.bindingManager.ItemChanged -= new ItemChangedEventHandler(this.bindingManager_ItemChanged);
this.bindingManager.PositionChanged -= new EventHandler(this.bindingManager_PositionChanged);
}
if (dataView!=null)
{
dataView.Table.RowDeleting -=new DataRowChangeEventHandler(Table_RowDeleting);
dataView.Table.RowDeleted -=new DataRowChangeEventHandler(Table_RowDeleted);
dataView.Table.ColumnChanging -=new DataColumnChangeEventHandler(Table_ColumnChanging);
dataView.Table.ColumnChanged -=new DataColumnChangeEventHandler(Table_ColumnChanged);
dataView.Table.RowChanging -=new DataRowChangeEventHandler(Table_RowChanging);
dataView.Table.RowChanged -=new DataRowChangeEventHandler(Table_RowChanged);
}
else if (this.bindingList!=null)
this.bindingList.ListChanged -=new ListChangedEventHandler(bindingList_ListChanged);
}
if (on )
{
dataSourceEvent=true;
if (this.bindingManager!=null)
{
this.bindingManager.ItemChanged += new ItemChangedEventHandler(this.bindingManager_ItemChanged);
this.bindingManager.PositionChanged +=new EventHandler(bindingManager_PositionChanged);
}
if (dataView!=null)
{
dataView.Table.RowDeleting +=new DataRowChangeEventHandler(Table_RowDeleting);
dataView.Table.RowDeleted +=new DataRowChangeEventHandler(Table_RowDeleted);
dataView.Table.ColumnChanging +=new DataColumnChangeEventHandler(Table_ColumnChanging);
dataView.Table.ColumnChanged +=new DataColumnChangeEventHandler(Table_ColumnChanged);
dataView.Table.RowChanging +=new DataRowChangeEventHandler(Table_RowChanging);
dataView.Table.RowChanged +=new DataRowChangeEventHandler(Table_RowChanged);
}
else if (this.bindingList!=null)
this.bindingList.ListChanged +=new ListChangedEventHandler(bindingList_ListChanged);
}
}
private void bindingManager_PositionChanged(object sender, EventArgs e)
{
try
{
this.AfterSelect -=new TreeViewEventHandler(upTreeView_AfterSelect);
if (this.BindingManager.Position ==-1)
this.SelectedNode =null;
else
{
object key=this.GetValueByIndex (this.IDProperty ,this.bindingManager.Position );
this.SelectedNode =this.FindNode (null, key );
}
}
catch
{
throw ;
}
finally
{
this.AfterSelect +=new TreeViewEventHandler(upTreeView_AfterSelect);
}
}
private void bindingManager_ItemChanged(object sender, ItemChangedEventArgs e)
{
}
private void bindingManager_MetaDataChanged(object sender, EventArgs e)
{
}
private void bindingList_ListChanged(object sender, ListChangedEventArgs e)
{
try
{
stack.Push ("ByBinding");
SetDataSourceEvent(false);
int index=this.bindingManager.Position ;
switch (e.ListChangedType )
{
case ListChangedType.ItemAdded: //数据行增加等要反映到树节点上
if (this.bindingList [e.NewIndex ] is DataRowView)
if (!(this.bindingList [e.NewIndex ] as DataRowView ).IsNew )
AddNewNodeByNewRow(index );
break;
case ListChangedType.ItemChanged :
ChangeNodeByRowChanged (index );
break;
case ListChangedType.ItemDeleted :
//DeleteNodeByRowDelete(index ); //该行已删除,在列表已找不到,在此调用的话会将删除行后的当前行代表的节点
break;
case ListChangedType.ItemMoved :
//DeleteNodeByRowDelete(index );
break;
case ListChangedType.Reset :
this.AllowMoveNode =this.BindingList.AllowEdit ;
this.AllowCopyNode =this.BindingList.AllowNew ;
break;
}
}
catch(System.Exception ex)
{
upSystem.upCommon.upApp.HaveErr (this,ex,3);
throw ex;
}
finally
{
SetDataSourceEvent(true);
stack.Pop ();
}
}
private void Table_ColumnChanging(object sender, DataColumnChangeEventArgs e)
{
}
private void Table_ColumnChanged(object sender, DataColumnChangeEventArgs e)
{
}
private void Table_RowChanging(object sender, DataRowChangeEventArgs e)
{
try
{
stack.Push ("ByBinding");
SetDataSourceEvent(false);
if (e.Action ==DataRowAction.Add )
AddNewNodeByNewRow(e.Row );
else if (e.Action ==DataRowAction.Change )
ChangeNodeByRowChanged(e.Row ,DataRowVersion.Default );
else if (e.Action ==DataRowAction.Delete )
DeleteNodeByRowDelete(e.Row );
else if (e.Action ==DataRowAction.Commit )
{
}
else if (e.Action ==DataRowAction.Rollback )
{
if (e.Row.RowState ==DataRowState.Added )
DeleteNodeByRowDelete(e.Row );
else if (e.Row.RowState ==DataRowState.Modified )
ChangeNodeByRowChanged(e.Row ,DataRowVersion.Original );
else if (e.Row.RowState ==DataRowState.Deleted )
AddNewNodeByNewRow(e.Row );
}
}
catch
{
throw ;
}
finally
{
SetDataSourceEvent(true);
stack.Pop ();
}
}
private void Table_RowChanged(object sender, DataRowChangeEventArgs e)
{
}
private void Table_RowDeleting(object sender, DataRowChangeEventArgs e)
{
try
{
stack.Push ("ByBinding");
SetDataSourceEvent(false);
DeleteNodeByRowDelete(e.Row );
}
catch
{
throw ;
}
finally
{
SetDataSourceEvent(true);
stack.Pop ();
}
}
private void Table_RowDeleted(object sender, DataRowChangeEventArgs e)
{
}
#endregion
#region 绑定管理器事件的处理
private upDataNode AddNewNodeByNewRow(int rowIndex)
{
if ( rowIndex<0) return null ;
upDataNode node=this.BuildNewNode (this.bindingList[rowIndex]);
object pkey=this.GetValueByIndex (this.parentIDProperty ,rowIndex);
upDataNode pnode=this.FindNode (null,pkey);
if (base.AddNode (pnode,node))
{
return node;
}
return null;
}
private upDataNode AddNewNodeByNewRow(DataRow row)
{
if ( row==null) return null ;
upDataNode node=this.BuildNewNode (row);
object pkey=row[this.parentIDColumn ];
upDataNode pnode=this.FindNode (null,pkey);
if (base.AddNode (pnode,node))
{
return node;
}
return null;
}
private void DeleteNodeByRowDelete(int rowIndex)
{
if ( rowIndex<0) return ;
object key=this.GetValueByIndex (this.idProperty ,rowIndex);
object text = this.GetValueByIndex (this.textProperty ,rowIndex);
upDataNode node=this.FindNode (null,key);
if (!base.DeleteNode (node))
throw new Exception ("不能移除节点:" + text==null?"无":text.ToString ());
}
private void DeleteNodeByRowDelete(DataRow Row)
{
object key=Row [this.idColumn ];
string text=Row [this.idColumn ].ToString ();
upDataNode node=this.FindNode (null,key);
if (!base.DeleteNode (node))
throw new Exception ("不能移除节点:" + text==""?"无":text);
}
private void ChangeNodeByRowChanged(int rowIndex)
{
if ( rowIndex<0 ) return ;
object key=this.GetValueByIndex (this.idProperty ,rowIndex);
upDataNode node=this.FindNode (null,key);
if (node!=null)
{
node.Key =key ;
object text = this.GetValueByIndex (this.textProperty ,rowIndex);
if (text !=null && !text.ToString ().Equals (""))
node.Text=text.ToString ();
else
node.Text="无";
object pkey = this.GetValueByIndex (this.parentIDProperty ,rowIndex);
upDataNode pnode=this.FindNode (null,pkey);
if (pnode==null && node.Parent ==null)
return ;
else
{
upDataNode.CheckNodeAddChild(pnode ,node);
RemoveNode(node);
if (pnode!=null )
pnode.Nodes.Add (node);
else
this.Nodes.Add (node);
}
}
}
private void ChangeNodeByRowChanged(DataRow Row,DataRowVersion rowVersion)
{
if ( Row==null ) return ;
object key=Row[this.IDColumn ,rowVersion];
upDataNode node=this.FindNode (null,key);
if (node!=null)
{
node.Key =key ;
object text = Row[this.textColumn,rowVersion ];
if (text !=null && !text.ToString ().Equals (""))
node.Text=text.ToString ();
else
node.Text="无";
object pkey = Row[this.parentIDColumn ,rowVersion];
upDataNode pnode=this.FindNode (null,pkey);
if (pnode==null && node.Parent ==null)
return ;
else
{
upDataNode.CheckNodeAddChild(pnode ,node);
RemoveNode(node);
if (pnode!=null )
pnode.Nodes.Add (node);
else
this.Nodes.Add (node);
}
}
}
#endregion
#region 树的事件
private void SetTreeEvent(bool on)
{
if (!on ||( on && treeViewEvent))
{
treeViewEvent=false;
this.NodeAdding -=new upLibrary.upControls.upTreeViewBase.NodeAddHandler(upTreeView_NodeAdding);
this.NodeDeleting -=new upLibrary.upControls.upTreeViewBase.NodeDeleteHandler(upTreeView_NodeDeleting);
this.AfterSelect -=new TreeViewEventHandler(upTreeView_AfterSelect);
}
if (on)
{
treeViewEvent=true;
this.NodeAdding +=new upLibrary.upControls.upTreeViewBase.NodeAddHandler(upTreeView_NodeAdding);
this.NodeDeleting +=new upLibrary.upControls.upTreeViewBase.NodeDeleteHandler(upTreeView_NodeDeleting);
this.AfterSelect +=new TreeViewEventHandler(upTreeView_AfterSelect);
}
}
/// <summary>
/// 节点加入前的事件
/// </summary>
/// <param name="Sender"></param>
/// <param name="e"></param>
private void upTreeView_NodeAdding(object Sender, upDataNodeEventArgs e)//不论何种增加方法,实际都在这里处理
{
bool success=false;
try
{
if( Sender is upDataNode )
success=AddNodeEvent((upDataNode)Sender,e.Node );
else
success=AddNodeEvent(null,e.Node );
e.Cancel =!success;
}
catch
{
throw ;
}
finally
{
}
}
/// <summary>
/// 删除一个节点时
/// </summary>
/// <param name="Sender"></param>
/// <param name="e"></param>
private void upTreeView_NodeDeleting(object Sender, upDataNodeEventArgs e)
{
try
{
e.Cancel =!DeleteNodeEvent(e.Node );
}
catch
{
throw ;
}
finally
{
}
}
private bool AddNodeEvent(upDataNode parentNode,upDataNode node)
{
if ( this.BindingList!=null && !stack.Contains ("ByBinding"))
{
object newRow=this.BindingList.AddNew ();
if (parentNode!=null)
this.parentIDProperty.SetValue (newRow,parentNode.Key );
else
this.parentIDProperty.SetValue (newRow,DBNull.Value );
}
return true;
}
private bool DeleteNodeEvent(upDataNode node)
{
if ( this.BindingList!=null && !stack.Contains ("ByBinding"))
{
upDataNode dnode=node as upDataNode;
int rowIndex=this.IndexOfValue (this.idProperty ,dnode.Key );
if (rowIndex>=0)
this.bindingList.RemoveAt (rowIndex);
}
return true;
}
private void upTreeView_AfterSelect(object sender, TreeViewEventArgs e)
{
try
{
if(stack.Contains ("ByBinding")) return ;
if (this.SelectedNode !=null && this.SelectedNode is upDataNode )
{
upDataNode dnode=this.SelectedNode as upDataNode ;
if ( dnode!=null ) //如果是由于手动选择树节点而非由绑定管理器的Positinon引起
{
int rowIndex = this.IndexOfValue (this.idProperty ,dnode.Key );
this.bindingManager.Position =rowIndex;
}
}
}
catch
{
throw ;
}
finally
{
}
}
#endregion
#region 其他方法:取数据行,据数据行找Node, 取值
internal PropertyDescriptor GetProperty( string Name)
{
return propertys.Find (Name , true);
}
/// <summary>
/// 获得指定列的属性说明器
/// </summary>
internal PropertyDescriptor GetProperty( string Name,bool ignoreCase)
{
return propertys.Find (Name , ignoreCase);
}
/// <summary>
/// 获得property所代表的列的某一个值位于BindingList中的索引
/// </summary>
internal int IndexOfValue(PropertyDescriptor property, object value)
{
if (value == null)
return -1;
if (property == null)
throw new ArgumentNullException("property");
if (property != null && this.bindingList !=null && this.bindingList.SupportsSearching)
return bindingList.Find(property, value);
for (int i = 0; i < bindingList.Count; i++)
{
object val = property.GetValue(bindingList[i]);
if (value.Equals(val))
return i;
}
return -1;
}
/// <summary>
/// 获得property所代表的列在指定行的值
/// </summary>
protected object GetValueByIndex(PropertyDescriptor property,int rowIndex)
{
if (property==null || this.bindingList.Count <=0 || rowIndex<0) return null;
return property.GetValue(this.bindingList[rowIndex]);
}
/// <summary>
/// 获得具有指定值的一行
/// </summary>
internal object GetItem(PropertyDescriptor property, object Value)
{
int rowIndex=IndexOfValue(property ,Value);
if (rowIndex>=0)
return this.bindingList[rowIndex];
return null;
}
/// <summary>
/// 查找具有指定Value的所有行并返回
/// </summary>
internal object[] GetItems(PropertyDescriptor property, object Value)
{
if (Value == null)
return null;
if (property == null)
throw new ArgumentNullException("property");
object[] result=null;
ArrayList list=new ArrayList ();
int index=0;
PropertyDescriptor oldSort=null;
ListSortDirection oldDirec=ListSortDirection.Ascending ;
if (this.BindingList.SupportsSorting)
{
oldSort=bindingList.SortProperty ;
oldDirec=bindingList.SortDirection ;
this.bindingList.ApplySort(property,ListSortDirection.Ascending );
if (bindingList.SupportsSearching)
index=bindingList.Find(property, Value);
}
while (index>-1 && index<bindingList.Count )
{
object item=bindingList[index];
object val = property.GetValue(item);
index++;
if (Value.Equals (val))
list.Add (item);
else if (oldSort!=null )
index=-1;
}
if (oldSort!=null)
bindingList.ApplySort(property,oldDirec );
else
bindingList.RemoveSort (); //一定要完全还原,原来没有排序就不能排序,否则改了排序列数据的话,改变类型是ItemMoved,而不是ItemChanged
if (list.Count >0)
{
result=new object [list.Count ];
list.CopyTo (result,0);
}
return result;
}
/// <summary>
/// 查找具有指定Value的所有行并返回
/// </summary>
internal object[] GetItems(PropertyDescriptor property, object[] Values)
{
if (Values == null )
return null;
if (property == null)
throw new ArgumentNullException("property");
object[] result=null,results=null;
ArrayList list=new ArrayList ();
for(int i=0 ; i < Values.Length ; i ++)
{
result=GetItems(property,Values[i]);
if (result!=null)
for(int j=0 ; j < result.Length ; j ++)
list.Add (result[j]);
}
if (list.Count >0)
{
results=new object [list.Count ];
list.CopyTo (results,0);
}
return results;
}
internal upDataNode FindNode(upDataNode topNode,object findKey)
{
upDataNode ChildNode=null,BrotherNode=null;
TreeNodeCollection nodes;
if (topNode==null )
nodes=this.Nodes ;
else
nodes=topNode.Nodes ;
if (topNode !=null )
{
upDataNode cnode=topNode as upDataNode;
if (cnode.Key.Equals (findKey))
return cnode;
}
if (nodes.Count >0 ) //有下级又没有要求取消,否则要处理下级
{
ChildNode=nodes[0] as upDataNode ;
while (ChildNode!=null ) //兄弟节点可能有多个
{
BrotherNode=ChildNode.NextNode as upDataNode ;
upDataNode result= FindNode(ChildNode,findKey);
if (result!=null )
return result;
else
ChildNode=BrotherNode;
}
}
return null;
}
#endregion
#region 树的操作:展开折叠
private void mnu_Click(object sender, EventArgs e)
{
MenuItem mnu=sender as MenuItem ;
switch (mnu.Index )
{
case 0:
ExpandAll(this.SelectedNode );
break;
case 1:
if (this.SelectedNode !=null)
this.SelectedNode.Collapse ();
else
this.CollapseAll();
break;
case 3:
this.ExpandAll ();
break;
case 4:
this.CollapseAll ();
break;
}
}
public void ExpandAll(TreeNode node)
{
if (node!=null)
node.ExpandAll ();
else
base.ExpandAll ();
}
#endregion
}
}