欢迎光临
我们一直在努力

一个实现了数据绑定的树-.NET教程,Asp.Net开发

建站超值云服务器,限时71元/月

///如未特别说明,本人所发表的技术文章都为原创, 任何人引用都请注明出处,并包含本声明
///作者: 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

 

 

  }

 

 

 

 

 

}

 

 

赞(0)
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com 特别注意:本站所有转载文章言论不代表本站观点! 本站所提供的图片等素材,版权归原作者所有,如需使用,请与原作者联系。未经允许不得转载:IDC资讯中心 » 一个实现了数据绑定的树-.NET教程,Asp.Net开发
分享到: 更多 (0)