首页 > 开发 > 综合 > 正文

一个实现了数据绑定的树

2024-07-21 02:15:52
字体:
来源:转载
供稿:网友

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








 


 



  }








 


 



 








 


 



}








 


 







中国最大的web开发资源网站及技术社区,
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表